DO NOT MERGE: Merge commit '3b2b22f181a0de40a226d6672d159225fe263686'
from nyc-support-25.4-dev to stage-aosp-master.

Bug: 62846313
Test: build
Change-Id: Ibfcdc70369a4f24ed1142af6873e6dddf79f4296
diff --git a/api/25.2.0.txt b/api/25.2.0.txt
new file mode 100644
index 0000000..6709b97
--- /dev/null
+++ b/api/25.2.0.txt
@@ -0,0 +1,10817 @@
+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 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 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 onCreateEnterAnimation();
+    method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateLogoAnimation();
+    method protected void onFinishFragment();
+    method protected void onPageChanged(int, int);
+    method public int onProvideTheme();
+    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 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 onCreateEnterAnimation();
+    method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateLogoAnimation();
+    method protected void onFinishFragment();
+    method protected void onPageChanged(int, int);
+    method public int onProvideTheme();
+    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 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;
+    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.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 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 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 onSessionDestroyed();
+    method public void onSessionEvent(java.lang.String, android.os.Bundle);
+  }
+
+  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 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 setSessionActivity(android.app.PendingIntent);
+    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 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_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 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/25.3.0.txt b/api/25.3.0.txt
index 917fd00..a1ff8b4 100644
--- a/api/25.3.0.txt
+++ b/api/25.3.0.txt
@@ -1,3 +1,75 @@
+package android.support.animation {
+
+  public abstract class DynamicAnimation<T extends android.support.animation.DynamicAnimation<T>> {
+    method public T addEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+    method public T addUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+    method public void cancel();
+    method public boolean isRunning();
+    method public void removeEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+    method public void removeUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+    method public T setMaxValue(float);
+    method public T setMinValue(float);
+    method public T setStartValue(float);
+    method public T setStartVelocity(float);
+    method public void start();
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ALPHA;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Z;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty Z;
+  }
+
+  public static abstract interface DynamicAnimation.OnAnimationEndListener {
+    method public abstract void onAnimationEnd(android.support.animation.DynamicAnimation, boolean, float, float);
+  }
+
+  public static abstract interface DynamicAnimation.OnAnimationUpdateListener {
+    method public abstract void onAnimationUpdate(android.support.animation.DynamicAnimation, float, float);
+  }
+
+  public static abstract class DynamicAnimation.ViewProperty {
+  }
+
+  public final class SpringAnimation extends android.support.animation.DynamicAnimation {
+    ctor public SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty);
+    ctor public SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty, float);
+    method public void animateToFinalPosition(float);
+    method public boolean canSkipToEnd();
+    method public android.support.animation.SpringForce getSpring();
+    method public android.support.animation.SpringAnimation setSpring(android.support.animation.SpringForce);
+    method public void skipToEnd();
+  }
+
+  public final class SpringForce {
+    ctor public SpringForce();
+    ctor public SpringForce(float);
+    method public float getDampingRatio();
+    method public float getFinalPosition();
+    method public float getStiffness();
+    method public android.support.animation.SpringForce setDampingRatio(float);
+    method public android.support.animation.SpringForce setFinalPosition(float);
+    method public android.support.animation.SpringForce setStiffness(float);
+    field public static final float DAMPING_RATIO_HIGH_BOUNCY = 0.2f;
+    field public static final float DAMPING_RATIO_LOW_BOUNCY = 0.75f;
+    field public static final float DAMPING_RATIO_MEDIUM_BOUNCY = 0.5f;
+    field public static final float DAMPING_RATIO_NO_BOUNCY = 1.0f;
+    field public static final float STIFFNESS_HIGH = 10000.0f;
+    field public static final float STIFFNESS_LOW = 200.0f;
+    field public static final float STIFFNESS_MEDIUM = 1500.0f;
+    field public static final float STIFFNESS_VERY_LOW = 50.0f;
+  }
+
+}
+
 package android.support.app.recommendation {
 
   public final class ContentRecommendation {
@@ -135,7 +207,9 @@
   public class CustomTabsCallback {
     ctor public CustomTabsCallback();
     method public void extraCallback(java.lang.String, android.os.Bundle);
+    method public void onMessageChannelReady(android.os.Bundle);
     method public void onNavigationEvent(int, android.os.Bundle);
+    method public void onPostMessage(java.lang.String, 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
@@ -215,10 +289,19 @@
     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 int postMessage(android.support.customtabs.CustomTabsSessionToken, java.lang.String, android.os.Bundle);
+    method protected abstract boolean requestPostMessageChannel(android.support.customtabs.CustomTabsSessionToken, android.net.Uri);
     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";
+    field public static final int RESULT_FAILURE_DISALLOWED = -1; // 0xffffffff
+    field public static final int RESULT_FAILURE_MESSAGING_ERROR = -3; // 0xfffffffd
+    field public static final int RESULT_FAILURE_REMOTE_ERROR = -2; // 0xfffffffe
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+  }
+
+  public static abstract class CustomTabsService.Result implements java.lang.annotation.Annotation {
   }
 
   public abstract class CustomTabsServiceConnection implements android.content.ServiceConnection {
@@ -229,6 +312,8 @@
 
   public final class CustomTabsSession {
     method public boolean mayLaunchUrl(android.net.Uri, android.os.Bundle, java.util.List<android.os.Bundle>);
+    method public int postMessage(java.lang.String, android.os.Bundle);
+    method public boolean requestPostMessageChannel(android.net.Uri);
     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);
@@ -237,6 +322,24 @@
   public class CustomTabsSessionToken {
     method public android.support.customtabs.CustomTabsCallback getCallback();
     method public static android.support.customtabs.CustomTabsSessionToken getSessionTokenFromIntent(android.content.Intent);
+    method public boolean isAssociatedWith(android.support.customtabs.CustomTabsSession);
+  }
+
+  public class PostMessageService extends android.app.Service {
+    ctor public PostMessageService();
+    method public android.os.IBinder onBind(android.content.Intent);
+  }
+
+  public abstract class PostMessageServiceConnection implements android.content.ServiceConnection {
+    ctor public PostMessageServiceConnection(android.support.customtabs.CustomTabsSessionToken);
+    method public boolean bindSessionToPostMessageService(android.content.Context, java.lang.String);
+    method public final boolean notifyMessageChannelReady(android.os.Bundle);
+    method public void onPostMessageServiceConnected();
+    method public void onPostMessageServiceDisconnected();
+    method public final void onServiceConnected(android.content.ComponentName, android.os.IBinder);
+    method public final void onServiceDisconnected(android.content.ComponentName);
+    method public final boolean postMessage(java.lang.String, android.os.Bundle);
+    method public void unbindFromContext(android.content.Context);
   }
 
 }
@@ -839,16 +942,34 @@
 
 package android.support.graphics.drawable {
 
-  public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon {
+  public abstract interface Animatable2Compat {
+    method public abstract void clearAnimationCallbacks();
+    method public abstract void registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public abstract boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+  }
+
+  public static abstract class Animatable2Compat.AnimationCallback {
+    ctor public Animatable2Compat.AnimationCallback();
+    method public void onAnimationEnd(android.graphics.drawable.Drawable);
+    method public void onAnimationStart(android.graphics.drawable.Drawable);
+  }
+
+  public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon implements android.support.graphics.drawable.Animatable2Compat {
+    method public void clearAnimationCallbacks();
+    method public static void clearAnimationCallbacks(android.graphics.drawable.Drawable);
     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 registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public static void registerAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void start();
     method public void stop();
+    method public boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public static boolean unregisterAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
   }
 
    abstract class VectorDrawableCommon extends android.graphics.drawable.Drawable {
@@ -874,7 +995,8 @@
     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 deprecated boolean getLatLong(float[]);
+    method public double[] getLatLong();
     method public byte[] getThumbnail();
     method public android.graphics.Bitmap getThumbnailBitmap();
     method public byte[] getThumbnailBytes();
@@ -883,6 +1005,7 @@
     method public boolean isThumbnailCompressed();
     method public void saveAttributes() throws java.io.IOException;
     method public void setAttribute(java.lang.String, java.lang.String);
+    method public void setLatLong(double, double);
     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
@@ -1521,6 +1644,7 @@
     method public final boolean isHeadersTransitionOnBackEnabled();
     method public boolean isInHeadersTransition();
     method public boolean isShowingHeaders();
+    method public android.support.v17.leanback.app.HeadersFragment onCreateHeadersFragment();
     method protected void onEntranceTransitionEnd();
     method protected void onEntranceTransitionPrepare();
     method protected void onEntranceTransitionStart();
@@ -1625,6 +1749,7 @@
     method public final boolean isHeadersTransitionOnBackEnabled();
     method public boolean isInHeadersTransition();
     method public boolean isShowingHeaders();
+    method public android.support.v17.leanback.app.HeadersSupportFragment onCreateHeadersSupportFragment();
     method protected void onEntranceTransitionEnd();
     method protected void onEntranceTransitionPrepare();
     method protected void onEntranceTransitionStart();
@@ -2259,6 +2384,7 @@
     method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
     method public android.graphics.drawable.Drawable getBadgeDrawable();
     method public android.content.Intent getRecognizerIntent();
+    method public android.support.v17.leanback.app.RowsFragment getRowsFragment();
     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);
@@ -2288,6 +2414,7 @@
     method public void displayCompletions(android.view.inputmethod.CompletionInfo[]);
     method public android.graphics.drawable.Drawable getBadgeDrawable();
     method public android.content.Intent getRecognizerIntent();
+    method public android.support.v17.leanback.app.RowsSupportFragment getRowsSupportFragment();
     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);
@@ -2377,10 +2504,7 @@
   public class BoundsRule {
     ctor public BoundsRule();
     ctor public BoundsRule(android.support.v17.leanback.graphics.BoundsRule);
-    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
     method public void calculateBounds(android.graphics.Rect, android.graphics.Rect);
-    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
-    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
     field public android.support.v17.leanback.graphics.BoundsRule.ValueRule bottom;
     field public android.support.v17.leanback.graphics.BoundsRule.ValueRule left;
     field public android.support.v17.leanback.graphics.BoundsRule.ValueRule right;
@@ -2388,8 +2512,11 @@
   }
 
   public static final class BoundsRule.ValueRule {
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
     method public int getAbsoluteValue();
     method public float getFraction();
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
     method public void setAbsoluteValue(int);
     method public void setFraction(float);
   }
@@ -2575,6 +2702,7 @@
 
   public static abstract class PlaybackGlueHost.HostCallback {
     ctor public PlaybackGlueHost.HostCallback();
+    method public void onHostDestroy();
     method public void onHostPause();
     method public void onHostResume();
     method public void onHostStart();
@@ -2902,6 +3030,7 @@
     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);
+    method public static void setupHeaderItemFocusHighlight(android.support.v17.leanback.widget.VerticalGridView, boolean);
   }
 
   public abstract interface FragmentAnimationProvider {
@@ -3303,6 +3432,7 @@
     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 setPresenter(android.support.v17.leanback.widget.PresenterSelector);
     method public void setPresenterMapper(java.util.ArrayList<android.support.v17.leanback.widget.Presenter>);
     method public void setWrapper(android.support.v17.leanback.widget.ItemBridgeAdapter.Wrapper);
   }
@@ -3492,111 +3622,79 @@
 
   public abstract class Parallax<PropertyT extends android.util.Property> {
     ctor public Parallax();
-    method public void addEffect(android.support.v17.leanback.widget.ParallaxEffect);
-    method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue...);
-    method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue...);
-    method public abstract PropertyT addProperty(java.lang.String);
+    method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
+    method public final PropertyT addProperty(java.lang.String);
     method public abstract PropertyT createProperty(java.lang.String, int);
     method public java.util.List<android.support.v17.leanback.widget.ParallaxEffect> getEffects();
+    method public abstract float getMaxValue();
     method public final java.util.List<PropertyT> getProperties();
     method public void removeAllEffects();
     method public void removeEffect(android.support.v17.leanback.widget.ParallaxEffect);
     method public void updateValues();
-    method public abstract void verifyProperties() throws java.lang.IllegalStateException;
-  }
-
-  public static abstract class Parallax.FloatParallax<FloatPropertyT extends android.support.v17.leanback.widget.Parallax.FloatProperty> extends android.support.v17.leanback.widget.Parallax {
-    ctor public Parallax.FloatParallax();
-    method public final FloatPropertyT addProperty(java.lang.String);
-    method public abstract float getMaxValue();
-    method public final float getPropertyValue(int);
-    method public final void setPropertyValue(int, float);
-    method public final void verifyProperties() throws java.lang.IllegalStateException;
   }
 
   public static class Parallax.FloatProperty extends android.util.Property {
     ctor public Parallax.FloatProperty(java.lang.String, int);
-    method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue at(float, float);
-    method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atAbsolute(float);
-    method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atFraction(float);
-    method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax.FloatParallax);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(float, float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+    method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax);
     method public final int getIndex();
-    method public final void set(android.support.v17.leanback.widget.Parallax.FloatParallax, java.lang.Float);
+    method public final float getValue(android.support.v17.leanback.widget.Parallax);
+    method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Float);
+    method public final void setValue(android.support.v17.leanback.widget.Parallax, float);
     field public static final float UNKNOWN_AFTER = 3.4028235E38f;
     field public static final float UNKNOWN_BEFORE = -3.4028235E38f;
   }
 
-  public static class Parallax.FloatPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
-    ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float);
-    ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float, float);
-    method public final float getMarkerValue(android.support.v17.leanback.widget.Parallax.FloatParallax);
-  }
-
-  public static abstract class Parallax.IntParallax<IntPropertyT extends android.support.v17.leanback.widget.Parallax.IntProperty> extends android.support.v17.leanback.widget.Parallax {
-    ctor public Parallax.IntParallax();
-    method public final IntPropertyT addProperty(java.lang.String);
-    method public abstract int getMaxValue();
-    method public final int getPropertyValue(int);
-    method public final void setPropertyValue(int, int);
-    method public final void verifyProperties() throws java.lang.IllegalStateException;
-  }
-
   public static class Parallax.IntProperty extends android.util.Property {
     ctor public Parallax.IntProperty(java.lang.String, int);
-    method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue at(int, float);
-    method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atAbsolute(int);
-    method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atFraction(float);
-    method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax.IntParallax);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(int, float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(int);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+    method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax);
     method public final int getIndex();
-    method public final void set(android.support.v17.leanback.widget.Parallax.IntParallax, java.lang.Integer);
+    method public final int getValue(android.support.v17.leanback.widget.Parallax);
+    method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Integer);
+    method public final void setValue(android.support.v17.leanback.widget.Parallax, int);
     field public static final int UNKNOWN_AFTER = 2147483647; // 0x7fffffff
     field public static final int UNKNOWN_BEFORE = -2147483648; // 0x80000000
   }
 
-  public static class Parallax.IntPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
-    ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int);
-    ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int, float);
-    method public final int getMarkerValue(android.support.v17.leanback.widget.Parallax.IntParallax);
-  }
-
   public static class Parallax.PropertyMarkerValue<PropertyT> {
     ctor public Parallax.PropertyMarkerValue(PropertyT);
     method public PropertyT getProperty();
   }
 
-  public abstract class ParallaxEffect<ParallaxEffectT extends android.support.v17.leanback.widget.ParallaxEffect, PropertyMarkerValueT extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> {
-    ctor public ParallaxEffect();
+  public abstract class ParallaxEffect {
     method public final void addTarget(android.support.v17.leanback.widget.ParallaxTarget);
-    method protected abstract float calculateFraction(android.support.v17.leanback.widget.Parallax);
-    method public final java.util.List<PropertyMarkerValueT> getPropertyRanges();
+    method public final java.util.List<android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> getPropertyRanges();
     method public final java.util.List<android.support.v17.leanback.widget.ParallaxTarget> getTargets();
     method public final void performMapping(android.support.v17.leanback.widget.Parallax);
     method public final void removeTarget(android.support.v17.leanback.widget.ParallaxTarget);
-    method public final void setPropertyRanges(PropertyMarkerValueT...);
+    method public final void setPropertyRanges(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
     method public final android.support.v17.leanback.widget.ParallaxEffect target(android.support.v17.leanback.widget.ParallaxTarget);
     method public final android.support.v17.leanback.widget.ParallaxEffect target(java.lang.Object, android.animation.PropertyValuesHolder);
-  }
-
-  public static final class ParallaxEffect.FloatEffect extends android.support.v17.leanback.widget.ParallaxEffect {
-    ctor public ParallaxEffect.FloatEffect();
-    method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
-  }
-
-  public static final class ParallaxEffect.IntEffect extends android.support.v17.leanback.widget.ParallaxEffect {
-    ctor public ParallaxEffect.IntEffect();
-    method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
+    method public final <T, V extends java.lang.Number> android.support.v17.leanback.widget.ParallaxEffect target(T, android.util.Property<T, V>);
   }
 
   public abstract class ParallaxTarget {
     ctor public ParallaxTarget();
-    method public abstract float getFraction();
-    method public abstract void update(float);
+    method public void directUpdate(java.lang.Number);
+    method public boolean isDirectMapping();
+    method public void update(float);
+  }
+
+  public static final class ParallaxTarget.DirectPropertyTarget<T, V extends java.lang.Number> extends android.support.v17.leanback.widget.ParallaxTarget {
+    ctor public ParallaxTarget.DirectPropertyTarget(java.lang.Object, android.util.Property<T, V>);
   }
 
   public static final class ParallaxTarget.PropertyValuesHolderTarget extends android.support.v17.leanback.widget.ParallaxTarget {
     ctor public ParallaxTarget.PropertyValuesHolderTarget(java.lang.Object, android.animation.PropertyValuesHolder);
-    method public float getFraction();
-    method public void update(float);
   }
 
   public class PlaybackControlsRow extends android.support.v17.leanback.widget.Row {
@@ -3788,10 +3886,10 @@
     method public void unselect();
   }
 
-  public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax.IntParallax {
+  public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax {
     ctor public RecyclerViewParallax();
     method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty createProperty(java.lang.String, int);
-    method public int getMaxValue();
+    method public float getMaxValue();
     method public android.support.v7.widget.RecyclerView getRecyclerView();
     method public void setRecyclerView(android.support.v7.widget.RecyclerView);
   }
@@ -4228,6 +4326,18 @@
     method public void setStaticLabels(java.lang.CharSequence[]);
   }
 
+  public class TimePicker extends android.support.v17.leanback.widget.picker.Picker {
+    ctor public TimePicker(android.content.Context, android.util.AttributeSet);
+    ctor public TimePicker(android.content.Context, android.util.AttributeSet, int);
+    method public int getHour();
+    method public int getMinute();
+    method public boolean is24Hour();
+    method public boolean isPm();
+    method public void setHour(int);
+    method public void setIs24Hour(boolean);
+    method public void setMinute(int);
+  }
+
 }
 
 package android.support.v17.preference {
@@ -5651,6 +5761,7 @@
     method public android.content.ComponentName getServiceComponent();
     method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
     method public boolean isConnected();
+    method public void search(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.SearchCallback);
     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);
@@ -5688,6 +5799,12 @@
     field public static final int FLAG_PLAYABLE = 2; // 0x2
   }
 
+  public static abstract class MediaBrowserCompat.SearchCallback {
+    ctor public MediaBrowserCompat.SearchCallback();
+    method public void onError(java.lang.String, android.os.Bundle);
+    method public void onSearchResult(java.lang.String, android.os.Bundle, java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>);
+  }
+
   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>);
@@ -5708,6 +5825,7 @@
     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 onSearch(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserServiceCompat.Result<java.util.List<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";
   }
@@ -5719,7 +5837,7 @@
     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";
+    field public static final deprecated java.lang.String EXTRA_SUGGESTION_KEYWORDS = "android.service.media.extra.SUGGESTION_KEYWORDS";
   }
 
   public static class MediaBrowserServiceCompat.Result<T> {
@@ -5780,6 +5898,7 @@
     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_ADVERTISEMENT = "android.media.metadata.ADVERTISEMENT";
     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";
@@ -5848,72 +5967,72 @@
     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 abstract deprecated class TransportController {
+    ctor public deprecated TransportController();
+    method public abstract deprecated int getBufferPercentage();
+    method public abstract deprecated long getCurrentPosition();
+    method public abstract deprecated long getDuration();
+    method public abstract deprecated int getTransportControlFlags();
+    method public abstract deprecated boolean isPlaying();
+    method public abstract deprecated void pausePlaying();
+    method public abstract deprecated void registerStateListener(android.support.v4.media.TransportStateListener);
+    method public abstract deprecated void seekTo(long);
+    method public abstract deprecated void startPlaying();
+    method public abstract deprecated void stopPlaying();
+    method public abstract deprecated 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 deprecated class TransportMediator extends android.support.v4.media.TransportController {
+    ctor public deprecated TransportMediator(android.app.Activity, android.support.v4.media.TransportPerformer);
+    ctor public deprecated TransportMediator(android.view.View, android.support.v4.media.TransportPerformer);
+    method public deprecated void destroy();
+    method public deprecated boolean dispatchKeyEvent(android.view.KeyEvent);
+    method public deprecated int getBufferPercentage();
+    method public deprecated long getCurrentPosition();
+    method public deprecated long getDuration();
+    method public deprecated java.lang.Object getRemoteControlClient();
+    method public deprecated int getTransportControlFlags();
+    method public deprecated boolean isPlaying();
+    method public deprecated void pausePlaying();
+    method public deprecated void refreshState();
+    method public deprecated void registerStateListener(android.support.v4.media.TransportStateListener);
+    method public deprecated void seekTo(long);
+    method public deprecated void startPlaying();
+    method public deprecated void stopPlaying();
+    method public deprecated void unregisterStateListener(android.support.v4.media.TransportStateListener);
+    field public static final deprecated int FLAG_KEY_MEDIA_FAST_FORWARD = 64; // 0x40
+    field public static final deprecated int FLAG_KEY_MEDIA_NEXT = 128; // 0x80
+    field public static final deprecated int FLAG_KEY_MEDIA_PAUSE = 16; // 0x10
+    field public static final deprecated int FLAG_KEY_MEDIA_PLAY = 4; // 0x4
+    field public static final deprecated int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
+    field public static final deprecated int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
+    field public static final deprecated int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
+    field public static final deprecated int FLAG_KEY_MEDIA_STOP = 32; // 0x20
+    field public static final deprecated int KEYCODE_MEDIA_PAUSE = 127; // 0x7f
+    field public static final deprecated int KEYCODE_MEDIA_PLAY = 126; // 0x7e
+    field public static final deprecated 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 abstract deprecated class TransportPerformer {
+    ctor public deprecated TransportPerformer();
+    method public deprecated void onAudioFocusChange(int);
+    method public deprecated int onGetBufferPercentage();
+    method public abstract deprecated long onGetCurrentPosition();
+    method public abstract deprecated long onGetDuration();
+    method public deprecated int onGetTransportControlFlags();
+    method public abstract deprecated boolean onIsPlaying();
+    method public deprecated boolean onMediaButtonDown(int, android.view.KeyEvent);
+    method public deprecated boolean onMediaButtonUp(int, android.view.KeyEvent);
+    method public abstract deprecated void onPause();
+    method public abstract deprecated void onSeekTo(long);
+    method public abstract deprecated void onStart();
+    method public abstract deprecated 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 deprecated class TransportStateListener {
+    ctor public deprecated TransportStateListener();
+    method public deprecated void onPlayingChanged(android.support.v4.media.TransportController);
+    method public deprecated void onTransportControlsChanged(android.support.v4.media.TransportController);
   }
 
   public abstract class VolumeProviderCompat {
@@ -5951,6 +6070,8 @@
   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 addQueueItem(android.support.v4.media.MediaDescriptionCompat);
+    method public void addQueueItem(android.support.v4.media.MediaDescriptionCompat, int);
     method public void adjustVolume(int, int);
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
     method public android.os.Bundle getExtras();
@@ -5964,11 +6085,15 @@
     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 removeQueueItem(android.support.v4.media.MediaDescriptionCompat);
+    method public void removeQueueItemAt(int);
     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);
@@ -5984,8 +6109,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 {
@@ -6014,6 +6141,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);
@@ -6047,13 +6176,18 @@
     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_QUEUE_COMMANDS = 4; // 0x4
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
 
   public static abstract class MediaSessionCompat.Callback {
     ctor public MediaSessionCompat.Callback();
+    method public void onAddQueueItem(android.support.v4.media.MediaDescriptionCompat);
+    method public void onAddQueueItem(android.support.v4.media.MediaDescriptionCompat, int);
     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();
@@ -6067,9 +6201,13 @@
     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 onRemoveQueueItem(android.support.v4.media.MediaDescriptionCompat);
+    method public void onRemoveQueueItemAt(int);
     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);
@@ -6122,6 +6260,7 @@
     method public long getActiveQueueItemId();
     method public long getBufferedPosition();
     method public java.util.List<android.support.v4.media.session.PlaybackStateCompat.CustomAction> getCustomActions();
+    method public int getErrorCode();
     method public java.lang.CharSequence getErrorMessage();
     method public android.os.Bundle getExtras();
     method public long getLastPositionUpdateTime();
@@ -6145,12 +6284,29 @@
     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 int ERROR_CODE_ACTION_ABORTED = 10; // 0xa
+    field public static final int ERROR_CODE_APP_ERROR = 1; // 0x1
+    field public static final int ERROR_CODE_AUTHENTICATION_EXPIRED = 3; // 0x3
+    field public static final int ERROR_CODE_CONCURRENT_STREAM_LIMIT = 5; // 0x5
+    field public static final int ERROR_CODE_CONTENT_ALREADY_PLAYING = 8; // 0x8
+    field public static final int ERROR_CODE_END_OF_QUEUE = 11; // 0xb
+    field public static final int ERROR_CODE_NOT_AVAILABLE_IN_REGION = 7; // 0x7
+    field public static final int ERROR_CODE_NOT_SUPPORTED = 2; // 0x2
+    field public static final int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED = 6; // 0x6
+    field public static final int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED = 4; // 0x4
+    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
@@ -6174,7 +6330,8 @@
     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 deprecated android.support.v4.media.session.PlaybackStateCompat.Builder setErrorMessage(java.lang.CharSequence);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setErrorMessage(int, 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);
@@ -8373,6 +8530,7 @@
     method public android.support.v7.graphics.drawable.DrawerArrowDrawable getDrawerArrowDrawable();
     method public android.view.View.OnClickListener getToolbarNavigationClickListener();
     method public boolean isDrawerIndicatorEnabled();
+    method public boolean isDrawerSlideAnimationEnabled();
     method public void onConfigurationChanged(android.content.res.Configuration);
     method public void onDrawerClosed(android.view.View);
     method public void onDrawerOpened(android.view.View);
@@ -8381,6 +8539,7 @@
     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 setDrawerSlideAnimationEnabled(boolean);
     method public void setHomeAsUpIndicator(android.graphics.drawable.Drawable);
     method public void setHomeAsUpIndicator(int);
     method public void setToolbarNavigationClickListener(android.view.View.OnClickListener);
@@ -10038,7 +10197,8 @@
     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 deprecated int getInitialItemPrefetchCount();
+    method public int getInitialPrefetchItemCount();
     method public int getOrientation();
     method public boolean getRecycleChildrenOnDetach();
     method public boolean getReverseLayout();
@@ -10504,6 +10664,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);
@@ -10548,6 +10709,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);
diff --git a/api/25.4.0.txt b/api/25.4.0.txt
new file mode 100644
index 0000000..30642f1
--- /dev/null
+++ b/api/25.4.0.txt
@@ -0,0 +1,11332 @@
+package android.support.animation {
+
+  public abstract class DynamicAnimation<T extends android.support.animation.DynamicAnimation<T>> {
+    method public T addEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+    method public T addUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+    method public void cancel();
+    method public float getMinimumVisibleChange();
+    method public boolean isRunning();
+    method public void removeEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+    method public void removeUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+    method public T setMaxValue(float);
+    method public T setMinValue(float);
+    method public T setMinimumVisibleChange(float);
+    method public T setStartValue(float);
+    method public T setStartVelocity(float);
+    method public void start();
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ALPHA;
+    field public static final float MIN_VISIBLE_CHANGE_ALPHA = 0.00390625f;
+    field public static final float MIN_VISIBLE_CHANGE_PIXELS = 1.0f;
+    field public static final float MIN_VISIBLE_CHANGE_ROTATION_DEGREES = 0.1f;
+    field public static final float MIN_VISIBLE_CHANGE_SCALE = 0.002f;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Z;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty Z;
+  }
+
+  public static abstract interface DynamicAnimation.OnAnimationEndListener {
+    method public abstract void onAnimationEnd(android.support.animation.DynamicAnimation, boolean, float, float);
+  }
+
+  public static abstract interface DynamicAnimation.OnAnimationUpdateListener {
+    method public abstract void onAnimationUpdate(android.support.animation.DynamicAnimation, float, float);
+  }
+
+  public static abstract class DynamicAnimation.ViewProperty extends android.support.animation.FloatPropertyCompat {
+  }
+
+  public final class FlingAnimation extends android.support.animation.DynamicAnimation {
+    ctor public FlingAnimation(android.support.animation.FloatValueHolder);
+    ctor public FlingAnimation(K, android.support.animation.FloatPropertyCompat<K>);
+    method public float getFriction();
+    method public android.support.animation.FlingAnimation setFriction(float);
+  }
+
+  public abstract class FloatPropertyCompat<T> {
+    ctor public FloatPropertyCompat(java.lang.String);
+    method public static <T> android.support.animation.FloatPropertyCompat<T> createFloatPropertyCompat(android.util.FloatProperty<T>);
+    method public abstract float getValue(T);
+    method public abstract void setValue(T, float);
+  }
+
+  public final class FloatValueHolder {
+    ctor public FloatValueHolder();
+    ctor public FloatValueHolder(float);
+    method public float getValue();
+    method public void setValue(float);
+  }
+
+  public final class SpringAnimation extends android.support.animation.DynamicAnimation {
+    ctor public SpringAnimation(android.support.animation.FloatValueHolder);
+    ctor public SpringAnimation(K, android.support.animation.FloatPropertyCompat<K>);
+    ctor public SpringAnimation(K, android.support.animation.FloatPropertyCompat<K>, float);
+    ctor public deprecated SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty);
+    ctor public deprecated SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty, float);
+    method public void animateToFinalPosition(float);
+    method public boolean canSkipToEnd();
+    method public android.support.animation.SpringForce getSpring();
+    method public android.support.animation.SpringAnimation setSpring(android.support.animation.SpringForce);
+    method public void skipToEnd();
+  }
+
+  public final class SpringForce {
+    ctor public SpringForce();
+    ctor public SpringForce(float);
+    method public float getDampingRatio();
+    method public float getFinalPosition();
+    method public float getStiffness();
+    method public android.support.animation.SpringForce setDampingRatio(float);
+    method public android.support.animation.SpringForce setFinalPosition(float);
+    method public android.support.animation.SpringForce setStiffness(float);
+    field public static final float DAMPING_RATIO_HIGH_BOUNCY = 0.2f;
+    field public static final float DAMPING_RATIO_LOW_BOUNCY = 0.75f;
+    field public static final float DAMPING_RATIO_MEDIUM_BOUNCY = 0.5f;
+    field public static final float DAMPING_RATIO_NO_BOUNCY = 1.0f;
+    field public static final float STIFFNESS_HIGH = 10000.0f;
+    field public static final float STIFFNESS_LOW = 200.0f;
+    field public static final float STIFFNESS_MEDIUM = 1500.0f;
+    field public static final float STIFFNESS_VERY_LOW = 50.0f;
+  }
+
+}
+
+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 onMessageChannelReady(android.os.Bundle);
+    method public void onNavigationEvent(int, android.os.Bundle);
+    method public void onPostMessage(java.lang.String, 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 int postMessage(android.support.customtabs.CustomTabsSessionToken, java.lang.String, android.os.Bundle);
+    method protected abstract boolean requestPostMessageChannel(android.support.customtabs.CustomTabsSessionToken, android.net.Uri);
+    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";
+    field public static final int RESULT_FAILURE_DISALLOWED = -1; // 0xffffffff
+    field public static final int RESULT_FAILURE_MESSAGING_ERROR = -3; // 0xfffffffd
+    field public static final int RESULT_FAILURE_REMOTE_ERROR = -2; // 0xfffffffe
+    field public static final int RESULT_SUCCESS = 0; // 0x0
+  }
+
+  public static abstract class CustomTabsService.Result implements java.lang.annotation.Annotation {
+  }
+
+  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 int postMessage(java.lang.String, android.os.Bundle);
+    method public boolean requestPostMessageChannel(android.net.Uri);
+    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);
+    method public boolean isAssociatedWith(android.support.customtabs.CustomTabsSession);
+  }
+
+  public class PostMessageService extends android.app.Service {
+    ctor public PostMessageService();
+    method public android.os.IBinder onBind(android.content.Intent);
+  }
+
+  public abstract class PostMessageServiceConnection implements android.content.ServiceConnection {
+    ctor public PostMessageServiceConnection(android.support.customtabs.CustomTabsSessionToken);
+    method public boolean bindSessionToPostMessageService(android.content.Context, java.lang.String);
+    method public final boolean notifyMessageChannelReady(android.os.Bundle);
+    method public void onPostMessageServiceConnected();
+    method public void onPostMessageServiceDisconnected();
+    method public final void onServiceConnected(android.content.ComponentName, android.os.IBinder);
+    method public final void onServiceDisconnected(android.content.ComponentName);
+    method public final boolean postMessage(java.lang.String, android.os.Bundle);
+    method public void unbindFromContext(android.content.Context);
+  }
+
+}
+
+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 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 int getSelectedItemId();
+    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 setOnNavigationItemReselectedListener(android.support.design.widget.BottomNavigationView.OnNavigationItemReselectedListener);
+    method public void setOnNavigationItemSelectedListener(android.support.design.widget.BottomNavigationView.OnNavigationItemSelectedListener);
+    method public void setSelectedItemId(int);
+  }
+
+  public static abstract interface BottomNavigationView.OnNavigationItemReselectedListener {
+    method public abstract void onNavigationItemReselected(android.view.MenuItem);
+  }
+
+  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 abstract interface Animatable2Compat {
+    method public abstract void clearAnimationCallbacks();
+    method public abstract void registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public abstract boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+  }
+
+  public static abstract class Animatable2Compat.AnimationCallback {
+    ctor public Animatable2Compat.AnimationCallback();
+    method public void onAnimationEnd(android.graphics.drawable.Drawable);
+    method public void onAnimationStart(android.graphics.drawable.Drawable);
+  }
+
+  public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon implements android.support.graphics.drawable.Animatable2Compat {
+    method public void clearAnimationCallbacks();
+    method public static void clearAnimationCallbacks(android.graphics.drawable.Drawable);
+    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 registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public static void registerAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public void setAlpha(int);
+    method public void setColorFilter(android.graphics.ColorFilter);
+    method public void start();
+    method public void stop();
+    method public boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public static boolean unregisterAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+  }
+
+   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 deprecated boolean getLatLong(float[]);
+    method public double[] getLatLong();
+    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);
+    method public void setLatLong(double, double);
+    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 public android.support.v17.leanback.app.HeadersFragment onCreateHeadersFragment();
+    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 public android.support.v17.leanback.app.HeadersSupportFragment onCreateHeadersSupportFragment();
+    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.widget.DetailsParallax getParallax();
+    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 DetailsFragmentBackgroundController {
+    ctor public DetailsFragmentBackgroundController(android.support.v17.leanback.app.DetailsFragment);
+    method public boolean canNavigateToVideoFragment();
+    method public void enableParallax();
+    method public void enableParallax(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.support.v17.leanback.widget.ParallaxTarget.PropertyValuesHolderTarget);
+    method public final android.app.Fragment findOrCreateVideoFragment();
+    method public final android.graphics.drawable.Drawable getBottomDrawable();
+    method public final android.graphics.Bitmap getCoverBitmap();
+    method public final android.graphics.drawable.Drawable getCoverDrawable();
+    method public final int getParallaxDrawableMaxOffset();
+    method public final android.support.v17.leanback.media.PlaybackGlue getPlaybackGlue();
+    method public final int getSolidColor();
+    method public android.support.v17.leanback.media.PlaybackGlueHost onCreateGlueHost();
+    method public android.app.Fragment onCreateVideoFragment();
+    method public final void setCoverBitmap(android.graphics.Bitmap);
+    method public final void setParallaxDrawableMaxOffset(int);
+    method public final void setSolidColor(int);
+    method public void setupVideoPlayback(android.support.v17.leanback.media.PlaybackGlue);
+    method public final void switchToRows();
+    method public final void switchToVideo();
+  }
+
+  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.widget.DetailsParallax getParallax();
+    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 DetailsSupportFragmentBackgroundController {
+    ctor public DetailsSupportFragmentBackgroundController(android.support.v17.leanback.app.DetailsSupportFragment);
+    method public boolean canNavigateToVideoSupportFragment();
+    method public void enableParallax();
+    method public void enableParallax(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.support.v17.leanback.widget.ParallaxTarget.PropertyValuesHolderTarget);
+    method public final android.support.v4.app.Fragment findOrCreateVideoSupportFragment();
+    method public final android.graphics.drawable.Drawable getBottomDrawable();
+    method public final android.graphics.Bitmap getCoverBitmap();
+    method public final android.graphics.drawable.Drawable getCoverDrawable();
+    method public final int getParallaxDrawableMaxOffset();
+    method public final android.support.v17.leanback.media.PlaybackGlue getPlaybackGlue();
+    method public final int getSolidColor();
+    method public android.support.v17.leanback.media.PlaybackGlueHost onCreateGlueHost();
+    method public android.support.v4.app.Fragment onCreateVideoSupportFragment();
+    method public final void setCoverBitmap(android.graphics.Bitmap);
+    method public final void setParallaxDrawableMaxOffset(int);
+    method public final void setSolidColor(int);
+    method public void setupVideoPlayback(android.support.v17.leanback.media.PlaybackGlue);
+    method public final void switchToRows();
+    method public final void switchToVideo();
+  }
+
+  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 getLogoResourceId();
+    method protected abstract int getPageCount();
+    method protected abstract java.lang.CharSequence getPageDescription(int);
+    method protected abstract java.lang.CharSequence getPageTitle(int);
+    method protected final boolean isLogoAnimationFinished();
+    method protected void moveToNextPage();
+    method protected void moveToPreviousPage();
+    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 onCreateEnterAnimation();
+    method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateLogoAnimation();
+    method protected void onFinishFragment();
+    method protected void onLogoAnimationFinished();
+    method protected void onPageChanged(int, int);
+    method public int onProvideTheme();
+    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 getLogoResourceId();
+    method protected abstract int getPageCount();
+    method protected abstract java.lang.CharSequence getPageDescription(int);
+    method protected abstract java.lang.CharSequence getPageTitle(int);
+    method protected final boolean isLogoAnimationFinished();
+    method protected void moveToNextPage();
+    method protected void moveToPreviousPage();
+    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 onCreateEnterAnimation();
+    method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
+    method protected android.animation.Animator onCreateLogoAnimation();
+    method protected void onFinishFragment();
+    method protected void onLogoAnimationFinished();
+    method protected void onPageChanged(int, int);
+    method public int onProvideTheme();
+    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 void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+    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 void setOnItemViewSelectedListener(android.support.v17.leanback.widget.BaseOnItemViewSelectedListener);
+    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 android.support.v17.leanback.app.RowsFragment getRowsFragment();
+    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 android.support.v17.leanback.app.RowsSupportFragment getRowsSupportFragment();
+    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);
+  }
+
+  public class VideoFragment extends android.support.v17.leanback.app.PlaybackFragment {
+    ctor public VideoFragment();
+    method public android.view.SurfaceView getSurfaceView();
+    method public void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+  }
+
+  public class VideoFragmentGlueHost extends android.support.v17.leanback.app.PlaybackFragmentGlueHost implements android.support.v17.leanback.media.SurfaceHolderGlueHost {
+    ctor public VideoFragmentGlueHost(android.support.v17.leanback.app.VideoFragment);
+    method public void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+  }
+
+  public class VideoSupportFragment extends android.support.v17.leanback.app.PlaybackSupportFragment {
+    ctor public VideoSupportFragment();
+    method public android.view.SurfaceView getSurfaceView();
+    method public void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+  }
+
+  public class VideoSupportFragmentGlueHost extends android.support.v17.leanback.app.PlaybackSupportFragmentGlueHost implements android.support.v17.leanback.media.SurfaceHolderGlueHost {
+    ctor public VideoSupportFragmentGlueHost(android.support.v17.leanback.app.VideoSupportFragment);
+    method public void setSurfaceHolderCallback(android.view.SurfaceHolder.Callback);
+  }
+
+}
+
+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 class BoundsRule {
+    ctor public BoundsRule();
+    ctor public BoundsRule(android.support.v17.leanback.graphics.BoundsRule);
+    method public void calculateBounds(android.graphics.Rect, android.graphics.Rect);
+    field public android.support.v17.leanback.graphics.BoundsRule.ValueRule bottom;
+    field public android.support.v17.leanback.graphics.BoundsRule.ValueRule left;
+    field public android.support.v17.leanback.graphics.BoundsRule.ValueRule right;
+    field public android.support.v17.leanback.graphics.BoundsRule.ValueRule top;
+  }
+
+  public static final class BoundsRule.ValueRule {
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
+    method public int getAbsoluteValue();
+    method public float getFraction();
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
+    method public void setAbsoluteValue(int);
+    method public void setFraction(float);
+  }
+
+  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);
+  }
+
+  public class CompositeDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
+    ctor public CompositeDrawable();
+    method public void addChildDrawable(android.graphics.drawable.Drawable);
+    method public void draw(android.graphics.Canvas);
+    method public android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable getChildAt(int);
+    method public int getChildCount();
+    method public android.graphics.drawable.Drawable getDrawable(int);
+    method public int getOpacity();
+    method public void invalidateDrawable(android.graphics.drawable.Drawable);
+    method public void removeChild(int);
+    method public void removeDrawable(android.graphics.drawable.Drawable);
+    method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
+    method public void setAlpha(int);
+    method public void setChildDrawableAt(int, android.graphics.drawable.Drawable);
+    method public void setColorFilter(android.graphics.ColorFilter);
+    method public void unscheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable);
+  }
+
+  public static final class CompositeDrawable.ChildDrawable {
+    ctor public CompositeDrawable.ChildDrawable(android.graphics.drawable.Drawable, android.support.v17.leanback.graphics.CompositeDrawable);
+    method public android.support.v17.leanback.graphics.BoundsRule getBoundsRule();
+    method public android.graphics.drawable.Drawable getDrawable();
+    method public void recomputeBounds();
+    field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Integer> BOTTOM_ABSOLUTE;
+    field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Float> BOTTOM_FRACTION;
+    field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Integer> LEFT_ABSOLUTE;
+    field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Float> LEFT_FRACTION;
+    field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Integer> RIGHT_ABSOLUTE;
+    field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Float> RIGHT_FRACTION;
+    field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Integer> TOP_ABSOLUTE;
+    field public static final android.util.Property<android.support.v17.leanback.graphics.CompositeDrawable.ChildDrawable, java.lang.Float> TOP_FRACTION;
+  }
+
+  public class FitWidthBitmapDrawable extends android.graphics.drawable.Drawable {
+    ctor public FitWidthBitmapDrawable();
+    method public void draw(android.graphics.Canvas);
+    method public android.graphics.Bitmap getBitmap();
+    method public int getOpacity();
+    method public android.graphics.Rect getSource();
+    method public int getVerticalOffset();
+    method public void setAlpha(int);
+    method public void setBitmap(android.graphics.Bitmap);
+    method public void setColorFilter(android.graphics.ColorFilter);
+    method public void setSource(android.graphics.Rect);
+    method public void setVerticalOffset(int);
+    field public static final android.util.Property<android.support.v17.leanback.graphics.FitWidthBitmapDrawable, java.lang.Integer> PROPERTY_VERTICAL_OFFSET;
+  }
+
+}
+
+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 deprecated 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 android.support.v17.leanback.widget.PlaybackRowPresenter getPlaybackRowPresenter();
+    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 deprecated void setControlsRowPresenter(android.support.v17.leanback.widget.PlaybackControlsRowPresenter);
+    method public void setFadingEnabled(boolean);
+    method public void setPlaybackRowPresenter(android.support.v17.leanback.widget.PlaybackRowPresenter);
+    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 onHostDestroy();
+    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 DetailsParallax extends android.support.v17.leanback.widget.RecyclerViewParallax {
+    ctor public DetailsParallax();
+    method public android.support.v17.leanback.widget.Parallax.IntProperty getOverviewRowBottom();
+    method public android.support.v17.leanback.widget.Parallax.IntProperty getOverviewRowTop();
+  }
+
+  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);
+    method public static void setupHeaderItemFocusHighlight(android.support.v17.leanback.widget.VerticalGridView, boolean);
+  }
+
+  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 setPresenter(android.support.v17.leanback.widget.PresenterSelector);
+    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 abstract class Parallax<PropertyT extends android.util.Property> {
+    ctor public Parallax();
+    method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
+    method public final PropertyT addProperty(java.lang.String);
+    method public abstract PropertyT createProperty(java.lang.String, int);
+    method public java.util.List<android.support.v17.leanback.widget.ParallaxEffect> getEffects();
+    method public abstract float getMaxValue();
+    method public final java.util.List<PropertyT> getProperties();
+    method public void removeAllEffects();
+    method public void removeEffect(android.support.v17.leanback.widget.ParallaxEffect);
+    method public void updateValues();
+  }
+
+  public static class Parallax.FloatProperty extends android.util.Property {
+    ctor public Parallax.FloatProperty(java.lang.String, int);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(float, float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+    method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax);
+    method public final int getIndex();
+    method public final float getValue(android.support.v17.leanback.widget.Parallax);
+    method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Float);
+    method public final void setValue(android.support.v17.leanback.widget.Parallax, float);
+    field public static final float UNKNOWN_AFTER = 3.4028235E38f;
+    field public static final float UNKNOWN_BEFORE = -3.4028235E38f;
+  }
+
+  public static class Parallax.IntProperty extends android.util.Property {
+    ctor public Parallax.IntProperty(java.lang.String, int);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(int, float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(int);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+    method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax);
+    method public final int getIndex();
+    method public final int getValue(android.support.v17.leanback.widget.Parallax);
+    method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Integer);
+    method public final void setValue(android.support.v17.leanback.widget.Parallax, int);
+    field public static final int UNKNOWN_AFTER = 2147483647; // 0x7fffffff
+    field public static final int UNKNOWN_BEFORE = -2147483648; // 0x80000000
+  }
+
+  public static class Parallax.PropertyMarkerValue<PropertyT> {
+    ctor public Parallax.PropertyMarkerValue(PropertyT);
+    method public PropertyT getProperty();
+  }
+
+  public abstract class ParallaxEffect {
+    method public final void addTarget(android.support.v17.leanback.widget.ParallaxTarget);
+    method public final java.util.List<android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> getPropertyRanges();
+    method public final java.util.List<android.support.v17.leanback.widget.ParallaxTarget> getTargets();
+    method public final void performMapping(android.support.v17.leanback.widget.Parallax);
+    method public final void removeTarget(android.support.v17.leanback.widget.ParallaxTarget);
+    method public final void setPropertyRanges(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
+    method public final android.support.v17.leanback.widget.ParallaxEffect target(android.support.v17.leanback.widget.ParallaxTarget);
+    method public final android.support.v17.leanback.widget.ParallaxEffect target(java.lang.Object, android.animation.PropertyValuesHolder);
+    method public final <T, V extends java.lang.Number> android.support.v17.leanback.widget.ParallaxEffect target(T, android.util.Property<T, V>);
+  }
+
+  public abstract class ParallaxTarget {
+    ctor public ParallaxTarget();
+    method public void directUpdate(java.lang.Number);
+    method public boolean isDirectMapping();
+    method public void update(float);
+  }
+
+  public static final class ParallaxTarget.DirectPropertyTarget<T, V extends java.lang.Number> extends android.support.v17.leanback.widget.ParallaxTarget {
+    ctor public ParallaxTarget.DirectPropertyTarget(java.lang.Object, android.util.Property<T, V>);
+  }
+
+  public static final class ParallaxTarget.PropertyValuesHolderTarget extends android.support.v17.leanback.widget.ParallaxTarget {
+    ctor public ParallaxTarget.PropertyValuesHolderTarget(java.lang.Object, android.animation.PropertyValuesHolder);
+  }
+
+  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 RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax {
+    ctor public RecyclerViewParallax();
+    method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty createProperty(java.lang.String, int);
+    method public float getMaxValue();
+    method public android.support.v7.widget.RecyclerView getRecyclerView();
+    method public void setRecyclerView(android.support.v7.widget.RecyclerView);
+  }
+
+  public static final class RecyclerViewParallax.ChildPositionProperty extends android.support.v17.leanback.widget.Parallax.IntProperty {
+    method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty adapterPosition(int);
+    method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty fraction(float);
+    method public int getAdapterPosition();
+    method public float getFraction();
+    method public int getOffset();
+    method public int getViewId();
+    method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty offset(int);
+    method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty viewId(int);
+  }
+
+  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[]);
+  }
+
+  public class TimePicker extends android.support.v17.leanback.widget.picker.Picker {
+    ctor public TimePicker(android.content.Context, android.util.AttributeSet);
+    ctor public TimePicker(android.content.Context, android.util.AttributeSet, int);
+    method public int getHour();
+    method public int getMinute();
+    method public boolean is24Hour();
+    method public boolean isPm();
+    method public void setHour(int);
+    method public void setIs24Hour(boolean);
+    method public void setMinute(int);
+  }
+
+}
+
+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 deprecated 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 deprecated 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 final android.view.LayoutInflater getLayoutInflater();
+    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 android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle);
+    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 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;
+    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 java.util.List<android.support.v4.app.Fragment> getFragments();
+    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 java.lang.String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
+    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);
+  }
+
+  public final class PaintCompat {
+    method public static boolean hasGlyph(android.graphics.Paint, java.lang.String);
+  }
+
+}
+
+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.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 search(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.SearchCallback);
+    method public void sendCustomAction(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.CustomActionCallback);
+    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.CustomActionCallback {
+    ctor public MediaBrowserCompat.CustomActionCallback();
+    method public void onError(java.lang.String, android.os.Bundle, android.os.Bundle);
+    method public void onProgressUpdate(java.lang.String, android.os.Bundle, android.os.Bundle);
+    method public void onResult(java.lang.String, android.os.Bundle, android.os.Bundle);
+  }
+
+  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.SearchCallback {
+    ctor public MediaBrowserCompat.SearchCallback();
+    method public void onError(java.lang.String, android.os.Bundle);
+    method public void onSearchResult(java.lang.String, android.os.Bundle, java.util.List<android.support.v4.media.MediaBrowserCompat.MediaItem>);
+  }
+
+  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 void onCustomAction(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserServiceCompat.Result<android.os.Bundle>);
+    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 onSearch(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserServiceCompat.Result<java.util.List<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 deprecated 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 sendError(android.os.Bundle);
+    method public void sendProgressUpdate(android.os.Bundle);
+    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_ADVERTISEMENT = "android.media.metadata.ADVERTISEMENT";
+    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 deprecated class TransportController {
+    ctor public deprecated TransportController();
+    method public abstract deprecated int getBufferPercentage();
+    method public abstract deprecated long getCurrentPosition();
+    method public abstract deprecated long getDuration();
+    method public abstract deprecated int getTransportControlFlags();
+    method public abstract deprecated boolean isPlaying();
+    method public abstract deprecated void pausePlaying();
+    method public abstract deprecated void registerStateListener(android.support.v4.media.TransportStateListener);
+    method public abstract deprecated void seekTo(long);
+    method public abstract deprecated void startPlaying();
+    method public abstract deprecated void stopPlaying();
+    method public abstract deprecated void unregisterStateListener(android.support.v4.media.TransportStateListener);
+  }
+
+  public deprecated class TransportMediator extends android.support.v4.media.TransportController {
+    ctor public deprecated TransportMediator(android.app.Activity, android.support.v4.media.TransportPerformer);
+    ctor public deprecated TransportMediator(android.view.View, android.support.v4.media.TransportPerformer);
+    method public deprecated void destroy();
+    method public deprecated boolean dispatchKeyEvent(android.view.KeyEvent);
+    method public deprecated int getBufferPercentage();
+    method public deprecated long getCurrentPosition();
+    method public deprecated long getDuration();
+    method public deprecated java.lang.Object getRemoteControlClient();
+    method public deprecated int getTransportControlFlags();
+    method public deprecated boolean isPlaying();
+    method public deprecated void pausePlaying();
+    method public deprecated void refreshState();
+    method public deprecated void registerStateListener(android.support.v4.media.TransportStateListener);
+    method public deprecated void seekTo(long);
+    method public deprecated void startPlaying();
+    method public deprecated void stopPlaying();
+    method public deprecated void unregisterStateListener(android.support.v4.media.TransportStateListener);
+    field public static final deprecated int FLAG_KEY_MEDIA_FAST_FORWARD = 64; // 0x40
+    field public static final deprecated int FLAG_KEY_MEDIA_NEXT = 128; // 0x80
+    field public static final deprecated int FLAG_KEY_MEDIA_PAUSE = 16; // 0x10
+    field public static final deprecated int FLAG_KEY_MEDIA_PLAY = 4; // 0x4
+    field public static final deprecated int FLAG_KEY_MEDIA_PLAY_PAUSE = 8; // 0x8
+    field public static final deprecated int FLAG_KEY_MEDIA_PREVIOUS = 1; // 0x1
+    field public static final deprecated int FLAG_KEY_MEDIA_REWIND = 2; // 0x2
+    field public static final deprecated int FLAG_KEY_MEDIA_STOP = 32; // 0x20
+    field public static final deprecated int KEYCODE_MEDIA_PAUSE = 127; // 0x7f
+    field public static final deprecated int KEYCODE_MEDIA_PLAY = 126; // 0x7e
+    field public static final deprecated int KEYCODE_MEDIA_RECORD = 130; // 0x82
+  }
+
+  public abstract deprecated class TransportPerformer {
+    ctor public deprecated TransportPerformer();
+    method public deprecated void onAudioFocusChange(int);
+    method public deprecated int onGetBufferPercentage();
+    method public abstract deprecated long onGetCurrentPosition();
+    method public abstract deprecated long onGetDuration();
+    method public deprecated int onGetTransportControlFlags();
+    method public abstract deprecated boolean onIsPlaying();
+    method public deprecated boolean onMediaButtonDown(int, android.view.KeyEvent);
+    method public deprecated boolean onMediaButtonUp(int, android.view.KeyEvent);
+    method public abstract deprecated void onPause();
+    method public abstract deprecated void onSeekTo(long);
+    method public abstract deprecated void onStart();
+    method public abstract deprecated void onStop();
+  }
+
+  public deprecated class TransportStateListener {
+    ctor public deprecated TransportStateListener();
+    method public deprecated void onPlayingChanged(android.support.v4.media.TransportController);
+    method public deprecated 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 addQueueItem(android.support.v4.media.MediaDescriptionCompat);
+    method public void addQueueItem(android.support.v4.media.MediaDescriptionCompat, int);
+    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 isCaptioningEnabled();
+    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 removeQueueItem(android.support.v4.media.MediaDescriptionCompat);
+    method public void removeQueueItemAt(int);
+    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 onCaptioningEnabledChanged(boolean);
+    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 setCaptioningEnabled(boolean);
+    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 setCaptioningEnabled(boolean);
+    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 java.lang.String ACTION_FLAG_AS_INAPPROPRIATE = "android.support.v4.media.session.action.FLAG_AS_INAPPROPRIATE";
+    field public static final java.lang.String ACTION_SKIP_AD = "android.support.v4.media.session.action.SKIP_AD";
+    field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
+    field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
+    field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
+  }
+
+  public static abstract class MediaSessionCompat.Callback {
+    ctor public MediaSessionCompat.Callback();
+    method public void onAddQueueItem(android.support.v4.media.MediaDescriptionCompat);
+    method public void onAddQueueItem(android.support.v4.media.MediaDescriptionCompat, int);
+    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 onRemoveQueueItem(android.support.v4.media.MediaDescriptionCompat);
+    method public void onRemoveQueueItemAt(int);
+    method public void onRewind();
+    method public void onSeekTo(long);
+    method public void onSetCaptioningEnabled(boolean);
+    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 int getErrorCode();
+    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_CAPTIONING_ENABLED = 1048576L; // 0x100000L
+    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 int ERROR_CODE_ACTION_ABORTED = 10; // 0xa
+    field public static final int ERROR_CODE_APP_ERROR = 1; // 0x1
+    field public static final int ERROR_CODE_AUTHENTICATION_EXPIRED = 3; // 0x3
+    field public static final int ERROR_CODE_CONCURRENT_STREAM_LIMIT = 5; // 0x5
+    field public static final int ERROR_CODE_CONTENT_ALREADY_PLAYING = 8; // 0x8
+    field public static final int ERROR_CODE_END_OF_QUEUE = 11; // 0xb
+    field public static final int ERROR_CODE_NOT_AVAILABLE_IN_REGION = 7; // 0x7
+    field public static final int ERROR_CODE_NOT_SUPPORTED = 2; // 0x2
+    field public static final int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED = 6; // 0x6
+    field public static final int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED = 4; // 0x4
+    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
+    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 deprecated android.support.v4.media.session.PlaybackStateCompat.Builder setErrorMessage(java.lang.CharSequence);
+    method public android.support.v4.media.session.PlaybackStateCompat.Builder setErrorMessage(int, 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 class ImageViewCompat {
+    method public static android.content.res.ColorStateList getImageTintList(android.widget.ImageView);
+    method public static android.graphics.PorterDuff.Mode getImageTintMode(android.widget.ImageView);
+    method public static void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList);
+    method public static void setImageTintMode(android.widget.ImageView, android.graphics.PorterDuff.Mode);
+  }
+
+  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 boolean isDrawerSlideAnimationEnabled();
+    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 setDrawerSlideAnimationEnabled(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 deprecated int getInitialItemPrefetchCount();
+    method public int getInitialPrefetchItemCount();
+    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 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);
+    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 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);
+    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 a6cde7b..30642f1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1,3 +1,105 @@
+package android.support.animation {
+
+  public abstract class DynamicAnimation<T extends android.support.animation.DynamicAnimation<T>> {
+    method public T addEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+    method public T addUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+    method public void cancel();
+    method public float getMinimumVisibleChange();
+    method public boolean isRunning();
+    method public void removeEndListener(android.support.animation.DynamicAnimation.OnAnimationEndListener);
+    method public void removeUpdateListener(android.support.animation.DynamicAnimation.OnAnimationUpdateListener);
+    method public T setMaxValue(float);
+    method public T setMinValue(float);
+    method public T setMinimumVisibleChange(float);
+    method public T setStartValue(float);
+    method public T setStartVelocity(float);
+    method public void start();
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ALPHA;
+    field public static final float MIN_VISIBLE_CHANGE_ALPHA = 0.00390625f;
+    field public static final float MIN_VISIBLE_CHANGE_PIXELS = 1.0f;
+    field public static final float MIN_VISIBLE_CHANGE_ROTATION_DEGREES = 0.1f;
+    field public static final float MIN_VISIBLE_CHANGE_SCALE = 0.002f;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty ROTATION_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCALE_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty SCROLL_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty TRANSLATION_Z;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty X;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty Y;
+    field public static final android.support.animation.DynamicAnimation.ViewProperty Z;
+  }
+
+  public static abstract interface DynamicAnimation.OnAnimationEndListener {
+    method public abstract void onAnimationEnd(android.support.animation.DynamicAnimation, boolean, float, float);
+  }
+
+  public static abstract interface DynamicAnimation.OnAnimationUpdateListener {
+    method public abstract void onAnimationUpdate(android.support.animation.DynamicAnimation, float, float);
+  }
+
+  public static abstract class DynamicAnimation.ViewProperty extends android.support.animation.FloatPropertyCompat {
+  }
+
+  public final class FlingAnimation extends android.support.animation.DynamicAnimation {
+    ctor public FlingAnimation(android.support.animation.FloatValueHolder);
+    ctor public FlingAnimation(K, android.support.animation.FloatPropertyCompat<K>);
+    method public float getFriction();
+    method public android.support.animation.FlingAnimation setFriction(float);
+  }
+
+  public abstract class FloatPropertyCompat<T> {
+    ctor public FloatPropertyCompat(java.lang.String);
+    method public static <T> android.support.animation.FloatPropertyCompat<T> createFloatPropertyCompat(android.util.FloatProperty<T>);
+    method public abstract float getValue(T);
+    method public abstract void setValue(T, float);
+  }
+
+  public final class FloatValueHolder {
+    ctor public FloatValueHolder();
+    ctor public FloatValueHolder(float);
+    method public float getValue();
+    method public void setValue(float);
+  }
+
+  public final class SpringAnimation extends android.support.animation.DynamicAnimation {
+    ctor public SpringAnimation(android.support.animation.FloatValueHolder);
+    ctor public SpringAnimation(K, android.support.animation.FloatPropertyCompat<K>);
+    ctor public SpringAnimation(K, android.support.animation.FloatPropertyCompat<K>, float);
+    ctor public deprecated SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty);
+    ctor public deprecated SpringAnimation(android.view.View, android.support.animation.DynamicAnimation.ViewProperty, float);
+    method public void animateToFinalPosition(float);
+    method public boolean canSkipToEnd();
+    method public android.support.animation.SpringForce getSpring();
+    method public android.support.animation.SpringAnimation setSpring(android.support.animation.SpringForce);
+    method public void skipToEnd();
+  }
+
+  public final class SpringForce {
+    ctor public SpringForce();
+    ctor public SpringForce(float);
+    method public float getDampingRatio();
+    method public float getFinalPosition();
+    method public float getStiffness();
+    method public android.support.animation.SpringForce setDampingRatio(float);
+    method public android.support.animation.SpringForce setFinalPosition(float);
+    method public android.support.animation.SpringForce setStiffness(float);
+    field public static final float DAMPING_RATIO_HIGH_BOUNCY = 0.2f;
+    field public static final float DAMPING_RATIO_LOW_BOUNCY = 0.75f;
+    field public static final float DAMPING_RATIO_MEDIUM_BOUNCY = 0.5f;
+    field public static final float DAMPING_RATIO_NO_BOUNCY = 1.0f;
+    field public static final float STIFFNESS_HIGH = 10000.0f;
+    field public static final float STIFFNESS_LOW = 200.0f;
+    field public static final float STIFFNESS_MEDIUM = 1500.0f;
+    field public static final float STIFFNESS_VERY_LOW = 50.0f;
+  }
+
+}
+
 package android.support.app.recommendation {
 
   public final class ContentRecommendation {
@@ -870,16 +972,34 @@
 
 package android.support.graphics.drawable {
 
-  public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon {
+  public abstract interface Animatable2Compat {
+    method public abstract void clearAnimationCallbacks();
+    method public abstract void registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public abstract boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+  }
+
+  public static abstract class Animatable2Compat.AnimationCallback {
+    ctor public Animatable2Compat.AnimationCallback();
+    method public void onAnimationEnd(android.graphics.drawable.Drawable);
+    method public void onAnimationStart(android.graphics.drawable.Drawable);
+  }
+
+  public class AnimatedVectorDrawableCompat extends android.support.graphics.drawable.VectorDrawableCommon implements android.support.graphics.drawable.Animatable2Compat {
+    method public void clearAnimationCallbacks();
+    method public static void clearAnimationCallbacks(android.graphics.drawable.Drawable);
     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 registerAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public static void registerAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
     method public void setAlpha(int);
     method public void setColorFilter(android.graphics.ColorFilter);
     method public void start();
     method public void stop();
+    method public boolean unregisterAnimationCallback(android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
+    method public static boolean unregisterAnimationCallback(android.graphics.drawable.Drawable, android.support.graphics.drawable.Animatable2Compat.AnimationCallback);
   }
 
    abstract class VectorDrawableCommon extends android.graphics.drawable.Drawable {
@@ -1769,6 +1889,7 @@
 
   public class DetailsFragmentBackgroundController {
     ctor public DetailsFragmentBackgroundController(android.support.v17.leanback.app.DetailsFragment);
+    method public boolean canNavigateToVideoFragment();
     method public void enableParallax();
     method public void enableParallax(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.support.v17.leanback.widget.ParallaxTarget.PropertyValuesHolderTarget);
     method public final android.app.Fragment findOrCreateVideoFragment();
@@ -1776,6 +1897,7 @@
     method public final android.graphics.Bitmap getCoverBitmap();
     method public final android.graphics.drawable.Drawable getCoverDrawable();
     method public final int getParallaxDrawableMaxOffset();
+    method public final android.support.v17.leanback.media.PlaybackGlue getPlaybackGlue();
     method public final int getSolidColor();
     method public android.support.v17.leanback.media.PlaybackGlueHost onCreateGlueHost();
     method public android.app.Fragment onCreateVideoFragment();
@@ -1783,6 +1905,8 @@
     method public final void setParallaxDrawableMaxOffset(int);
     method public final void setSolidColor(int);
     method public void setupVideoPlayback(android.support.v17.leanback.media.PlaybackGlue);
+    method public final void switchToRows();
+    method public final void switchToVideo();
   }
 
   public class DetailsSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
@@ -1810,6 +1934,7 @@
 
   public class DetailsSupportFragmentBackgroundController {
     ctor public DetailsSupportFragmentBackgroundController(android.support.v17.leanback.app.DetailsSupportFragment);
+    method public boolean canNavigateToVideoSupportFragment();
     method public void enableParallax();
     method public void enableParallax(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.support.v17.leanback.widget.ParallaxTarget.PropertyValuesHolderTarget);
     method public final android.support.v4.app.Fragment findOrCreateVideoSupportFragment();
@@ -1817,6 +1942,7 @@
     method public final android.graphics.Bitmap getCoverBitmap();
     method public final android.graphics.drawable.Drawable getCoverDrawable();
     method public final int getParallaxDrawableMaxOffset();
+    method public final android.support.v17.leanback.media.PlaybackGlue getPlaybackGlue();
     method public final int getSolidColor();
     method public android.support.v17.leanback.media.PlaybackGlueHost onCreateGlueHost();
     method public android.support.v4.app.Fragment onCreateVideoSupportFragment();
@@ -1824,6 +1950,8 @@
     method public final void setParallaxDrawableMaxOffset(int);
     method public final void setSolidColor(int);
     method public void setupVideoPlayback(android.support.v17.leanback.media.PlaybackGlue);
+    method public final void switchToRows();
+    method public final void switchToVideo();
   }
 
   public class ErrorFragment extends android.support.v17.leanback.app.BrandedFragment {
@@ -2032,12 +2160,16 @@
     method protected abstract int getPageCount();
     method protected abstract java.lang.CharSequence getPageDescription(int);
     method protected abstract java.lang.CharSequence getPageTitle(int);
+    method protected final boolean isLogoAnimationFinished();
+    method protected void moveToNextPage();
+    method protected void moveToPreviousPage();
     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 onCreateEnterAnimation();
     method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
     method protected android.animation.Animator onCreateLogoAnimation();
     method protected void onFinishFragment();
+    method protected void onLogoAnimationFinished();
     method protected void onPageChanged(int, int);
     method public int onProvideTheme();
     method public final void setLogoResourceId(int);
@@ -2050,12 +2182,16 @@
     method protected abstract int getPageCount();
     method protected abstract java.lang.CharSequence getPageDescription(int);
     method protected abstract java.lang.CharSequence getPageTitle(int);
+    method protected final boolean isLogoAnimationFinished();
+    method protected void moveToNextPage();
+    method protected void moveToPreviousPage();
     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 onCreateEnterAnimation();
     method protected abstract android.view.View onCreateForegroundView(android.view.LayoutInflater, android.view.ViewGroup);
     method protected android.animation.Animator onCreateLogoAnimation();
     method protected void onFinishFragment();
+    method protected void onLogoAnimationFinished();
     method protected void onPageChanged(int, int);
     method public int onProvideTheme();
     method public final void setLogoResourceId(int);
@@ -2414,10 +2550,7 @@
   public class BoundsRule {
     ctor public BoundsRule();
     ctor public BoundsRule(android.support.v17.leanback.graphics.BoundsRule);
-    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
     method public void calculateBounds(android.graphics.Rect, android.graphics.Rect);
-    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
-    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
     field public android.support.v17.leanback.graphics.BoundsRule.ValueRule bottom;
     field public android.support.v17.leanback.graphics.BoundsRule.ValueRule left;
     field public android.support.v17.leanback.graphics.BoundsRule.ValueRule right;
@@ -2425,8 +2558,11 @@
   }
 
   public static final class BoundsRule.ValueRule {
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule absoluteValue(int);
     method public int getAbsoluteValue();
     method public float getFraction();
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParent(float);
+    method public static android.support.v17.leanback.graphics.BoundsRule.ValueRule inheritFromParentWithOffset(float, int);
     method public void setAbsoluteValue(int);
     method public void setFraction(float);
   }
@@ -2530,7 +2666,7 @@
     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 deprecated android.support.v17.leanback.widget.PlaybackControlsRowPresenter getControlsRowPresenter();
     method public abstract int getCurrentPosition();
     method public abstract int getCurrentSpeedId();
     method public int[] getFastForwardSpeeds();
@@ -2538,6 +2674,7 @@
     method public abstract int getMediaDuration();
     method public abstract java.lang.CharSequence getMediaSubtitle();
     method public abstract java.lang.CharSequence getMediaTitle();
+    method public android.support.v17.leanback.widget.PlaybackRowPresenter getPlaybackRowPresenter();
     method public int[] getRewindSpeeds();
     method public abstract long getSupportedActions();
     method public int getUpdatePeriod();
@@ -2554,8 +2691,9 @@
     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 deprecated void setControlsRowPresenter(android.support.v17.leanback.widget.PlaybackControlsRowPresenter);
     method public void setFadingEnabled(boolean);
+    method public void setPlaybackRowPresenter(android.support.v17.leanback.widget.PlaybackRowPresenter);
     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
@@ -3532,111 +3670,79 @@
 
   public abstract class Parallax<PropertyT extends android.util.Property> {
     ctor public Parallax();
-    method public void addEffect(android.support.v17.leanback.widget.ParallaxEffect);
-    method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue...);
-    method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue...);
-    method public abstract PropertyT addProperty(java.lang.String);
+    method public android.support.v17.leanback.widget.ParallaxEffect addEffect(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
+    method public final PropertyT addProperty(java.lang.String);
     method public abstract PropertyT createProperty(java.lang.String, int);
     method public java.util.List<android.support.v17.leanback.widget.ParallaxEffect> getEffects();
+    method public abstract float getMaxValue();
     method public final java.util.List<PropertyT> getProperties();
     method public void removeAllEffects();
     method public void removeEffect(android.support.v17.leanback.widget.ParallaxEffect);
     method public void updateValues();
-    method public abstract void verifyProperties() throws java.lang.IllegalStateException;
-  }
-
-  public static abstract class Parallax.FloatParallax<FloatPropertyT extends android.support.v17.leanback.widget.Parallax.FloatProperty> extends android.support.v17.leanback.widget.Parallax {
-    ctor public Parallax.FloatParallax();
-    method public final FloatPropertyT addProperty(java.lang.String);
-    method public abstract float getMaxValue();
-    method public final float getPropertyValue(int);
-    method public final void setPropertyValue(int, float);
-    method public final void verifyProperties() throws java.lang.IllegalStateException;
   }
 
   public static class Parallax.FloatProperty extends android.util.Property {
     ctor public Parallax.FloatProperty(java.lang.String, int);
-    method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue at(float, float);
-    method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atAbsolute(float);
-    method public final android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue atFraction(float);
-    method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax.FloatParallax);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(float, float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+    method public final java.lang.Float get(android.support.v17.leanback.widget.Parallax);
     method public final int getIndex();
-    method public final void set(android.support.v17.leanback.widget.Parallax.FloatParallax, java.lang.Float);
+    method public final float getValue(android.support.v17.leanback.widget.Parallax);
+    method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Float);
+    method public final void setValue(android.support.v17.leanback.widget.Parallax, float);
     field public static final float UNKNOWN_AFTER = 3.4028235E38f;
     field public static final float UNKNOWN_BEFORE = -3.4028235E38f;
   }
 
-  public static class Parallax.FloatPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
-    ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float);
-    ctor public Parallax.FloatPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.FloatProperty, float, float);
-    method public final float getMarkerValue(android.support.v17.leanback.widget.Parallax.FloatParallax);
-  }
-
-  public static abstract class Parallax.IntParallax<IntPropertyT extends android.support.v17.leanback.widget.Parallax.IntProperty> extends android.support.v17.leanback.widget.Parallax {
-    ctor public Parallax.IntParallax();
-    method public final IntPropertyT addProperty(java.lang.String);
-    method public abstract int getMaxValue();
-    method public final int getPropertyValue(int);
-    method public final void setPropertyValue(int, int);
-    method public final void verifyProperties() throws java.lang.IllegalStateException;
-  }
-
   public static class Parallax.IntProperty extends android.util.Property {
     ctor public Parallax.IntProperty(java.lang.String, int);
-    method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue at(int, float);
-    method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atAbsolute(int);
-    method public final android.support.v17.leanback.widget.Parallax.IntPropertyMarkerValue atFraction(float);
-    method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax.IntParallax);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue at(int, float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atAbsolute(int);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atFraction(float);
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMax();
+    method public final android.support.v17.leanback.widget.Parallax.PropertyMarkerValue atMin();
+    method public final java.lang.Integer get(android.support.v17.leanback.widget.Parallax);
     method public final int getIndex();
-    method public final void set(android.support.v17.leanback.widget.Parallax.IntParallax, java.lang.Integer);
+    method public final int getValue(android.support.v17.leanback.widget.Parallax);
+    method public final void set(android.support.v17.leanback.widget.Parallax, java.lang.Integer);
+    method public final void setValue(android.support.v17.leanback.widget.Parallax, int);
     field public static final int UNKNOWN_AFTER = 2147483647; // 0x7fffffff
     field public static final int UNKNOWN_BEFORE = -2147483648; // 0x80000000
   }
 
-  public static class Parallax.IntPropertyMarkerValue extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue {
-    ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int);
-    ctor public Parallax.IntPropertyMarkerValue(android.support.v17.leanback.widget.Parallax.IntProperty, int, float);
-    method public final int getMarkerValue(android.support.v17.leanback.widget.Parallax.IntParallax);
-  }
-
   public static class Parallax.PropertyMarkerValue<PropertyT> {
     ctor public Parallax.PropertyMarkerValue(PropertyT);
     method public PropertyT getProperty();
   }
 
-  public abstract class ParallaxEffect<ParallaxEffectT extends android.support.v17.leanback.widget.ParallaxEffect, PropertyMarkerValueT extends android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> {
-    ctor public ParallaxEffect();
+  public abstract class ParallaxEffect {
     method public final void addTarget(android.support.v17.leanback.widget.ParallaxTarget);
-    method protected abstract float calculateFraction(android.support.v17.leanback.widget.Parallax);
-    method public final java.util.List<PropertyMarkerValueT> getPropertyRanges();
+    method public final java.util.List<android.support.v17.leanback.widget.Parallax.PropertyMarkerValue> getPropertyRanges();
     method public final java.util.List<android.support.v17.leanback.widget.ParallaxTarget> getTargets();
     method public final void performMapping(android.support.v17.leanback.widget.Parallax);
     method public final void removeTarget(android.support.v17.leanback.widget.ParallaxTarget);
-    method public final void setPropertyRanges(PropertyMarkerValueT...);
+    method public final void setPropertyRanges(android.support.v17.leanback.widget.Parallax.PropertyMarkerValue...);
     method public final android.support.v17.leanback.widget.ParallaxEffect target(android.support.v17.leanback.widget.ParallaxTarget);
     method public final android.support.v17.leanback.widget.ParallaxEffect target(java.lang.Object, android.animation.PropertyValuesHolder);
-  }
-
-  public static final class ParallaxEffect.FloatEffect extends android.support.v17.leanback.widget.ParallaxEffect {
-    ctor public ParallaxEffect.FloatEffect();
-    method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
-  }
-
-  public static final class ParallaxEffect.IntEffect extends android.support.v17.leanback.widget.ParallaxEffect {
-    ctor public ParallaxEffect.IntEffect();
-    method protected float calculateFraction(android.support.v17.leanback.widget.Parallax);
+    method public final <T, V extends java.lang.Number> android.support.v17.leanback.widget.ParallaxEffect target(T, android.util.Property<T, V>);
   }
 
   public abstract class ParallaxTarget {
     ctor public ParallaxTarget();
-    method public abstract float getFraction();
-    method public abstract void update(float);
+    method public void directUpdate(java.lang.Number);
+    method public boolean isDirectMapping();
+    method public void update(float);
+  }
+
+  public static final class ParallaxTarget.DirectPropertyTarget<T, V extends java.lang.Number> extends android.support.v17.leanback.widget.ParallaxTarget {
+    ctor public ParallaxTarget.DirectPropertyTarget(java.lang.Object, android.util.Property<T, V>);
   }
 
   public static final class ParallaxTarget.PropertyValuesHolderTarget extends android.support.v17.leanback.widget.ParallaxTarget {
     ctor public ParallaxTarget.PropertyValuesHolderTarget(java.lang.Object, android.animation.PropertyValuesHolder);
-    method public float getFraction();
-    method public void update(float);
   }
 
   public class PlaybackControlsRow extends android.support.v17.leanback.widget.Row {
@@ -3828,10 +3934,10 @@
     method public void unselect();
   }
 
-  public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax.IntParallax {
+  public class RecyclerViewParallax extends android.support.v17.leanback.widget.Parallax {
     ctor public RecyclerViewParallax();
     method public android.support.v17.leanback.widget.RecyclerViewParallax.ChildPositionProperty createProperty(java.lang.String, int);
-    method public int getMaxValue();
+    method public float getMaxValue();
     method public android.support.v7.widget.RecyclerView getRecyclerView();
     method public void setRecyclerView(android.support.v7.widget.RecyclerView);
   }
@@ -4391,13 +4497,13 @@
     method public void syncState();
   }
 
-  public static abstract interface ActionBarDrawerToggle.Delegate {
+  public static abstract deprecated 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 {
+  public static abstract deprecated interface ActionBarDrawerToggle.DelegateProvider {
     method public abstract android.support.v4.app.ActionBarDrawerToggle.Delegate getDrawerToggleDelegate();
   }
 
@@ -4501,6 +4607,7 @@
     method public final android.support.v4.app.FragmentManager getFragmentManager();
     method public final java.lang.Object getHost();
     method public final int getId();
+    method public final android.view.LayoutInflater getLayoutInflater();
     method public android.support.v4.app.LoaderManager getLoaderManager();
     method public final android.support.v4.app.Fragment getParentFragment();
     method public java.lang.Object getReenterTransition();
@@ -4543,6 +4650,7 @@
     method public void onDestroyOptionsMenu();
     method public void onDestroyView();
     method public void onDetach();
+    method public android.view.LayoutInflater onGetLayoutInflater(android.os.Bundle);
     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);
@@ -4703,6 +4811,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 java.util.List<android.support.v4.app.Fragment> getFragments();
     method public abstract boolean isDestroyed();
     method public abstract void popBackStack();
     method public abstract void popBackStack(java.lang.String, int);
@@ -5431,6 +5540,7 @@
     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 java.lang.String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
     field public static final int FLAG_ACTIVITY_CLEAR_TASK = 32768; // 0x8000
     field public static final int FLAG_ACTIVITY_TASK_ON_HOME = 16384; // 0x4000
   }
@@ -5704,6 +5814,7 @@
     method public android.support.v4.media.session.MediaSessionCompat.Token getSessionToken();
     method public boolean isConnected();
     method public void search(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.SearchCallback);
+    method public void sendCustomAction(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserCompat.CustomActionCallback);
     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);
@@ -5719,6 +5830,13 @@
     method public void onConnectionSuspended();
   }
 
+  public static abstract class MediaBrowserCompat.CustomActionCallback {
+    ctor public MediaBrowserCompat.CustomActionCallback();
+    method public void onError(java.lang.String, android.os.Bundle, android.os.Bundle);
+    method public void onProgressUpdate(java.lang.String, android.os.Bundle, android.os.Bundle);
+    method public void onResult(java.lang.String, android.os.Bundle, android.os.Bundle);
+  }
+
   public static abstract class MediaBrowserCompat.ItemCallback {
     ctor public MediaBrowserCompat.ItemCallback();
     method public void onError(java.lang.String);
@@ -5763,6 +5881,7 @@
     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 void onCustomAction(java.lang.String, android.os.Bundle, android.support.v4.media.MediaBrowserServiceCompat.Result<android.os.Bundle>);
     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);
@@ -5784,6 +5903,8 @@
 
   public static class MediaBrowserServiceCompat.Result<T> {
     method public void detach();
+    method public void sendError(android.os.Bundle);
+    method public void sendProgressUpdate(android.os.Bundle);
     method public void sendResult(T);
   }
 
@@ -6031,6 +6152,7 @@
     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 isCaptioningEnabled();
     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);
@@ -6046,6 +6168,7 @@
     ctor public MediaControllerCompat.Callback();
     method public void binderDied();
     method public void onAudioInfoChanged(android.support.v4.media.session.MediaControllerCompat.PlaybackInfo);
+    method public void onCaptioningEnabledChanged(boolean);
     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);
@@ -6082,6 +6205,7 @@
     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 setCaptioningEnabled(boolean);
     method public abstract void setRating(android.support.v4.media.RatingCompat);
     method public abstract void setRepeatMode(int);
     method public abstract void setShuffleModeEnabled(boolean);
@@ -6108,6 +6232,7 @@
     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 setCaptioningEnabled(boolean);
     method public void setExtras(android.os.Bundle);
     method public void setFlags(int);
     method public void setMediaButtonReceiver(android.app.PendingIntent);
@@ -6121,6 +6246,8 @@
     method public void setRepeatMode(int);
     method public void setSessionActivity(android.app.PendingIntent);
     method public void setShuffleModeEnabled(boolean);
+    field public static final java.lang.String ACTION_FLAG_AS_INAPPROPRIATE = "android.support.v4.media.session.action.FLAG_AS_INAPPROPRIATE";
+    field public static final java.lang.String ACTION_SKIP_AD = "android.support.v4.media.session.action.SKIP_AD";
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
     field public static final int FLAG_HANDLES_QUEUE_COMMANDS = 4; // 0x4
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
@@ -6147,6 +6274,7 @@
     method public void onRemoveQueueItemAt(int);
     method public void onRewind();
     method public void onSeekTo(long);
+    method public void onSetCaptioningEnabled(boolean);
     method public void onSetRating(android.support.v4.media.RatingCompat);
     method public void onSetRepeatMode(int);
     method public void onSetShuffleModeEnabled(boolean);
@@ -6225,6 +6353,7 @@
     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_CAPTIONING_ENABLED = 1048576L; // 0x100000L
     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
@@ -8024,6 +8153,13 @@
     field public static final int INVALID_ID = -2147483648; // 0x80000000
   }
 
+  public class ImageViewCompat {
+    method public static android.content.res.ColorStateList getImageTintList(android.widget.ImageView);
+    method public static android.graphics.PorterDuff.Mode getImageTintMode(android.widget.ImageView);
+    method public static void setImageTintList(android.widget.ImageView, android.content.res.ColorStateList);
+    method public static void setImageTintMode(android.widget.ImageView, android.graphics.PorterDuff.Mode);
+  }
+
   public final class ListPopupWindowCompat {
     method public static android.view.View.OnTouchListener createDragToOpenListener(java.lang.Object, android.view.View);
   }
@@ -10139,7 +10275,8 @@
     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 deprecated int getInitialItemPrefetchCount();
+    method public int getInitialPrefetchItemCount();
     method public int getOrientation();
     method public boolean getRecycleChildrenOnDetach();
     method public boolean getReverseLayout();
diff --git a/build.gradle b/build.gradle
index d3312bc..ddb70c5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -40,8 +40,8 @@
     doclava project(':doclava')
 }
 
-ext.supportVersion = '25.3.0-SNAPSHOT'
-ext.extraVersion = 44
+ext.supportVersion = '25.4.0'
+ext.extraVersion = 49
 ext.supportRepoOut = ''
 ext.buildNumber = Integer.toString(ext.extraVersion)
 
@@ -236,7 +236,6 @@
     options {
         addStringOption "templatedir",
                 "${project.rootDir}/../../build/tools/droiddoc/templates-sdk"
-        addStringOption "federate Android", "http://developer.android.com"
         addStringOption "stubpackages", "android.support.*"
         addStringOption "samplesdir", "${project.rootDir}/samples"
         addOption hdfOption
@@ -260,7 +259,6 @@
     options {
         addStringOption "templatedir",
                 "${project.rootDir}/../../build/tools/droiddoc/templates-sdk"
-        addStringOption "federate Android", "http://developer.android.com"
         addStringOption "stubpackages", "android.support.*"
     }
     exclude '**/BuildConfig.java'
@@ -366,78 +364,51 @@
             // Add library to the aggregate dependency report.
             task allDeps(type: DependencyReportTask) {}
 
-            // Create release and separate zip task for library.
-            task release(type: Upload) {
-                configuration = configurations.archives
-                repositories {
-                    mavenDeployer {
-                        repository(url: uri("$rootProject.ext.supportRepoOut"))
+            project.afterEvaluate {
+                Upload uploadTask = (Upload) project.tasks.uploadArchives;
 
-                        // Disable unique names for SNAPSHOTS so they can be updated in place.
-                        setUniqueVersion(false)
-                        doLast {
-                            // Remove any invalid maven-metadata.xml files that may have been
-                            // created for SNAPSHOT versions that are *not* uniquely versioned.
-                            pom*.each { pom ->
-                                if (pom.version.endsWith('-SNAPSHOT')) {
-                                    final File artifactDir = new File(
-                                            rootProject.ext.supportRepoOut,
-                                            pom.groupId.replace('.', '/')
-                                                    + '/' + pom.artifactId
-                                                    + '/' + pom.version)
-                                    delete fileTree(dir: artifactDir,
-                                            include: 'maven-metadata.xml*')
-                                }
-                            }
+                uploadTask.repositories.mavenDeployer {
+                    // Disable unique names for SNAPSHOTS so they can be updated in place.
+                    setUniqueVersion(false)
+                }
+
+                uploadTask.doLast {
+                    // Remove any invalid maven-metadata.xml files that may have been
+                    // created for SNAPSHOT versions that are *not* uniquely versioned.
+                    repositories.mavenDeployer.pom*.each { pom ->
+                        if (pom.version.endsWith('-SNAPSHOT')) {
+                            final File artifactDir = new File(
+                                    rootProject.ext.supportRepoOut,
+                                    pom.groupId.replace('.', '/')
+                                            + '/' + pom.artifactId
+                                            + '/' + pom.version)
+                            delete fileTree(dir: artifactDir,
+                                    include: 'maven-metadata.xml*')
                         }
                     }
                 }
+
+                uploadTask.repositories.mavenDeployer.pom*.whenConfigured { pom ->
+                    pom.dependencies.findAll { dep ->
+                        dep.groupId == 'com.android.support' &&
+                                dep.artifactId != 'support-annotations'
+                    }*.type = 'aar'
+                }
+
+                task createSeparateZip(type: Zip)  {
+                    into archivesBaseName
+                    destinationDir project.parent.ext.distDir
+                    baseName = project.group
+                    version = project.parent.ext.buildNumber
+                }
+                project.parent.createArchive.dependsOn createSeparateZip
+
+                // Before the upload, make sure the repo is ready.
+                uploadTask.dependsOn rootProject.tasks.prepareRepo
+
+                // Make the mainupload depend on this one.
+                mainUpload.dependsOn uploadTask
             }
-
-            def deployer = release.repositories.mavenDeployer
-            deployer.pom*.whenConfigured { pom ->
-                pom.dependencies.findAll { dep ->
-                    dep.groupId == 'com.android.support' && dep.artifactId != 'support-annotations'
-                }*.type = 'aar'
-            }
-
-            ext.versionDir = {
-                def groupDir = new File(rootProject.ext.supportRepoOut,
-                        project.group.replace('.','/'))
-                def artifactDir = new File(groupDir, archivesBaseName)
-                return new File(artifactDir, version)
-            }
-
-            task generateSourceProps(dependsOn: createRepository) << {
-                def content = "Maven.GroupId=$deployer.pom.groupId\n" +
-                        "Maven.ArtifactId=$deployer.pom.artifactId\n" +
-                        "Maven.Version=$deployer.pom.version\n" +
-                        "Extra.VendorDisplay=Android\n" +
-                        "Extra.VendorId=android\n" +
-                        "Pkg.Desc=$project.name\n" +
-                        "Pkg.Revision=1\n" +
-                        "Maven.Dependencies=" +
-                        String.join(",", project.configurations.compile.allDependencies.collect {
-                            def p = parent.findProject(it.name)
-                            return p ? "$p.group:$p.archivesBaseName:$p.version" : null
-                        }.grep()) +
-                        "\n"
-                Files.write(content, new File(versionDir(), 'source.properties'), Charsets.UTF_8)
-            }
-
-            task createSeparateZip(type: Zip, dependsOn: generateSourceProps)  {
-                into archivesBaseName
-                destinationDir project.parent.ext.distDir
-                baseName = project.group
-                version = project.parent.ext.buildNumber
-            }
-            project.parent.createArchive.dependsOn createSeparateZip
-
-            // Before the upload, make sure the repo is ready.
-            release.dependsOn rootProject.tasks.prepareRepo
-
-            // Make the mainupload depend on this one.
-            mainUpload.dependsOn release
         }
     }
 
diff --git a/compat/AndroidManifest.xml b/compat/AndroidManifest.xml
index 55ddcff..54d7767 100644
--- a/compat/AndroidManifest.xml
+++ b/compat/AndroidManifest.xml
@@ -17,6 +17,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.compat">
     <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.compat"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/compat/api21/android/support/v4/view/ViewCompatLollipop.java b/compat/api21/android/support/v4/view/ViewCompatLollipop.java
index 9828165..1f226fc 100644
--- a/compat/api21/android/support/v4/view/ViewCompatLollipop.java
+++ b/compat/api21/android/support/v4/view/ViewCompatLollipop.java
@@ -16,13 +16,13 @@
 
 package android.support.v4.view;
 
+import android.annotation.TargetApi;
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 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;
diff --git a/compat/api21/android/support/v4/widget/ImageViewCompatLollipop.java b/compat/api21/android/support/v4/widget/ImageViewCompatLollipop.java
new file mode 100644
index 0000000..c5279d0
--- /dev/null
+++ b/compat/api21/android/support/v4/widget/ImageViewCompatLollipop.java
@@ -0,0 +1,71 @@
+/*
+ * 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.widget;
+
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.widget.ImageView;
+
+@RequiresApi(21)
+class ImageViewCompatLollipop {
+    static ColorStateList getImageTintList(ImageView view) {
+        return view.getImageTintList();
+    }
+
+    static void setImageTintList(ImageView view, ColorStateList tintList) {
+        view.setImageTintList(tintList);
+
+        if (Build.VERSION.SDK_INT == 21) {
+            // Work around a bug in L that did not update the state of the image source
+            // after applying the tint
+            Drawable imageViewDrawable = view.getDrawable();
+            boolean hasTint = (view.getImageTintList() != null)
+                    && (view.getImageTintMode() != null);
+            if ((imageViewDrawable != null) && hasTint) {
+                if (imageViewDrawable.isStateful()) {
+                    imageViewDrawable.setState(view.getDrawableState());
+                }
+                view.setImageDrawable(imageViewDrawable);
+            }
+        }
+    }
+
+    static PorterDuff.Mode getImageTintMode(ImageView view) {
+        return view.getImageTintMode();
+    }
+
+    static void setImageTintMode(ImageView view, PorterDuff.Mode mode) {
+        view.setImageTintMode(mode);
+
+        if (Build.VERSION.SDK_INT == 21) {
+            // Work around a bug in L that did not update the state of the image source
+            // after applying the tint
+            Drawable imageViewDrawable = view.getDrawable();
+            boolean hasTint = (view.getImageTintList() != null)
+                    && (view.getImageTintMode() != null);
+            if ((imageViewDrawable != null) && hasTint) {
+                if (imageViewDrawable.isStateful()) {
+                    imageViewDrawable.setState(view.getDrawableState());
+                }
+                view.setImageDrawable(imageViewDrawable);
+            }
+        }
+    }
+}
diff --git a/compat/gingerbread/android/support/v4/view/TintableBackgroundView.java b/compat/gingerbread/android/support/v4/view/TintableBackgroundView.java
index 83c014b..9a22d7e 100644
--- a/compat/gingerbread/android/support/v4/view/TintableBackgroundView.java
+++ b/compat/gingerbread/android/support/v4/view/TintableBackgroundView.java
@@ -22,7 +22,7 @@
 
 /**
  * Interface which allows a {@link android.view.View} to receive background tinting calls from
- * {@code ViewCompat} when running on API v20 devices or lower.
+ * {@link ViewCompat} when running on API v20 devices or lower.
  */
 public interface TintableBackgroundView {
 
diff --git a/compat/gingerbread/android/support/v4/widget/ImageViewCompatBase.java b/compat/gingerbread/android/support/v4/widget/ImageViewCompatBase.java
new file mode 100644
index 0000000..1963340
--- /dev/null
+++ b/compat/gingerbread/android/support/v4/widget/ImageViewCompatBase.java
@@ -0,0 +1,47 @@
+/*
+ * 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.widget;
+
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.widget.ImageView;
+
+class ImageViewCompatBase {
+    static ColorStateList getImageTintList(ImageView view) {
+        return (view instanceof TintableImageSourceView)
+                ? ((TintableImageSourceView) view).getSupportImageTintList()
+                : null;
+    }
+
+    static void setImageTintList(ImageView view, ColorStateList tintList) {
+        if (view instanceof TintableImageSourceView) {
+            ((TintableImageSourceView) view).setSupportImageTintList(tintList);
+        }
+    }
+
+    static PorterDuff.Mode getImageTintMode(ImageView view) {
+        return (view instanceof TintableImageSourceView)
+                ? ((TintableImageSourceView) view).getSupportImageTintMode()
+                : null;
+    }
+
+    static void setImageTintMode(ImageView view, PorterDuff.Mode mode) {
+        if (view instanceof TintableImageSourceView) {
+            ((TintableImageSourceView) view).setSupportImageTintMode(mode);
+        }
+    }
+}
diff --git a/compat/gingerbread/android/support/v4/widget/TintableImageSourceView.java b/compat/gingerbread/android/support/v4/widget/TintableImageSourceView.java
new file mode 100644
index 0000000..0c3d436
--- /dev/null
+++ b/compat/gingerbread/android/support/v4/widget/TintableImageSourceView.java
@@ -0,0 +1,75 @@
+/*
+ * 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.widget;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
+
+/**
+ * Interface which allows an {@link android.widget.ImageView} to receive image tinting calls
+ * from {@link ImageViewCompat} when running on API v20 devices or lower.
+ *
+ * @hide Internal use only
+ */
+@RestrictTo(LIBRARY_GROUP)
+public interface TintableImageSourceView {
+
+    /**
+     * Applies a tint to the image drawable. Does not modify the current tint
+     * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
+     * <p>
+     * Subsequent calls to the source's image will automatically
+     * mutate the drawable and apply the specified tint and tint mode.
+     *
+     * @param tint the tint to apply, may be {@code null} to clear tint
+     *
+     * @see #getSupportImageTintList()
+     */
+    void setSupportImageTintList(@Nullable ColorStateList tint);
+
+    /**
+     * Return the tint applied to the image drawable, if specified.
+     *
+     * @return the tint applied to the image drawable
+     */
+    @Nullable
+    ColorStateList getSupportImageTintList();
+
+    /**
+     * Specifies the blending mode used to apply the tint specified by
+     * {@link #setSupportImageTintList(ColorStateList)}} to the image
+     * drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
+     *
+     * @param tintMode the blending mode used to apply the tint, may be
+     *                 {@code null} to clear tint
+     * @see #getSupportImageTintMode()
+     */
+    void setSupportImageTintMode(@Nullable PorterDuff.Mode tintMode);
+
+    /**
+     * Return the blending mode used to apply the tint to the image
+     * drawable, if specified.
+     *
+     * @return the blending mode used to apply the tint to the image drawable
+     */
+    @Nullable
+    PorterDuff.Mode getSupportImageTintMode();
+}
diff --git a/compat/java/android/support/v4/content/IntentCompat.java b/compat/java/android/support/v4/content/IntentCompat.java
index 179824e..2ea0a10 100644
--- a/compat/java/android/support/v4/content/IntentCompat.java
+++ b/compat/java/android/support/v4/content/IntentCompat.java
@@ -174,6 +174,13 @@
     public static final String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
 
     /**
+     * Used as a boolean extra field in {@link android.content.Intent#ACTION_VIEW} intents to
+     * indicate that content should immediately be played without any intermediate screens that
+     * require additional user input, e.g. a profile selection screen or a details page.
+     */
+    public static final String EXTRA_START_PLAYBACK = "android.intent.extra.START_PLAYBACK";
+
+    /**
      * Indicates an activity optimized for Leanback mode, and that should
      * be displayed in the Leanback launcher.
      */
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/java/android/support/v4/view/ViewCompat.java
index 15ee7744..bacd900 100644
--- a/compat/java/android/support/v4/view/ViewCompat.java
+++ b/compat/java/android/support/v4/view/ViewCompat.java
@@ -3130,7 +3130,7 @@
      * Applies a tint to the background drawable.
      * <p>
      * This will always take effect when running on API v21 or newer. When running on platforms
-     * previous to API v21, it will only take effect if {@code view} implement the
+     * previous to API v21, it will only take effect if {@code view} implements the
      * {@code TintableBackgroundView} interface.
      */
     public static void setBackgroundTintList(View view, ColorStateList tintList) {
@@ -3160,6 +3160,7 @@
     public static void setBackgroundTintMode(View view, PorterDuff.Mode mode) {
         IMPL.setBackgroundTintMode(view, mode);
     }
+
     // TODO: getters for various view properties (rotation, etc)
 
     /**
diff --git a/compat/java/android/support/v4/widget/ImageViewCompat.java b/compat/java/android/support/v4/widget/ImageViewCompat.java
new file mode 100644
index 0000000..3c0b357
--- /dev/null
+++ b/compat/java/android/support/v4/widget/ImageViewCompat.java
@@ -0,0 +1,122 @@
+/*
+ * 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.widget;
+
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
+import android.widget.ImageView;
+
+/**
+ * Helper for accessing features in {@link ImageView} introduced in later platform releases
+ * in a backwards compatible fashion.
+ */
+public class ImageViewCompat {
+    interface ImageViewCompatImpl {
+        ColorStateList getImageTintList(ImageView view);
+
+        void setImageTintList(ImageView view, ColorStateList tintList);
+
+        PorterDuff.Mode getImageTintMode(ImageView view);
+
+        void setImageTintMode(ImageView view, PorterDuff.Mode mode);
+    }
+
+    static class BaseViewCompatImpl implements ImageViewCompatImpl {
+        @Override
+        public ColorStateList getImageTintList(ImageView view) {
+            return ImageViewCompatBase.getImageTintList(view);
+        }
+
+        @Override
+        public void setImageTintList(ImageView view, ColorStateList tintList) {
+            ImageViewCompatBase.setImageTintList(view, tintList);
+        }
+
+        @Override
+        public void setImageTintMode(ImageView view, PorterDuff.Mode mode) {
+            ImageViewCompatBase.setImageTintMode(view, mode);
+        }
+
+        @Override
+        public PorterDuff.Mode getImageTintMode(ImageView view) {
+            return ImageViewCompatBase.getImageTintMode(view);
+        }
+    }
+
+    static class LollipopViewCompatImpl extends BaseViewCompatImpl {
+        @Override
+        public ColorStateList getImageTintList(ImageView view) {
+            return ImageViewCompatLollipop.getImageTintList(view);
+        }
+
+        @Override
+        public void setImageTintList(ImageView view, ColorStateList tintList) {
+            ImageViewCompatLollipop.setImageTintList(view, tintList);
+        }
+
+        @Override
+        public void setImageTintMode(ImageView view, PorterDuff.Mode mode) {
+            ImageViewCompatLollipop.setImageTintMode(view, mode);
+        }
+
+        @Override
+        public PorterDuff.Mode getImageTintMode(ImageView view) {
+            return ImageViewCompatLollipop.getImageTintMode(view);
+        }
+    }
+
+    static final ImageViewCompatImpl IMPL;
+    static {
+        if (android.os.Build.VERSION.SDK_INT >= 21) {
+            IMPL = new LollipopViewCompatImpl();
+        } else {
+            IMPL = new BaseViewCompatImpl();
+        }
+    }
+
+    /**
+     * Return the tint applied to the image drawable, if specified.
+     */
+    public static ColorStateList getImageTintList(ImageView view) {
+        return IMPL.getImageTintList(view);
+    }
+
+    /**
+     * Applies a tint to the image drawable.
+     */
+    public static void setImageTintList(ImageView view, ColorStateList tintList) {
+        IMPL.setImageTintList(view, tintList);
+    }
+
+    /**
+     * Return the blending mode used to apply the tint to the image drawable, if specified.
+     */
+    public static PorterDuff.Mode getImageTintMode(ImageView view) {
+        return IMPL.getImageTintMode(view);
+    }
+
+    /**
+     * Specifies the blending mode used to apply the tint specified by
+     * {@link #setImageTintList(android.widget.ImageView, android.content.res.ColorStateList)}
+     * to the image drawable. The default mode is {@link PorterDuff.Mode#SRC_IN}.
+     */
+    public static void setImageTintMode(ImageView view, PorterDuff.Mode mode) {
+        IMPL.setImageTintMode(view, mode);
+    }
+
+    private ImageViewCompat() {}
+}
diff --git a/core-ui/AndroidManifest.xml b/core-ui/AndroidManifest.xml
index 5357112..646626e 100644
--- a/core-ui/AndroidManifest.xml
+++ b/core-ui/AndroidManifest.xml
@@ -17,6 +17,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.coreui">
     <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreui"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java b/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
index 4c99341..92af2de 100644
--- a/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
+++ b/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
@@ -38,9 +38,6 @@
 import android.view.View;
 
 /**
- * @deprecated Please use ActionBarDrawerToggle in support-v7-appcompat.
- *
- * <p>
  * This class provides a handy way to tie together the functionality of
  * {@link DrawerLayout} and the framework <code>ActionBar</code> to implement the recommended
  * design for navigation drawers.
@@ -69,7 +66,10 @@
     /**
      * Allows an implementing Activity to return an {@link ActionBarDrawerToggle.Delegate} to use
      * with ActionBarDrawerToggle.
+     *
+     * @deprecated Use ActionBarDrawerToggle.DelegateProvider in support-v7-appcompat.
      */
+    @Deprecated
     public interface DelegateProvider {
 
         /**
@@ -80,6 +80,10 @@
         Delegate getDrawerToggleDelegate();
     }
 
+    /**
+     * @deprecated Use ActionBarDrawerToggle.DelegateProvider in support-v7-appcompat.
+     */
+    @Deprecated
     public interface Delegate {
         /**
          * @return Up indicator drawable as defined in the Activity's theme, or null if one is not
diff --git a/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java b/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
index 526575c..d30b0cf 100644
--- a/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
+++ b/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
@@ -49,8 +49,7 @@
  * support in custom {@link View}s that represent a collection of View-like
  * logical items. It extends {@link AccessibilityNodeProviderCompat} and
  * simplifies many aspects of providing information to accessibility services
- * and managing accessibility focus. This class does not currently support
- * hierarchies of logical items.
+ * and managing accessibility focus.
  * <p>
  * Clients should override abstract methods on this class and attach it to the
  * host view using {@link ViewCompat#setAccessibilityDelegate}:
diff --git a/core-utils/AndroidManifest.xml b/core-utils/AndroidManifest.xml
index 03ff3b4..6e730b9 100644
--- a/core-utils/AndroidManifest.xml
+++ b/core-utils/AndroidManifest.xml
@@ -17,6 +17,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.coreutils">
     <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.coreutils"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/core-utils/java/android/support/v4/content/AsyncTaskLoader.java b/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
index c31a8cd..faa13ad 100644
--- a/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
+++ b/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
@@ -157,6 +157,9 @@
     protected boolean onCancelLoad() {
         if (DEBUG) Log.v(TAG, "onCancelLoad: mTask=" + mTask);
         if (mTask != null) {
+            if (!mStarted) {
+                mContentChanged = true;
+            }
             if (mCancellingTask != null) {
                 // There was a pending task already waiting for a previous
                 // one being canceled; just drop it.
diff --git a/customtabs/AndroidManifest.xml b/customtabs/AndroidManifest.xml
index 19a1d54..4069dae 100644
--- a/customtabs/AndroidManifest.xml
+++ b/customtabs/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.customtabs">
     <uses-sdk android:minSdkVersion="15"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/customtabs/build.gradle b/customtabs/build.gradle
index bfbeb1a..a2ad274 100644
--- a/customtabs/build.gradle
+++ b/customtabs/build.gradle
@@ -55,3 +55,37 @@
 
     artifacts.add('archives', sourcesJarTask);
 }
+
+uploadArchives {
+    repositories {
+        mavenDeployer {
+            repository(url: uri(rootProject.ext.supportRepoOut)) {
+            }
+
+            pom.project {
+                name 'Android Support Custom Tabs'
+                description "Android Support Custom Tabs"
+                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'
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/design/AndroidManifest.xml b/design/AndroidManifest.xml
index 2d5fe0b..81924cb 100644
--- a/design/AndroidManifest.xml
+++ b/design/AndroidManifest.xml
@@ -18,6 +18,7 @@
           package="android.support.design">
     <uses-sdk android:minSdkVersion="9"
               tools:overrideLibrary="android.support.transition"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/design/res/layout/design_bottom_sheet_dialog.xml b/design/res/layout/design_bottom_sheet_dialog.xml
index c99caa6..29212ed 100644
--- a/design/res/layout/design_bottom_sheet_dialog.xml
+++ b/design/res/layout/design_bottom_sheet_dialog.xml
@@ -14,26 +14,38 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
 -->
-<android.support.design.widget.CoordinatorLayout
-        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">
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/container"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:fitsSystemWindows="true">
 
-    <View
+    <android.support.design.widget.CoordinatorLayout
+        android:id="@+id/coordinator"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:fitsSystemWindows="true">
+
+        <View
             android:id="@+id/touch_outside"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:importantForAccessibility="no"
-            android:soundEffectsEnabled="false"/>
+            android:soundEffectsEnabled="false"
+            tools:ignore="UnusedAttribute"/>
 
-    <FrameLayout
+        <FrameLayout
             android:id="@+id/design_bottom_sheet"
+            style="?attr/bottomSheetStyle"
             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"/>
+            app:layout_behavior="@string/bottom_sheet_behavior"/>
 
-</android.support.design.widget.CoordinatorLayout>
+    </android.support.design.widget.CoordinatorLayout>
+
+</FrameLayout>
diff --git a/design/src/android/support/design/internal/BottomNavigationMenuView.java b/design/src/android/support/design/internal/BottomNavigationMenuView.java
index 5d7c19d..316d271 100644
--- a/design/src/android/support/design/internal/BottomNavigationMenuView.java
+++ b/design/src/android/support/design/internal/BottomNavigationMenuView.java
@@ -290,19 +290,25 @@
             return;
         }
         int previousSelectedId = mSelectedItemId;
+
         for (int i = 0; i < menuSize; i++) {
-            mPresenter.setUpdateSuspended(true);
             MenuItem item = mMenu.getItem(i);
             if (item.isChecked()) {
                 mSelectedItemId = item.getItemId();
                 mSelectedItemPosition = i;
             }
-            mButtons[i].initialize((MenuItemImpl) item, 0);
-            mPresenter.setUpdateSuspended(false);
         }
         if (previousSelectedId != mSelectedItemId) {
+            // Note: this has to be called before BottomNavigationItemView#initialize().
             mAnimationHelper.beginDelayedTransition(this);
         }
+
+        for (int i = 0; i < menuSize; i++) {
+            mPresenter.setUpdateSuspended(true);
+            mButtons[i].initialize((MenuItemImpl) mMenu.getItem(i), 0);
+            mPresenter.setUpdateSuspended(false);
+        }
+
     }
 
     private BottomNavigationItemView getNewItem() {
diff --git a/design/src/android/support/design/widget/AppBarLayout.java b/design/src/android/support/design/widget/AppBarLayout.java
index ff41db8..6215057 100644
--- a/design/src/android/support/design/widget/AppBarLayout.java
+++ b/design/src/android/support/design/widget/AppBarLayout.java
@@ -146,7 +146,7 @@
     private boolean mCollapsible;
     private boolean mCollapsed;
 
-    private final int[] mTmpStatesArray = new int[2];
+    private int[] mTmpStatesArray;
 
     public AppBarLayout(Context context) {
         this(context, null);
@@ -500,6 +500,12 @@
 
     @Override
     protected int[] onCreateDrawableState(int extraSpace) {
+        if (mTmpStatesArray == null) {
+            // Note that we can't allocate this at the class level (in declaration) since
+            // some paths in super View constructor are going to call this method before
+            // that
+            mTmpStatesArray = new int[2];
+        }
         final int[] extraStates = mTmpStatesArray;
         final int[] states = super.onCreateDrawableState(extraSpace + extraStates.length);
 
diff --git a/design/src/android/support/design/widget/BottomSheetDialog.java b/design/src/android/support/design/widget/BottomSheetDialog.java
index c5fccb0..ca89b20 100644
--- a/design/src/android/support/design/widget/BottomSheetDialog.java
+++ b/design/src/android/support/design/widget/BottomSheetDialog.java
@@ -32,6 +32,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
+import android.view.WindowManager;
 import android.widget.FrameLayout;
 
 /**
@@ -71,8 +72,15 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        getWindow().setLayout(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        Window window = getWindow();
+        if (window != null) {
+            if (Build.VERSION.SDK_INT >= 21) {
+                window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
+                window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+            }
+            window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
+                    ViewGroup.LayoutParams.MATCH_PARENT);
+        }
     }
 
     @Override
@@ -115,8 +123,10 @@
     }
 
     private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {
-        final CoordinatorLayout coordinator = (CoordinatorLayout) View.inflate(getContext(),
+        final FrameLayout container = (FrameLayout) View.inflate(getContext(),
                 R.layout.design_bottom_sheet_dialog, null);
+        final CoordinatorLayout coordinator =
+                (CoordinatorLayout) container.findViewById(R.id.coordinator);
         if (layoutResId != 0 && view == null) {
             view = getLayoutInflater().inflate(layoutResId, coordinator, false);
         }
@@ -161,7 +171,7 @@
                 return super.performAccessibilityAction(host, action, args);
             }
         });
-        return coordinator;
+        return container;
     }
 
     boolean shouldWindowCloseOnTouchOutside() {
diff --git a/design/src/android/support/design/widget/ThemeUtils.java b/design/src/android/support/design/widget/ThemeUtils.java
index ffdc3f4..821dcb6 100644
--- a/design/src/android/support/design/widget/ThemeUtils.java
+++ b/design/src/android/support/design/widget/ThemeUtils.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
-import android.support.design.R;
 
 class ThemeUtils {
 
@@ -29,9 +28,7 @@
     static void checkAppCompatTheme(Context context) {
         TypedArray a = context.obtainStyledAttributes(APPCOMPAT_CHECK_ATTRS);
         final boolean failed = !a.hasValue(0);
-        if (a != null) {
-            a.recycle();
-        }
+        a.recycle();
         if (failed) {
             throw new IllegalArgumentException("You need to use a Theme.AppCompat theme "
                     + "(or descendant) with the design library.");
diff --git a/design/tests/AndroidManifest.xml b/design/tests/AndroidManifest.xml
index 886540d..6122490 100755
--- a/design/tests/AndroidManifest.xml
+++ b/design/tests/AndroidManifest.xml
@@ -92,6 +92,10 @@
             android:name="android.support.design.widget.AppBarLayoutCollapsePinTestActivity"
             android:theme="@style/Theme.TranslucentStatus"/>
 
+        <activity
+            android:name="android.support.design.widget.AppBarWithScrollbarsActivity"
+            android:theme="@style/Theme.AppCompat.Light.DarkActionBar"/>
+
     </application>
 
     <instrumentation
diff --git a/design/tests/res/layout/design_appbar_with_scrollbars.xml b/design/tests/res/layout/design_appbar_with_scrollbars.xml
new file mode 100644
index 0000000..6c89a2a
--- /dev/null
+++ b/design/tests/res/layout/design_appbar_with_scrollbars.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+
+<android.support.design.widget.AppBarLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="200dp"
+    android:theme="@style/AppBarWithScrollbars"/>
\ No newline at end of file
diff --git a/design/tests/res/values/styles.xml b/design/tests/res/values/styles.xml
index 8f0af0c..eb6aee6 100644
--- a/design/tests/res/values/styles.xml
+++ b/design/tests/res/values/styles.xml
@@ -36,4 +36,7 @@
         <item name="android:textColor">@color/color_state_list_themed</item>
     </style>
 
+    <style name="AppBarWithScrollbars" parent="ThemeOverlay.AppCompat.Dark.ActionBar">
+        <item name="android:scrollbars">horizontal</item>
+    </style>
 </resources>
\ No newline at end of file
diff --git a/design/tests/src/android/support/design/widget/AppBarWithScrollbarsActivity.java b/design/tests/src/android/support/design/widget/AppBarWithScrollbarsActivity.java
new file mode 100644
index 0000000..bd693d4
--- /dev/null
+++ b/design/tests/src/android/support/design/widget/AppBarWithScrollbarsActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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.design.widget;
+
+import android.support.design.test.R;
+
+public class AppBarWithScrollbarsActivity extends BaseTestActivity {
+    @Override
+    protected int getContentViewLayoutResId() {
+        return R.layout.design_appbar_with_scrollbars;
+    }
+}
diff --git a/design/tests/src/android/support/design/widget/AppBarWithScrollbarsTest.java b/design/tests/src/android/support/design/widget/AppBarWithScrollbarsTest.java
new file mode 100644
index 0000000..f6fe8bfb
--- /dev/null
+++ b/design/tests/src/android/support/design/widget/AppBarWithScrollbarsTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.design.widget;
+
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+
+public class AppBarWithScrollbarsTest extends
+        BaseInstrumentationTestCase<AppBarWithScrollbarsActivity> {
+
+    public AppBarWithScrollbarsTest() {
+        super(AppBarWithScrollbarsActivity.class);
+    }
+
+    @Test
+    @SmallTest
+    public void testInflationNoCrash() {
+        // This is the implicit test for to check that AppBarLayout inflation doesn't crash
+        // when its theme has attributes that would cause onCreateDrawableState to be called
+        // during the super's constructor flow.
+    }
+}
diff --git a/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java b/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
index d57bfe9..24d8eee 100644
--- a/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
+++ b/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
@@ -54,7 +54,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.widget.TextView;
 
 import org.hamcrest.Matcher;
 import org.hamcrest.Matchers;
@@ -512,18 +511,9 @@
             public void run() {
                 bottomSheet.addView(scroll, new ViewGroup.LayoutParams(
                         ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
-                TextView view = new TextView(mActivityTestRule.getActivity());
-                StringBuilder sb = new StringBuilder();
-                for (int i = 0; i < 500; ++i) {
-                    sb.append("It is fine today. ");
-                }
-                view.setText(sb);
-                view.setOnClickListener(new View.OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        // Do nothing
-                    }
-                });
+                final View view = new View(mActivityTestRule.getActivity());
+                // Make sure that the NestedScrollView is always scrollable
+                view.setMinimumHeight(bottomSheet.getHeight() + 1000);
                 scroll.addView(view);
                 assertThat(behavior.getState(), is(BottomSheetBehavior.STATE_COLLAPSED));
                 // The scroll offset is 0 at first
diff --git a/dynamic-animation/Android.mk b/dynamic-animation/Android.mk
new file mode 100644
index 0000000..b8ba1395
--- /dev/null
+++ b/dynamic-animation/Android.mk
@@ -0,0 +1,30 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_MODULE := android-support-dynamic-animation
+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-annotations
+LOCAL_JAR_EXCLUDE_FILES := none
+LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/dynamic-animation/AndroidManifest-make.xml
similarity index 70%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to dynamic-animation/AndroidManifest-make.xml
index 36c297f..bfe97cc 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/dynamic-animation/AndroidManifest-make.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
@@ -14,9 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.support.dynamicanimation">
+    <uses-sdk android:minSdkVersion="16"/>
+</manifest>
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/dynamic-animation/AndroidManifest.xml
similarity index 62%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to dynamic-animation/AndroidManifest.xml
index 36c297f..f818402 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/dynamic-animation/AndroidManifest.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
@@ -14,9 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="android.support.dynamicanimation">
+    <uses-sdk android:minSdkVersion="16"/>
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
+</manifest>
diff --git a/dynamic-animation/build.gradle b/dynamic-animation/build.gradle
new file mode 100644
index 0000000..907fff8
--- /dev/null
+++ b/dynamic-animation/build.gradle
@@ -0,0 +1,110 @@
+apply plugin: 'com.android.library'
+archivesBaseName = 'support-dynamic-animation'
+
+dependencies {
+    compile project(':support-core-utils')
+    androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+        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'
+    testCompile "org.mockito:mockito-core:1.9.5"
+
+    testCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
+        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 16
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+    }
+
+    sourceSets {
+        main.manifest.srcFile 'AndroidManifest.xml'
+        main.java.srcDir '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
+    }
+
+    lintOptions {
+        // TODO: fix errors and reenable.
+        abortOnError false
+    }
+
+    packagingOptions {
+        exclude 'LICENSE.txt'
+    }
+
+    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
+    }
+
+    artifacts.add('archives', sourcesJarTask);
+}
+
+uploadArchives {
+    repositories {
+        mavenDeployer {
+            repository(url: uri(rootProject.ext.supportRepoOut)) {
+            }
+
+            pom.project {
+                name 'Android Support DynamicAnimation v16'
+                description "Physics-based animation in support library, where the animations are driven by physics force. You can use this Animation library to create smooth and realistic animations."
+                url 'http://developer.android.com/tools/extras/support-library.html'
+                inceptionYear '2017'
+
+                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/dynamic-animation/src/android/support/animation/AnimationHandler.java b/dynamic-animation/src/android/support/animation/AnimationHandler.java
new file mode 100644
index 0000000..fac9cd2
--- /dev/null
+++ b/dynamic-animation/src/android/support/animation/AnimationHandler.java
@@ -0,0 +1,202 @@
+/*
+ * 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.animation;
+
+import android.os.SystemClock;
+import android.support.v4.util.SimpleArrayMap;
+import android.view.Choreographer;
+
+import java.util.ArrayList;
+
+/**
+ * This custom, static handler handles the timing pulse that is shared by all active
+ * ValueAnimators. This approach ensures that the setting of animation values will happen on the
+ * same thread that animations start on, and that all animations will share the same times for
+ * calculating their values, which makes synchronizing animations possible.
+ *
+ * The handler uses the Choreographer by default for doing periodic callbacks. A custom
+ * AnimationFrameCallbackProvider can be set on the handler to provide timing pulse that
+ * may be independent of UI frame update. This could be useful in testing.
+ *
+ * @hide
+ */
+class AnimationHandler {
+    /**
+     * Callbacks that receives notifications for animation timing
+     */
+    interface AnimationFrameCallback {
+        /**
+         * Run animation based on the frame time.
+         * @param frameTime The frame start time
+         */
+        boolean doAnimationFrame(long frameTime);
+    }
+
+    /**
+     * Internal per-thread collections used to avoid set collisions as animations start and end
+     * while being processed.
+     * @hide
+     */
+    private final SimpleArrayMap<AnimationFrameCallback, Long> mDelayedCallbackStartTime =
+            new SimpleArrayMap<>();
+    public static final ThreadLocal<AnimationHandler> sAnimatorHandler = new ThreadLocal<>();
+    private final ArrayList<AnimationFrameCallback> mAnimationCallbacks = new ArrayList<>();
+    private AnimationFrameCallbackProvider mProvider;
+
+    private long mCurrentFrameTime = 0;
+    private final Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {
+        @Override
+        public void doFrame(long frameTimeNanos) {
+            mCurrentFrameTime = System.currentTimeMillis();
+            doAnimationFrame(mCurrentFrameTime);
+            if (mAnimationCallbacks.size() > 0) {
+                getProvider().postFrameCallback(this);
+            }
+        }
+    };
+
+    private boolean mListDirty = false;
+
+    public static AnimationHandler getInstance() {
+        if (sAnimatorHandler.get() == null) {
+            sAnimatorHandler.set(new AnimationHandler());
+        }
+        return sAnimatorHandler.get();
+    }
+
+    public static long getFrameTime() {
+        if (sAnimatorHandler.get() == null) {
+            return 0;
+        }
+        return sAnimatorHandler.get().mCurrentFrameTime;
+    }
+
+    /**
+     * By default, the Choreographer is used to provide timing for frame callbacks. A custom
+     * provider can be used here to provide different timing pulse.
+     */
+    public void setProvider(AnimationFrameCallbackProvider provider) {
+        if (provider == null) {
+            mProvider = new MyFrameCallbackProvider();
+        } else {
+            mProvider = provider;
+        }
+    }
+
+    private AnimationFrameCallbackProvider getProvider() {
+        if (mProvider == null) {
+            mProvider = new MyFrameCallbackProvider();
+        }
+        return mProvider;
+    }
+
+    /**
+     * Register to get a callback on the next frame after the delay.
+     */
+    public void addAnimationFrameCallback(final AnimationFrameCallback callback, long delay) {
+        if (mAnimationCallbacks.size() == 0) {
+            getProvider().postFrameCallback(mFrameCallback);
+        }
+        if (!mAnimationCallbacks.contains(callback)) {
+            mAnimationCallbacks.add(callback);
+        }
+
+        if (delay > 0) {
+            mDelayedCallbackStartTime.put(callback, (SystemClock.uptimeMillis() + delay));
+        }
+    }
+    /**
+     * Removes the given callback from the list, so it will no longer be called for frame related
+     * timing.
+     */
+    public void removeCallback(AnimationFrameCallback callback) {
+        mDelayedCallbackStartTime.remove(callback);
+        int id = mAnimationCallbacks.indexOf(callback);
+        if (id >= 0) {
+            mAnimationCallbacks.set(id, null);
+            mListDirty = true;
+        }
+    }
+
+    private void doAnimationFrame(long frameTime) {
+        long currentTime = SystemClock.uptimeMillis();
+        for (int i = 0; i < mAnimationCallbacks.size(); i++) {
+            final AnimationFrameCallback callback = mAnimationCallbacks.get(i);
+            if (callback == null) {
+                continue;
+            }
+            if (isCallbackDue(callback, currentTime)) {
+                callback.doAnimationFrame(frameTime);
+            }
+        }
+        cleanUpList();
+    }
+
+    /**
+     * Remove the callbacks from mDelayedCallbackStartTime once they have passed the initial delay
+     * so that they can start getting frame callbacks.
+     *
+     * @return true if they have passed the initial delay or have no delay, false otherwise.
+     */
+    private boolean isCallbackDue(AnimationFrameCallback callback, long currentTime) {
+        Long startTime = mDelayedCallbackStartTime.get(callback);
+        if (startTime == null) {
+            return true;
+        }
+        if (startTime < currentTime) {
+            mDelayedCallbackStartTime.remove(callback);
+            return true;
+        }
+        return false;
+    }
+
+    private void cleanUpList() {
+        if (mListDirty) {
+            for (int i = mAnimationCallbacks.size() - 1; i >= 0; i--) {
+                if (mAnimationCallbacks.get(i) == null) {
+                    mAnimationCallbacks.remove(i);
+                }
+            }
+            mListDirty = false;
+        }
+    }
+
+    /**
+     * Default provider of timing pulse that uses Choreographer for frame callbacks.
+     */
+    private class MyFrameCallbackProvider implements AnimationFrameCallbackProvider {
+
+        final Choreographer mChoreographer = Choreographer.getInstance();
+
+        @Override
+        public void postFrameCallback(Choreographer.FrameCallback callback) {
+            mChoreographer.postFrameCallback(callback);
+        }
+    }
+
+    /**
+     * The intention for having this interface is to increase the testability of ValueAnimator.
+     * Specifically, we can have a custom implementation of the interface below and provide
+     * timing pulse without using Choreographer. That way we could use any arbitrary interval for
+     * our timing pulse in the tests.
+     *
+     * @hide
+     */
+    public interface AnimationFrameCallbackProvider {
+        void postFrameCallback(Choreographer.FrameCallback callback);
+    }
+}
diff --git a/dynamic-animation/src/android/support/animation/DynamicAnimation.java b/dynamic-animation/src/android/support/animation/DynamicAnimation.java
new file mode 100644
index 0000000..2895d80
--- /dev/null
+++ b/dynamic-animation/src/android/support/animation/DynamicAnimation.java
@@ -0,0 +1,778 @@
+/*
+ * 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.animation;
+
+import android.os.Build;
+import android.os.Looper;
+import android.support.annotation.FloatRange;
+import android.util.AndroidRuntimeException;
+import android.view.View;
+
+import java.util.ArrayList;
+
+/**
+ * This class is the base class of physics-based animations. It manages the animation's
+ * lifecycle such as {@link #start()} and {@link #cancel()}. This base class also handles the common
+ * setup for all the subclass animations. For example, DynamicAnimation supports adding
+ * {@link OnAnimationEndListener} and {@link OnAnimationUpdateListener} so that the important
+ * animation events can be observed through the callbacks. The start conditions for any subclass of
+ * DynamicAnimation can be set using {@link #setStartValue(float)} and
+ * {@link #setStartVelocity(float)}.
+ *
+ * @param <T> subclass of DynamicAnimation
+ */
+public abstract class DynamicAnimation<T extends DynamicAnimation<T>>
+        implements AnimationHandler.AnimationFrameCallback {
+
+    /**
+     * ViewProperty holds the access of a property of a {@link View}. When an animation is
+     * created with a {@link ViewProperty} instance, the corresponding property value of the view
+     * will be updated through this ViewProperty instance.
+     */
+    public abstract static class ViewProperty extends FloatPropertyCompat<View> {
+        private ViewProperty(String name) {
+            super(name);
+        }
+    }
+
+    /**
+     * View's translationX property.
+     */
+    public static final ViewProperty TRANSLATION_X = new ViewProperty("translationX") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setTranslationX(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getTranslationX();
+        }
+    };
+
+    /**
+     * View's translationY property.
+     */
+    public static final ViewProperty TRANSLATION_Y = new ViewProperty("translationY") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setTranslationY(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getTranslationY();
+        }
+    };
+
+    /**
+     * View's translationZ property.
+     */
+    public static final ViewProperty TRANSLATION_Z = new ViewProperty("translationZ") {
+        @Override
+        public void setValue(View view, float value) {
+            if (isZSupported()) {
+                view.setTranslationZ(value);
+            }
+        }
+
+        @Override
+        public float getValue(View view) {
+            if (isZSupported()) {
+                return view.getTranslationZ();
+            } else {
+                return 0;
+            }
+        }
+    };
+
+    /**
+     * View's scaleX property.
+     */
+    public static final ViewProperty SCALE_X = new ViewProperty("scaleX") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setScaleX(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getScaleX();
+        }
+    };
+
+    /**
+     * View's scaleY property.
+     */
+    public static final ViewProperty SCALE_Y = new ViewProperty("scaleY") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setScaleY(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getScaleY();
+        }
+    };
+
+    /**
+     * View's rotation property.
+     */
+    public static final ViewProperty ROTATION = new ViewProperty("rotation") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setRotation(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getRotation();
+        }
+    };
+
+    /**
+     * View's rotationX property.
+     */
+    public static final ViewProperty ROTATION_X = new ViewProperty("rotationX") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setRotationX(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getRotationX();
+        }
+    };
+
+    /**
+     * View's rotationY property.
+     */
+    public static final ViewProperty ROTATION_Y = new ViewProperty("rotationY") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setRotationY(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getRotationY();
+        }
+    };
+
+    /**
+     * View's x property.
+     */
+    public static final ViewProperty X = new ViewProperty("x") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setX(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getX();
+        }
+    };
+
+    /**
+     * View's y property.
+     */
+    public static final ViewProperty Y = new ViewProperty("y") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setY(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getY();
+        }
+    };
+
+    /**
+     * View's z property.
+     */
+    public static final ViewProperty Z = new ViewProperty("z") {
+        @Override
+        public void setValue(View view, float value) {
+            if (isZSupported()) {
+                view.setZ(value);
+            }
+        }
+
+        @Override
+        public float getValue(View view) {
+            if (isZSupported()) {
+                return view.getZ();
+            } else {
+                return 0;
+            }
+        }
+    };
+
+    /**
+     * View's alpha property.
+     */
+    public static final ViewProperty ALPHA = new ViewProperty("alpha") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setAlpha(value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getAlpha();
+        }
+    };
+
+    // Properties below are not RenderThread compatible
+    /**
+     * View's scrollX property.
+     */
+    public static final ViewProperty SCROLL_X = new ViewProperty("scrollX") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setScrollX((int) value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getScrollX();
+        }
+    };
+
+    /**
+     * View's scrollY property.
+     */
+    public static final ViewProperty SCROLL_Y = new ViewProperty("scrollY") {
+        @Override
+        public void setValue(View view, float value) {
+            view.setScrollY((int) value);
+        }
+
+        @Override
+        public float getValue(View view) {
+            return view.getScrollY();
+        }
+    };
+
+    /**
+     * The minimum visible change in pixels that can be visible to users.
+     */
+    public static final float MIN_VISIBLE_CHANGE_PIXELS = 1f;
+    /**
+     * The minimum visible change in degrees that can be visible to users.
+     */
+    public static final float MIN_VISIBLE_CHANGE_ROTATION_DEGREES = 1f / 10f;
+    /**
+     * The minimum visible change in alpha that can be visible to users.
+     */
+    public static final float MIN_VISIBLE_CHANGE_ALPHA = 1f / 256f;
+    /**
+     * The minimum visible change in scale that can be visible to users.
+     */
+    public static final float MIN_VISIBLE_CHANGE_SCALE = 1f / 500f;
+
+    // Use the max value of float to indicate an unset state.
+    private static final float UNSET = Float.MAX_VALUE;
+
+    // Multiplier to the min visible change value for value threshold
+    private static final float THRESHOLD_MULTIPLIER = 0.75f;
+
+    // Internal tracking for velocity.
+    float mVelocity = 0;
+
+    // Internal tracking for value.
+    float mValue = UNSET;
+
+    // Tracks whether start value is set. If not, the animation will obtain the value at the time
+    // of starting through the getter and use that as the starting value of the animation.
+    boolean mStartValueIsSet = false;
+
+    // Target to be animated.
+    final Object mTarget;
+
+    // View property id.
+    final FloatPropertyCompat mProperty;
+
+    // Package private tracking of animation lifecycle state. Visible to subclass animations.
+    boolean mRunning = false;
+
+    // Min and max values that defines the range of the animation values.
+    float mMaxValue = Float.MAX_VALUE;
+    float mMinValue = -mMaxValue;
+
+    // Last frame time. Always gets reset to -1  at the end of the animation.
+    private long mLastFrameTime = 0;
+
+    private float mMinVisibleChange;
+
+    // List of end listeners
+    private final ArrayList<OnAnimationEndListener> mEndListeners = new ArrayList<>();
+
+    // List of update listeners
+    private final ArrayList<OnAnimationUpdateListener> mUpdateListeners = new ArrayList<>();
+
+    // Internal state for value/velocity pair.
+    static class MassState {
+        float mValue;
+        float mVelocity;
+    }
+
+    /**
+     * Creates a dynamic animation with the given FloatValueHolder instance.
+     *
+     * @param floatValueHolder the FloatValueHolder instance to be animated.
+     */
+    DynamicAnimation(final FloatValueHolder floatValueHolder) {
+        mTarget = null;
+        mProperty = new FloatPropertyCompat("FloatValueHolder") {
+            @Override
+            public float getValue(Object object) {
+                return floatValueHolder.getValue();
+            }
+
+            @Override
+            public void setValue(Object object, float value) {
+                floatValueHolder.setValue(value);
+            }
+        };
+        mMinVisibleChange = MIN_VISIBLE_CHANGE_PIXELS;
+    }
+
+    /**
+     * Creates a dynamic animation to animate the given property for the given {@link View}
+     *
+     * @param object the Object whose property is to be animated
+     * @param property the property to be animated
+     */
+
+    <K> DynamicAnimation(K object, FloatPropertyCompat<K> property) {
+        mTarget = object;
+        mProperty = property;
+        if (mProperty == ROTATION || mProperty == ROTATION_X
+                || mProperty == ROTATION_Y) {
+            mMinVisibleChange = MIN_VISIBLE_CHANGE_ROTATION_DEGREES;
+        } else if (mProperty == ALPHA) {
+            mMinVisibleChange = MIN_VISIBLE_CHANGE_ALPHA;
+        } else if (mProperty == SCALE_X || mProperty == SCALE_Y) {
+            mMinVisibleChange = MIN_VISIBLE_CHANGE_ALPHA;
+        } else {
+            mMinVisibleChange = MIN_VISIBLE_CHANGE_PIXELS;
+        }
+    }
+
+    /**
+     * Sets the start value of the animation. If start value is not set, the animation will get
+     * the current value for the view's property, and use that as the start value.
+     *
+     * @param startValue start value for the animation
+     * @return the Animation whose start value is being set
+     */
+    public T setStartValue(float startValue) {
+        mValue = startValue;
+        mStartValueIsSet = true;
+        return (T) this;
+    }
+
+    /**
+     * Start velocity of the animation. Default velocity is 0. Unit: pixel/second
+     *
+     * <p>Note when using a fixed value as the start velocity (as opposed to getting the velocity
+     * through touch events), it is recommended to define such a value in dp/second and convert it
+     * to pixel/second based on the density of the screen to achieve a consistent look across
+     * different screens.
+     *
+     * <p>To convert from dp/second to pixel/second:
+     * <pre class="prettyprint">
+     * float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond,
+     *         getResources().getDisplayMetrics());
+     * </pre>
+     *
+     * @param startVelocity start velocity of the animation in pixel/second
+     * @return the Animation whose start velocity is being set
+     */
+    public T setStartVelocity(float startVelocity) {
+        mVelocity = startVelocity;
+        return (T) this;
+    }
+
+    /**
+     * Sets the max value of the animation. Animations will not animate beyond their max value.
+     * Whether or not animation will come to an end when max value is reached is dependent on the
+     * child animation's implementation.
+     *
+     * @param max maximum value of the property to be animated
+     * @return the Animation whose max value is being set
+     */
+    public T setMaxValue(float max) {
+        // This max value should be checked and handled in the subclass animations, instead of
+        // assuming the end of the animations when the max/min value is hit in the base class.
+        // The reason is that hitting max/min value may just be a transient state, such as during
+        // the spring oscillation.
+        mMaxValue = max;
+        return (T) this;
+    }
+
+    /**
+     * Sets the min value of the animation. Animations will not animate beyond their min value.
+     * Whether or not animation will come to an end when min value is reached is dependent on the
+     * child animation's implementation.
+     *
+     * @param min minimum value of the property to be animated
+     * @return the Animation whose min value is being set
+     */
+    public T setMinValue(float min) {
+        mMinValue = min;
+        return (T) this;
+    }
+
+    /**
+     * Adds an end listener to the animation for receiving onAnimationEnd callbacks. If the listener
+     * is {@code null} or has already been added to the list of listeners for the animation, no op.
+     *
+     * @param listener the listener to be added
+     * @return the animation to which the listener is added
+     */
+    public T addEndListener(OnAnimationEndListener listener) {
+        if (!mEndListeners.contains(listener)) {
+            mEndListeners.add(listener);
+        }
+        return (T) this;
+    }
+
+    /**
+     * Removes the end listener from the animation, so as to stop receiving animation end callbacks.
+     *
+     * @param listener the listener to be removed
+     */
+    public void removeEndListener(OnAnimationEndListener listener) {
+        removeEntry(mEndListeners, listener);
+    }
+
+    /**
+     * Adds an update listener to the animation for receiving per-frame animation update callbacks.
+     * If the listener is {@code null} or has already been added to the list of listeners for the
+     * animation, no op.
+     *
+     * <p>Note that update listener should only be added before the start of the animation.
+     *
+     * @param listener the listener to be added
+     * @return the animation to which the listener is added
+     * @throws UnsupportedOperationException if the update listener is added after the animation has
+     *                                       started
+     */
+    public T addUpdateListener(OnAnimationUpdateListener listener) {
+        if (isRunning()) {
+            // Require update listener to be added before the animation, such as when we start
+            // the animation, we know whether the animation is RenderThread compatible.
+            throw new UnsupportedOperationException("Error: Update listeners must be added before"
+                    + "the animation.");
+        }
+        if (!mUpdateListeners.contains(listener)) {
+            mUpdateListeners.add(listener);
+        }
+        return (T) this;
+    }
+
+    /**
+     * Removes the update listener from the animation, so as to stop receiving animation update
+     * callbacks.
+     *
+     * @param listener the listener to be removed
+     */
+    public void removeUpdateListener(OnAnimationUpdateListener listener) {
+        removeEntry(mUpdateListeners, listener);
+    }
+
+
+    /**
+     * This method sets the minimal change of animation value that is visible to users, which helps
+     * determine a reasonable threshold for the animation's termination condition. It is critical
+     * to set the minimal visible change for custom properties (i.e. non-<code>ViewProperty</code>s)
+     * unless the custom property is in pixels.
+     *
+     * <p>For custom properties, this minimum visible change defaults to change in pixel
+     * (i.e. {@link #MIN_VISIBLE_CHANGE_PIXELS}. It is recommended to adjust this value that is
+     * reasonable for the property to be animated. A general rule of thumb to calculate such a value
+     * is: minimum visible change = range of custom property value / corresponding pixel range. For
+     * example, if the property to be animated is a progress (from 0 to 100) that corresponds to a
+     * 200-pixel change. Then the min visible change should be 100 / 200. (i.e. 0.5).
+     *
+     * <p>It's not necessary to call this method when animating {@link ViewProperty}s, as the
+     * minimum visible change will be derived from the property. For example, if the property to be
+     * animated is in pixels (i.e. {@link #TRANSLATION_X}, {@link #TRANSLATION_Y},
+     * {@link #TRANSLATION_Z}, @{@link #SCROLL_X} or {@link #SCROLL_Y}), the default minimum visible
+     * change is 1 (pixel). For {@link #ROTATION}, {@link #ROTATION_X} or {@link #ROTATION_Y}, the
+     * animation will use {@link #MIN_VISIBLE_CHANGE_ROTATION_DEGREES} as the min visible change,
+     * which is 1/10. Similarly, the minimum visible change for alpha (
+     * i.e. {@link #MIN_VISIBLE_CHANGE_ALPHA} is defined as 1 / 256.
+     *
+     * @param minimumVisibleChange minimum change in property value that is visible to users
+     * @return the animation whose min visible change is being set
+     * @throws IllegalArgumentException if the given threshold is not positive
+     */
+    public T setMinimumVisibleChange(@FloatRange(from = 0.0, fromInclusive = false)
+            float minimumVisibleChange) {
+        if (minimumVisibleChange <= 0) {
+            throw new IllegalArgumentException("Minimum visible change must be positive.");
+        }
+        mMinVisibleChange = minimumVisibleChange;
+        setValueThreshold(minimumVisibleChange * THRESHOLD_MULTIPLIER);
+        return (T) this;
+    }
+
+    /**
+     * Returns the minimum change in the animation property that could be visibly different to
+     * users.
+     *
+     * @return minimum change in property value that is visible to users
+     */
+    public float getMinimumVisibleChange() {
+        return mMinVisibleChange;
+    }
+
+    /**
+     * Remove {@code null} entries from the list.
+     */
+    private static <T> void removeNullEntries(ArrayList<T> list) {
+        // Clean up null entries
+        for (int i = list.size() - 1; i >= 0; i--) {
+            if (list.get(i) == null) {
+                list.remove(i);
+            }
+        }
+    }
+
+    /**
+     * Remove an entry from the list by marking it {@code null} and clean up later.
+     */
+    private static <T> void removeEntry(ArrayList<T> list, T entry) {
+        int id = list.indexOf(entry);
+        if (id >= 0) {
+            list.set(id, null);
+        }
+    }
+
+    /****************Animation Lifecycle Management***************/
+
+    /**
+     * Starts an animation. If the animation has already been started, no op. Note that calling
+     * {@link #start()} will not immediately set the property value to start value of the animation.
+     * The property values will be changed at each animation pulse, which happens before the draw
+     * pass. As a result, the changes will be reflected in the next frame, the same as if the values
+     * were set immediately. This method should only be called on main thread.
+     *
+     * @throws AndroidRuntimeException if this method is not called on the main thread
+     */
+    public void start() {
+        if (Looper.myLooper() != Looper.getMainLooper()) {
+            throw new AndroidRuntimeException("Animations may only be started on the main thread");
+        }
+        if (!mRunning) {
+            startAnimationInternal();
+        }
+    }
+
+    /**
+     * Cancels the on-going animation. If the animation hasn't started, no op. Note that this method
+     * should only be called on main thread.
+     *
+     * @throws AndroidRuntimeException if this method is not called on the main thread
+     */
+    public void cancel() {
+        if (Looper.myLooper() != Looper.getMainLooper()) {
+            throw new AndroidRuntimeException("Animations may only be canceled on the main thread");
+        }
+        if (mRunning) {
+            endAnimationInternal(true);
+        }
+    }
+
+    /**
+     * Returns whether the animation is currently running.
+     *
+     * @return {@code true} if the animation is currently running, {@code false} otherwise
+     */
+    public boolean isRunning() {
+        return mRunning;
+    }
+
+    /************************** Private APIs below ********************************/
+
+    // This gets called when the animation is started, to finish the setup of the animation
+    // before the animation pulsing starts.
+    private void startAnimationInternal() {
+        if (!mRunning) {
+            mRunning = true;
+            if (!mStartValueIsSet) {
+                mValue = getPropertyValue();
+            }
+            // Sanity check:
+            if (mValue > mMaxValue || mValue < mMinValue) {
+                throw new IllegalArgumentException("Starting value need to be in between min"
+                        + " value and max value");
+            }
+            AnimationHandler.getInstance().addAnimationFrameCallback(this, 0);
+        }
+    }
+
+    /**
+     * This gets call on each frame of the animation. Animation value and velocity are updated
+     * in this method based on the new frame time. The property value of the view being animated
+     * is then updated. The animation's ending conditions are also checked in this method. Once
+     * the animation reaches equilibrium, the animation will come to its end, and end listeners
+     * will be notified, if any.
+     *
+     * @hide
+     */
+    @Override
+    public boolean doAnimationFrame(long frameTime) {
+        if (mLastFrameTime == 0) {
+            // First frame.
+            mLastFrameTime = frameTime;
+            setPropertyValue(mValue);
+            return false;
+        }
+        long deltaT = frameTime - mLastFrameTime;
+        mLastFrameTime = frameTime;
+        boolean finished = updateValueAndVelocity(deltaT);
+        // Clamp value & velocity.
+        mValue = Math.min(mValue, mMaxValue);
+        mValue = Math.max(mValue, mMinValue);
+
+        setPropertyValue(mValue);
+
+        if (finished) {
+            endAnimationInternal(false);
+        }
+        return finished;
+    }
+
+    /**
+     * Updates the animation state (i.e. value and velocity). This method is package private, so
+     * subclasses can override this method to calculate the new value and velocity in their custom
+     * way.
+     *
+     * @param deltaT time elapsed in millisecond since last frame
+     * @return whether the animation has finished
+     */
+    abstract boolean updateValueAndVelocity(long deltaT);
+
+    /**
+     * Internal method to reset the animation states when animation is finished/canceled.
+     */
+    private void endAnimationInternal(boolean canceled) {
+        mRunning = false;
+        AnimationHandler.getInstance().removeCallback(this);
+        mLastFrameTime = 0;
+        mStartValueIsSet = false;
+        for (int i = 0; i < mEndListeners.size(); i++) {
+            if (mEndListeners.get(i) != null) {
+                mEndListeners.get(i).onAnimationEnd(this, canceled, mValue, mVelocity);
+            }
+        }
+        removeNullEntries(mEndListeners);
+    }
+
+    /**
+     * Returns whether z and translationZ are supported on the current build version.
+     */
+    private static boolean isZSupported() {
+        return Build.VERSION.SDK_INT >= 21;
+    }
+
+    /**
+     * Updates the property value through the corresponding setter.
+     */
+    void setPropertyValue(float value) {
+        mProperty.setValue(mTarget, value);
+        for (int i = 0; i < mUpdateListeners.size(); i++) {
+            if (mUpdateListeners.get(i) != null) {
+                mUpdateListeners.get(i).onAnimationUpdate(this, mValue, mVelocity);
+            }
+        }
+        removeNullEntries(mUpdateListeners);
+    }
+
+    /**
+     * Returns the default threshold.
+     */
+    float getValueThreshold() {
+        return mMinVisibleChange * THRESHOLD_MULTIPLIER;
+    }
+
+    /**
+     * Obtain the property value through the corresponding getter.
+     */
+    private float getPropertyValue() {
+        return mProperty.getValue(mTarget);
+    }
+
+    /****************Sub class animations**************/
+    /**
+     * Returns the acceleration at the given value with the given velocity.
+     **/
+    abstract float getAcceleration(float value, float velocity);
+
+    /**
+     * Returns whether the animation has reached equilibrium.
+     */
+    abstract boolean isAtEquilibrium(float value, float velocity);
+
+    /**
+     * Updates the default value threshold for the animation based on the property to be animated.
+     */
+    abstract void setValueThreshold(float threshold);
+
+    /**
+     * An animation listener that receives end notifications from an animation.
+     */
+    public interface OnAnimationEndListener {
+        /**
+         * Notifies the end of an animation. Note that this callback will be invoked not only when
+         * an animation reach equilibrium, but also when the animation is canceled.
+         *
+         * @param animation animation that has ended or was canceled
+         * @param canceled whether the animation has been canceled
+         * @param value the final value when the animation stopped
+         * @param velocity the final velocity when the animation stopped
+         */
+        void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value,
+                              float velocity);
+    }
+
+    /**
+     * Implementors of this interface can add themselves as update listeners
+     * to an <code>DynamicAnimation</code> instance to receive callbacks on every animation
+     * frame, after the current frame's values have been calculated for that
+     * <code>DynamicAnimation</code>.
+     */
+    public interface OnAnimationUpdateListener {
+
+        /**
+         * Notifies the occurrence of another frame of the animation.
+         *
+         * @param animation animation that the update listener is added to
+         * @param value the current value of the animation
+         * @param velocity the current velocity of the animation
+         */
+        void onAnimationUpdate(DynamicAnimation animation, float value, float velocity);
+    }
+}
diff --git a/dynamic-animation/src/android/support/animation/FlingAnimation.java b/dynamic-animation/src/android/support/animation/FlingAnimation.java
new file mode 100644
index 0000000..f8d19a2
--- /dev/null
+++ b/dynamic-animation/src/android/support/animation/FlingAnimation.java
@@ -0,0 +1,241 @@
+/*
+ * 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.animation;
+
+import android.support.annotation.FloatRange;
+
+/**
+ * <p>Fling animation is an animation that continues an initial momentum (most often from gesture
+ * velocity) and gradually slows down. The fling animation will come to a stop when the velocity of
+ * the animation is below the threshold derived from {@link #setMinimumVisibleChange(float)},
+ * or when the value of the animation has gone beyond the min or max value defined via
+ * {@link DynamicAnimation#setMinValue(float)} or {@link DynamicAnimation#setMaxValue(float)}.
+ * It is recommended to restrict the fling animation with min and/or max value, such that the
+ * animation can end when it goes beyond screen bounds, thus preserving CPU cycles and resources.
+ *
+ * <p>For example, you can create a fling animation that animates the translationX of a view:
+ * <pre class="prettyprint">
+ * FlingAnimation flingAnim = new FlingAnimation(view, DynamicAnimation.TRANSLATION_X)
+ *         // Sets the start velocity to -2000 (pixel/s)
+ *         .setStartVelocity(-2000)
+ *         // Optional but recommended to set a reasonable min and max range for the animation.
+ *         // In this particular case, we set the min and max to -200 and 2000 respectively.
+ *         .setMinValue(-200).setMaxValue(2000);
+ * flingAnim.start();
+ * </pre>
+ */
+public final class FlingAnimation extends DynamicAnimation<FlingAnimation> {
+
+    private final DragForce mFlingForce = new DragForce();
+
+    /**
+     * <p>This creates a FlingAnimation that animates a {@link FloatValueHolder} instance. During
+     * the animation, the {@link FloatValueHolder} instance will be updated via
+     * {@link FloatValueHolder#setValue(float)} each frame. The caller can obtain the up-to-date
+     * animation value via {@link FloatValueHolder#getValue()}.
+     *
+     * <p><strong>Note:</strong> changing the value in the {@link FloatValueHolder} via
+     * {@link FloatValueHolder#setValue(float)} outside of the animation during an
+     * animation run will not have any effect on the on-going animation.
+     *
+     * @param floatValueHolder the property to be animated
+     */
+    public FlingAnimation(FloatValueHolder floatValueHolder) {
+        super(floatValueHolder);
+        mFlingForce.setValueThreshold(getValueThreshold());
+    }
+
+    /**
+     * This creates a FlingAnimation that animates the property of the given object.
+     *
+     * @param object the Object whose property will be animated
+     * @param property the property to be animated
+     * @param <K> the class on which the property is declared
+     */
+    public <K> FlingAnimation(K object, FloatPropertyCompat<K> property) {
+        super(object, property);
+        mFlingForce.setValueThreshold(getValueThreshold());
+    }
+
+    /**
+     * Sets the friction for the fling animation. The greater the friction is, the sooner the
+     * animation will slow down. When not set, the friction defaults to 1.
+     *
+     * @param friction the friction used in the animation
+     * @return the animation whose friction will be scaled
+     * @throws IllegalArgumentException if the input friction is not positive
+     */
+    public FlingAnimation setFriction(
+            @FloatRange(from = 0.0, fromInclusive = false) float friction) {
+        if (friction <= 0) {
+            throw new IllegalArgumentException("Friction must be positive");
+        }
+        mFlingForce.setFrictionScalar(friction);
+        return this;
+    }
+
+    /**
+     * Returns the friction being set on the animation via {@link #setFriction(float)}. If the
+     * friction has not been set, the default friction of 1 will be returned.
+     *
+     * @return friction being used in the animation
+     */
+    public float getFriction() {
+        return mFlingForce.getFrictionScalar();
+    }
+
+    /**
+     * Sets the min value of the animation. When a fling animation reaches the min value, the
+     * animation will end immediately. Animations will not animate beyond the min value.
+     *
+     * @param minValue minimum value of the property to be animated
+     * @return the Animation whose min value is being set
+     */
+    @Override
+    public FlingAnimation setMinValue(float minValue) {
+        super.setMinValue(minValue);
+        return this;
+    }
+
+    /**
+     * Sets the max value of the animation. When a fling animation reaches the max value, the
+     * animation will end immediately. Animations will not animate beyond the max value.
+     *
+     * @param maxValue maximum value of the property to be animated
+     * @return the Animation whose max value is being set
+     */
+    @Override
+    public FlingAnimation setMaxValue(float maxValue) {
+        super.setMaxValue(maxValue);
+        return this;
+    }
+
+    /**
+     * Start velocity of the animation. Default velocity is 0. Unit: pixel/second
+     *
+     * <p>A <b>non-zero</b> start velocity is required for a FlingAnimation. If no start velocity is
+     * set through {@link #setStartVelocity(float)}, the start velocity defaults to 0. In that
+     * case, the fling animation will consider itself done in the next frame.
+     *
+     * <p>Note when using a fixed value as the start velocity (as opposed to getting the velocity
+     * through touch events), it is recommended to define such a value in dp/second and convert it
+     * to pixel/second based on the density of the screen to achieve a consistent look across
+     * different screens.
+     *
+     * <p>To convert from dp/second to pixel/second:
+     * <pre class="prettyprint">
+     * float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond,
+     *         getResources().getDisplayMetrics());
+     * </pre>
+     *
+     * @param startVelocity start velocity of the animation in pixel/second
+     * @return the Animation whose start velocity is being set
+     */
+    @Override
+    public FlingAnimation setStartVelocity(float startVelocity) {
+        super.setStartVelocity(startVelocity);
+        return this;
+    }
+
+    @Override
+    boolean updateValueAndVelocity(long deltaT) {
+
+        MassState state = mFlingForce.updateValueAndVelocity(mValue, mVelocity, deltaT);
+        mValue = state.mValue;
+        mVelocity = state.mVelocity;
+
+        // When the animation hits the max/min value, consider animation done.
+        if (mValue < mMinValue) {
+            mValue = mMinValue;
+            return true;
+        }
+        if (mValue > mMaxValue) {
+            mValue = mMaxValue;
+            return true;
+        }
+
+        if (isAtEquilibrium(mValue, mVelocity)) {
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    float getAcceleration(float value, float velocity) {
+        return mFlingForce.getAcceleration(value, velocity);
+    }
+
+    @Override
+    boolean isAtEquilibrium(float value, float velocity) {
+        return value >= mMaxValue
+                || value <= mMinValue
+                || mFlingForce.isAtEquilibrium(value, velocity);
+    }
+
+    @Override
+    void setValueThreshold(float threshold) {
+        mFlingForce.setValueThreshold(threshold);
+    }
+
+    private static final class DragForce implements Force {
+
+        private static final float DEFAULT_FRICTION = -4.2f;
+
+        // This multiplier is used to calculate the velocity threshold given a certain value
+        // threshold. The idea is that if it takes >= 1 frame to move the value threshold amount,
+        // then the velocity is a reasonable threshold.
+        private static final float VELOCITY_THRESHOLD_MULTIPLIER = 1000f / 16f;
+        private float mFriction = DEFAULT_FRICTION;
+        private float mVelocityThreshold;
+
+        // Internal state to hold a value/velocity pair.
+        private final DynamicAnimation.MassState mMassState = new DynamicAnimation.MassState();
+
+        void setFrictionScalar(float frictionScalar) {
+            mFriction = frictionScalar * DEFAULT_FRICTION;
+        }
+
+        float getFrictionScalar() {
+            return mFriction / DEFAULT_FRICTION;
+        }
+
+        MassState updateValueAndVelocity(float value, float velocity, long deltaT) {
+            mMassState.mVelocity = (float) (velocity * Math.exp((deltaT / 1000f) * mFriction));
+            mMassState.mValue = (float) (value - velocity / mFriction
+                    + velocity / mFriction * Math.exp(mFriction * deltaT / 1000f));
+            if (isAtEquilibrium(mMassState.mValue, mMassState.mVelocity)) {
+                mMassState.mVelocity = 0f;
+            }
+            return mMassState;
+        }
+
+        @Override
+        public float getAcceleration(float position, float velocity) {
+            return velocity * mFriction;
+        }
+
+        @Override
+        public boolean isAtEquilibrium(float value, float velocity) {
+            return Math.abs(velocity) < mVelocityThreshold;
+        }
+
+        void setValueThreshold(float threshold) {
+            mVelocityThreshold = threshold * VELOCITY_THRESHOLD_MULTIPLIER;
+        }
+    }
+
+}
diff --git a/dynamic-animation/src/android/support/animation/FloatPropertyCompat.java b/dynamic-animation/src/android/support/animation/FloatPropertyCompat.java
new file mode 100644
index 0000000..cde340c
--- /dev/null
+++ b/dynamic-animation/src/android/support/animation/FloatPropertyCompat.java
@@ -0,0 +1,85 @@
+/*
+ * 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.animation;
+
+import android.annotation.TargetApi;
+import android.util.FloatProperty;
+
+/**
+ * <p>FloatPropertyCompat is an abstraction that can be used to represent a mutable float value that
+ * is held in a host object. To access this float value, {@link #setValue(Object, float)} and getter
+ * {@link #getValue(Object)} need to be implemented. Both the setter and the getter take the
+ * primitive <code>float</code> type and avoids autoboxing and other overhead associated with the
+ * <code>Float</code> class.
+ *
+ * <p>For API 24 and later, {@link FloatProperty} instances can be converted to
+ * {@link FloatPropertyCompat} through
+ * {@link FloatPropertyCompat#createFloatPropertyCompat(FloatProperty)}.
+ *
+ * @param <T> the class on which the Property is declared
+ */
+public abstract class FloatPropertyCompat<T> {
+    final String mPropertyName;
+
+    /**
+     * A constructor that takes an identifying name.
+     */
+    public FloatPropertyCompat(String name) {
+        mPropertyName = name;
+    }
+
+    /**
+     * Create a {@link FloatPropertyCompat} wrapper for a {@link FloatProperty} object. The new
+     * {@link FloatPropertyCompat} instance will access and modify the property value of
+     * {@link FloatProperty} through the {@link FloatProperty} instance's setter and getter.
+     *
+     * @param property FloatProperty instance to be wrapped
+     * @param <T> the class on which the Property is declared
+     * @return a new {@link FloatPropertyCompat} wrapper for the given {@link FloatProperty} object
+     */
+    @TargetApi(24)
+    public static <T> FloatPropertyCompat<T> createFloatPropertyCompat(
+            final FloatProperty<T> property) {
+        return new FloatPropertyCompat<T>(property.getName()) {
+            @Override
+            public float getValue(T object) {
+                return property.get(object);
+            }
+
+            @Override
+            public void setValue(T object, float value) {
+                property.setValue(object, value);
+            }
+        };
+    }
+
+    /**
+     * Returns the current value that this property represents on the given <code>object</code>.
+     *
+     * @param object object which this property represents
+     * @return the current property value of the given object
+     */
+    public abstract float getValue(T object);
+
+    /**
+     * Sets the value on <code>object</code> which this property represents.
+     *
+     * @param object object which this property represents
+     * @param value new value of the property
+     */
+    public abstract void setValue(T object, float value);
+}
diff --git a/dynamic-animation/src/android/support/animation/FloatValueHolder.java b/dynamic-animation/src/android/support/animation/FloatValueHolder.java
new file mode 100644
index 0000000..08dcc9c
--- /dev/null
+++ b/dynamic-animation/src/android/support/animation/FloatValueHolder.java
@@ -0,0 +1,74 @@
+/*
+ * 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.animation;
+
+/**
+ * <p>FloatValueHolder holds a float value. FloatValueHolder provides a setter and a getter (
+ * i.e. {@link #setValue(float)} and {@link #getValue()}) to access this float value. Animations can
+ * be performed on a FloatValueHolder instance. During each frame of the animation, the
+ * FloatValueHolder will have its value updated via {@link #setValue(float)}. The caller can
+ * obtain the up-to-date animation value via {@link FloatValueHolder#getValue()}.
+ *
+ * <p> Here is an example for creating a {@link FlingAnimation} with a FloatValueHolder:
+ * <pre class="prettyprint">
+ * // Create a fling animation with an initial velocity of 5000 (pixel/s) and an initial position
+ * // of 20f.
+ * FloatValueHolder floatValueHolder = new FloatValueHolder(20f);
+ * FlingAnimation anim = new FlingAnimation(floatValueHolder).setStartVelocity(5000);
+ * anim.start();
+ * </pre>
+ *
+ * @see SpringAnimation#SpringAnimation(FloatValueHolder)
+ * @see FlingAnimation#FlingAnimation(FloatValueHolder)
+ */
+
+public final class FloatValueHolder {
+    private float mValue = 0.0f;
+
+    /**
+     * Constructs a holder for a float value that is initialized to 0.
+     */
+    public FloatValueHolder() {
+    }
+
+    /**
+     * Constructs a holder for a float value that is initialized to the input value.
+     *
+     * @param value the value to initialize the value held in the FloatValueHolder
+     */
+    public FloatValueHolder(float value) {
+        setValue(value);
+    }
+
+    /**
+     * Sets the value held in the FloatValueHolder instance.
+     *
+     * @param value float value held in the FloatValueHolder instance
+     */
+    public void setValue(float value) {
+        mValue = value;
+    }
+
+    /**
+     * Returns the float value held in the FloatValueHolder instance.
+     *
+     * @return float value held in the FloatValueHolder instance
+     */
+    public float getValue() {
+        return mValue;
+    }
+}
diff --git a/dynamic-animation/src/android/support/animation/Force.java b/dynamic-animation/src/android/support/animation/Force.java
new file mode 100644
index 0000000..afcf84d
--- /dev/null
+++ b/dynamic-animation/src/android/support/animation/Force.java
@@ -0,0 +1,27 @@
+/*
+ * 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.animation;
+
+/**
+ * Hide this for now, in case we want to change the API.
+ */
+interface Force {
+    // Acceleration based on position.
+    float getAcceleration(float position, float velocity);
+
+    boolean isAtEquilibrium(float value, float velocity);
+}
diff --git a/dynamic-animation/src/android/support/animation/SpringAnimation.java b/dynamic-animation/src/android/support/animation/SpringAnimation.java
new file mode 100644
index 0000000..5a9a432
--- /dev/null
+++ b/dynamic-animation/src/android/support/animation/SpringAnimation.java
@@ -0,0 +1,296 @@
+/*
+ * 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.animation;
+
+import android.os.Looper;
+import android.util.AndroidRuntimeException;
+import android.view.View;
+
+/**
+ * SpringAnimation is an animation that is driven by a {@link SpringForce}. The spring force defines
+ * the spring's stiffness, damping ratio, as well as the rest position. Once the SpringAnimation is
+ * started, on each frame the spring force will update the animation's value and velocity.
+ * The animation will continue to run until the spring force reaches equilibrium. If the spring used
+ * in the animation is undamped, the animation will never reach equilibrium. Instead, it will
+ * oscillate forever.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * </div>
+ *
+ * <p>To create a simple {@link SpringAnimation} that uses the default {@link SpringForce}:</p>
+ * <pre class="prettyprint">
+ * // Create an animation to animate view's X property, set the rest position of the
+ * // default spring to 0, and start the animation with a starting velocity of 5000 (pixel/s).
+ * final SpringAnimation anim = new SpringAnimation(view, DynamicAnimation.X, 0)
+ *         .setStartVelocity(5000);
+ * anim.start();
+ * </pre>
+ *
+ * <p>Alternatively, a {@link SpringAnimation} can take a pre-configured {@link SpringForce}, and
+ * use that to drive the animation. </p>
+ * <pre class="prettyprint">
+ * // Create a low stiffness, low bounce spring at position 0.
+ * SpringForce spring = new SpringForce(0)
+ *         .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+ *         .setStiffness(SpringForce.STIFFNESS_LOW);
+ * // Create an animation to animate view's scaleY property, and start the animation using
+ * // the spring above and a starting value of 0.5. Additionally, constrain the range of value for
+ * // the animation to be non-negative, effectively preventing any spring overshoot.
+ * final SpringAnimation anim = new SpringAnimation(view, DynamicAnimation.SCALE_Y)
+ *         .setMinValue(0).setSpring(spring).setStartValue(1);
+ * anim.start();
+ * </pre>
+ */
+public final class SpringAnimation extends DynamicAnimation<SpringAnimation> {
+
+    private SpringForce mSpring = null;
+    private float mPendingPosition = UNSET;
+    private static final float UNSET = Float.MAX_VALUE;
+    private boolean mEndRequested = false;
+
+    /**
+     * <p>This creates a SpringAnimation that animates a {@link FloatValueHolder} instance. During
+     * the animation, the {@link FloatValueHolder} instance will be updated via
+     * {@link FloatValueHolder#setValue(float)} each frame. The caller can obtain the up-to-date
+     * animation value via {@link FloatValueHolder#getValue()}.
+     *
+     * <p><strong>Note:</strong> changing the value in the {@link FloatValueHolder} via
+     * {@link FloatValueHolder#setValue(float)} outside of the animation during an
+     * animation run will not have any effect on the on-going animation.
+     *
+     * @param floatValueHolder the property to be animated
+     */
+    public SpringAnimation(FloatValueHolder floatValueHolder) {
+        super(floatValueHolder);
+    }
+
+    /**
+     * This creates a SpringAnimation that animates the property of the given object.
+     * Note, a spring will need to setup through {@link #setSpring(SpringForce)} before
+     * the animation starts.
+     *
+     * @param object the Object whose property will be animated
+     * @param property the property to be animated
+     * @param <K> the class on which the Property is declared
+     */
+    public <K> SpringAnimation(K object, FloatPropertyCompat<K> property) {
+        super(object, property);
+    }
+
+    /**
+     * This creates a SpringAnimation that animates the property of the given object. A Spring will
+     * be created with the given final position and default stiffness and damping ratio.
+     * This spring can be accessed and reconfigured through {@link #setSpring(SpringForce)}.
+     *
+     * @param object the Object whose property will be animated
+     * @param property the property to be animated
+     * @param finalPosition the final position of the spring to be created.
+     * @param <K> the class on which the Property is declared
+     */
+    public <K> SpringAnimation(K object, FloatPropertyCompat<K> property,
+            float finalPosition) {
+        super(object, property);
+        mSpring = new SpringForce(finalPosition);
+    }
+
+    /**
+     * @deprecated This API is being replaced with
+     * {@link #SpringAnimation(Object, FloatPropertyCompat)}.
+     *
+     * <p><b>Note: </b> Migration to the new API should require no modification to callers of this
+     * deprecated API.  The new API's parameters are the base class of the original's parameters and
+     * therefore is compatible to calls to this deprecated method.
+     */
+    @Deprecated
+    public SpringAnimation(View v, ViewProperty property) {
+        super(v, property);
+    }
+
+    /**
+     * @deprecated This API is being replaced with
+     * {@link #SpringAnimation(Object, FloatPropertyCompat, float)}.
+     *
+     * <p><b>Note: </b> Migration to the new API should require no modification to callers of this
+     * deprecated API.  The new API's parameters are the base class of the original's parameters and
+     * therefore is compatible to calls to this deprecated method.
+     */
+    @Deprecated
+    public SpringAnimation(View v, ViewProperty property, float finalPosition) {
+        super(v, property);
+        mSpring = new SpringForce(finalPosition);
+    }
+
+    /**
+     * Returns the spring that the animation uses for animations.
+     *
+     * @return the spring that the animation uses for animations
+     */
+    public SpringForce getSpring() {
+        return mSpring;
+    }
+
+    /**
+     * Uses the given spring as the force that drives this animation. If this spring force has its
+     * parameters re-configured during the animation, the new configuration will be reflected in the
+     * animation immediately.
+     *
+     * @param force a pre-defined spring force that drives the animation
+     * @return the animation that the spring force is set on
+     */
+    public SpringAnimation setSpring(SpringForce force) {
+        mSpring = force;
+        return this;
+    }
+
+    @Override
+    public void start() {
+        sanityCheck();
+        mSpring.setValueThreshold(getValueThreshold());
+        super.start();
+    }
+
+    /**
+     * Updates the final position of the spring.
+     * <p/>
+     * When the animation is running, calling this method would assume the position change of the
+     * spring as a continuous movement since last frame, which yields more accurate results than
+     * changing the spring position directly through {@link SpringForce#setFinalPosition(float)}.
+     * <p/>
+     * If the animation hasn't started, calling this method will change the spring position, and
+     * immediately start the animation.
+     *
+     * @param finalPosition rest position of the spring
+     */
+    public void animateToFinalPosition(float finalPosition) {
+        if (isRunning()) {
+            mPendingPosition = finalPosition;
+        } else {
+            if (mSpring == null) {
+                mSpring = new SpringForce(finalPosition);
+            }
+            mSpring.setFinalPosition(finalPosition);
+            start();
+        }
+    }
+
+    /**
+     * Skips to the end of the animation. If the spring is undamped, an
+     * {@link IllegalStateException} will be thrown, as the animation would never reach to an end.
+     * It is recommended to check {@link #canSkipToEnd()} before calling this method. This method
+     * should only be called on main thread. If animation is not running, no-op.
+     *
+     * @throws IllegalStateException if the spring is undamped (i.e. damping ratio = 0)
+     * @throws AndroidRuntimeException if this method is not called on the main thread
+     */
+    public void skipToEnd() {
+        if (!canSkipToEnd()) {
+            throw new UnsupportedOperationException("Spring animations can only come to an end"
+                    + " when there is damping");
+        }
+        if (Looper.myLooper() != Looper.getMainLooper()) {
+            throw new AndroidRuntimeException("Animations may only be started on the main thread");
+        }
+        if (mRunning) {
+            mEndRequested = true;
+        }
+    }
+
+    /**
+     * Queries whether the spring can eventually come to the rest position.
+     *
+     * @return {@code true} if the spring is damped, otherwise {@code false}
+     */
+    public boolean canSkipToEnd() {
+        return mSpring.mDampingRatio > 0;
+    }
+
+    /************************ Below are private APIs *************************/
+
+    private void sanityCheck() {
+        if (mSpring == null) {
+            throw new UnsupportedOperationException("Incomplete SpringAnimation: Either final"
+                    + " position or a spring force needs to be set.");
+        }
+        double finalPosition = mSpring.getFinalPosition();
+        if (finalPosition > mMaxValue) {
+            throw new UnsupportedOperationException("Final position of the spring cannot be greater"
+                    + " than the max value.");
+        } else if (finalPosition < mMinValue) {
+            throw new UnsupportedOperationException("Final position of the spring cannot be less"
+                    + " than the min value.");
+        }
+    }
+
+    @Override
+    boolean updateValueAndVelocity(long deltaT) {
+        // If user had requested end, then update the value and velocity to end state and consider
+        // animation done.
+        if (mEndRequested) {
+            if (mPendingPosition != UNSET) {
+                mSpring.setFinalPosition(mPendingPosition);
+                mPendingPosition = UNSET;
+            }
+            mValue = mSpring.getFinalPosition();
+            mVelocity = 0;
+            mEndRequested = false;
+            return true;
+        }
+
+        if (mPendingPosition != UNSET) {
+            double lastPosition = mSpring.getFinalPosition();
+            // Approximate by considering half of the time spring position stayed at the old
+            // position, half of the time it's at the new position.
+            MassState massState = mSpring.updateValues(mValue, mVelocity, deltaT / 2);
+            mSpring.setFinalPosition(mPendingPosition);
+            mPendingPosition = UNSET;
+
+            massState = mSpring.updateValues(massState.mValue, massState.mVelocity, deltaT / 2);
+            mValue = massState.mValue;
+            mVelocity = massState.mVelocity;
+
+        } else {
+            MassState massState = mSpring.updateValues(mValue, mVelocity, deltaT);
+            mValue = massState.mValue;
+            mVelocity = massState.mVelocity;
+        }
+
+        mValue = Math.max(mValue, mMinValue);
+        mValue = Math.min(mValue, mMaxValue);
+
+        if (isAtEquilibrium(mValue, mVelocity)) {
+            mValue = mSpring.getFinalPosition();
+            mVelocity = 0f;
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    float getAcceleration(float value, float velocity) {
+        return mSpring.getAcceleration(value, velocity);
+    }
+
+    @Override
+    boolean isAtEquilibrium(float value, float velocity) {
+        return mSpring.isAtEquilibrium(value, velocity);
+    }
+
+    @Override
+    void setValueThreshold(float threshold) {
+    }
+}
diff --git a/dynamic-animation/src/android/support/animation/SpringForce.java b/dynamic-animation/src/android/support/animation/SpringForce.java
new file mode 100644
index 0000000..5f95aa8
--- /dev/null
+++ b/dynamic-animation/src/android/support/animation/SpringForce.java
@@ -0,0 +1,329 @@
+/*
+ * 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.animation;
+
+import android.support.annotation.FloatRange;
+
+/**
+ * Spring Force defines the characteristics of the spring being used in the animation.
+ * <p>
+ * By configuring the stiffness and damping ratio, callers can create a spring with the look and
+ * feel suits their use case. Stiffness corresponds to the spring constant. The stiffer the spring
+ * is, the harder it is to stretch it, the faster it undergoes dampening.
+ * <p>
+ * Spring damping ratio describes how oscillations in a system decay after a disturbance.
+ * When damping ratio > 1* (i.e. over-damped), the object will quickly return to the rest position
+ * without overshooting. If damping ratio equals to 1 (i.e. critically damped), the object will
+ * return to equilibrium within the shortest amount of time. When damping ratio is less than 1
+ * (i.e. under-damped), the mass tends to overshoot, and return, and overshoot again. Without any
+ * damping (i.e. damping ratio = 0), the mass will oscillate forever.
+ */
+public final class SpringForce implements Force {
+    /**
+     * Stiffness constant for extremely stiff spring.
+     */
+    public static final float STIFFNESS_HIGH = 10_000f;
+    /**
+     * Stiffness constant for medium stiff spring. This is the default stiffness for spring force.
+     */
+    public static final float STIFFNESS_MEDIUM = 1500f;
+    /**
+     * Stiffness constant for a spring with low stiffness.
+     */
+    public static final float STIFFNESS_LOW = 200f;
+    /**
+     * Stiffness constant for a spring with very low stiffness.
+     */
+    public static final float STIFFNESS_VERY_LOW = 50f;
+
+    /**
+     * Damping ratio for a very bouncy spring. Note for under-damped springs
+     * (i.e. damping ratio < 1), the lower the damping ratio, the more bouncy the spring.
+     */
+    public static final float DAMPING_RATIO_HIGH_BOUNCY = 0.2f;
+    /**
+     * Damping ratio for a medium bouncy spring. This is also the default damping ratio for spring
+     * force. Note for under-damped springs (i.e. damping ratio < 1), the lower the damping ratio,
+     * the more bouncy the spring.
+     */
+    public static final float DAMPING_RATIO_MEDIUM_BOUNCY = 0.5f;
+    /**
+     * Damping ratio for a spring with low bounciness. Note for under-damped springs
+     * (i.e. damping ratio < 1), the lower the damping ratio, the higher the bounciness.
+     */
+    public static final float DAMPING_RATIO_LOW_BOUNCY = 0.75f;
+    /**
+     * Damping ratio for a spring with no bounciness. This damping ratio will create a critically
+     * damped spring that returns to equilibrium within the shortest amount of time without
+     * oscillating.
+     */
+    public static final float DAMPING_RATIO_NO_BOUNCY = 1f;
+
+    // This multiplier is used to calculate the velocity threshold given a certain value threshold.
+    // The idea is that if it takes >= 1 frame to move the value threshold amount, then the velocity
+    // is a reasonable threshold.
+    private static final double VELOCITY_THRESHOLD_MULTIPLIER = 1000.0 / 16.0;
+
+    // Natural frequency
+    double mNaturalFreq = Math.sqrt(STIFFNESS_MEDIUM);
+    // Damping ratio.
+    double mDampingRatio = DAMPING_RATIO_MEDIUM_BOUNCY;
+
+    // Value to indicate an unset state.
+    private static final double UNSET = Double.MAX_VALUE;
+
+    // Indicates whether the spring has been initialized
+    private boolean mInitialized = false;
+
+    // Threshold for velocity and value to determine when it's reasonable to assume that the spring
+    // is approximately at rest.
+    private double mValueThreshold;
+    private double mVelocityThreshold;
+
+    // Intermediate values to simplify the spring function calculation per frame.
+    private double mGammaPlus;
+    private double mGammaMinus;
+    private double mDampedFreq;
+
+    // Final position of the spring. This must be set before the start of the animation.
+    private double mFinalPosition = UNSET;
+
+    // Internal state to hold a value/velocity pair.
+    private final DynamicAnimation.MassState mMassState = new DynamicAnimation.MassState();
+
+    /**
+     * Creates a spring force. Note that final position of the spring must be set through
+     * {@link #setFinalPosition(float)} before the spring animation starts.
+     */
+    public SpringForce() {
+        // No op.
+    }
+
+    /**
+     * Creates a spring with a given final rest position.
+     *
+     * @param finalPosition final position of the spring when it reaches equilibrium
+     */
+    public SpringForce(float finalPosition) {
+        mFinalPosition = finalPosition;
+    }
+
+    /**
+     * Sets the stiffness of a spring. The more stiff a spring is, the more force it applies to
+     * the object attached when the spring is not at the final position. Default stiffness is
+     * {@link #STIFFNESS_MEDIUM}.
+     *
+     * @param stiffness non-negative stiffness constant of a spring
+     * @return the spring force that the given stiffness is set on
+     * @throws IllegalArgumentException if the given spring stiffness is not positive
+     */
+    public SpringForce setStiffness(
+            @FloatRange(from = 0.0, fromInclusive = false) float stiffness) {
+        if (stiffness <= 0) {
+            throw new IllegalArgumentException("Spring stiffness constant must be positive.");
+        }
+        mNaturalFreq = Math.sqrt(stiffness);
+        // All the intermediate values need to be recalculated.
+        mInitialized = false;
+        return this;
+    }
+
+    /**
+     * Gets the stiffness of the spring.
+     *
+     * @return the stiffness of the spring
+     */
+    public float getStiffness() {
+        return (float) (mNaturalFreq * mNaturalFreq);
+    }
+
+    /**
+     * Spring damping ratio describes how oscillations in a system decay after a disturbance.
+     * <p>
+     * When damping ratio > 1 (over-damped), the object will quickly return to the rest position
+     * without overshooting. If damping ratio equals to 1 (i.e. critically damped), the object will
+     * return to equilibrium within the shortest amount of time. When damping ratio is less than 1
+     * (i.e. under-damped), the mass tends to overshoot, and return, and overshoot again. Without
+     * any damping (i.e. damping ratio = 0), the mass will oscillate forever.
+     * <p>
+     * Default damping ratio is {@link #DAMPING_RATIO_MEDIUM_BOUNCY}.
+     *
+     * @param dampingRatio damping ratio of the spring, it should be non-negative
+     * @return the spring force that the given damping ratio is set on
+     * @throws IllegalArgumentException if the {@param dampingRatio} is negative.
+     */
+    public SpringForce setDampingRatio(@FloatRange(from = 0.0) float dampingRatio) {
+        if (dampingRatio < 0) {
+            throw new IllegalArgumentException("Damping ratio must be non-negative");
+        }
+        mDampingRatio = dampingRatio;
+        // All the intermediate values need to be recalculated.
+        mInitialized = false;
+        return this;
+    }
+
+    /**
+     * Returns the damping ratio of the spring.
+     *
+     * @return damping ratio of the spring
+     */
+    public float getDampingRatio() {
+        return (float) mDampingRatio;
+    }
+
+    /**
+     * Sets the rest position of the spring.
+     *
+     * @param finalPosition rest position of the spring
+     * @return the spring force that the given final position is set on
+     */
+    public SpringForce setFinalPosition(float finalPosition) {
+        mFinalPosition = finalPosition;
+        return this;
+    }
+
+    /**
+     * Returns the rest position of the spring.
+     *
+     * @return rest position of the spring
+     */
+    public float getFinalPosition() {
+        return (float) mFinalPosition;
+    }
+
+    /*********************** Below are private APIs *********************/
+
+    /**
+     * @hide
+     */
+    @Override
+    public float getAcceleration(float lastDisplacement, float lastVelocity) {
+
+        lastDisplacement -= getFinalPosition();
+
+        double k = mNaturalFreq * mNaturalFreq;
+        double c = 2 * mNaturalFreq * mDampingRatio;
+
+        return (float) (-k * lastDisplacement - c * lastVelocity);
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public boolean isAtEquilibrium(float value, float velocity) {
+        if (Math.abs(velocity) < mVelocityThreshold
+                && Math.abs(value - getFinalPosition()) < mValueThreshold) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Initialize the string by doing the necessary pre-calculation as well as some sanity check
+     * on the setup.
+     *
+     * @throws IllegalStateException if the final position is not yet set by the time the spring
+     *                               animation has started
+     */
+    private void init() {
+        if (mInitialized) {
+            return;
+        }
+
+        if (mFinalPosition == UNSET) {
+            throw new IllegalStateException("Error: Final position of the spring must be"
+                    + " set before the animation starts");
+        }
+
+        if (mDampingRatio > 1) {
+            // Over damping
+            mGammaPlus = -mDampingRatio * mNaturalFreq
+                    + mNaturalFreq * Math.sqrt(mDampingRatio * mDampingRatio - 1);
+            mGammaMinus = -mDampingRatio * mNaturalFreq
+                    - mNaturalFreq * Math.sqrt(mDampingRatio * mDampingRatio - 1);
+        } else if (mDampingRatio >= 0 && mDampingRatio < 1) {
+            // Under damping
+            mDampedFreq = mNaturalFreq * Math.sqrt(1 - mDampingRatio * mDampingRatio);
+        }
+
+        mInitialized = true;
+    }
+
+    /**
+     * Internal only call for Spring to calculate the spring position/velocity using
+     * an analytical approach.
+     */
+    DynamicAnimation.MassState updateValues(double lastDisplacement, double lastVelocity,
+            long timeElapsed) {
+        init();
+
+        double deltaT = timeElapsed / 1000d; // unit: seconds
+        lastDisplacement -= mFinalPosition;
+        double displacement;
+        double currentVelocity;
+        if (mDampingRatio > 1) {
+            // Overdamped
+            double coeffA =  lastDisplacement - (mGammaMinus * lastDisplacement - lastVelocity)
+                    / (mGammaMinus - mGammaPlus);
+            double coeffB =  (mGammaMinus * lastDisplacement - lastVelocity)
+                    / (mGammaMinus - mGammaPlus);
+            displacement = coeffA * Math.pow(Math.E, mGammaMinus * deltaT)
+                    + coeffB * Math.pow(Math.E, mGammaPlus * deltaT);
+            currentVelocity = coeffA * mGammaMinus * Math.pow(Math.E, mGammaMinus * deltaT)
+                    + coeffB * mGammaPlus * Math.pow(Math.E, mGammaPlus * deltaT);
+        } else if (mDampingRatio == 1) {
+            // Critically damped
+            double coeffA = lastDisplacement;
+            double coeffB = lastVelocity + mNaturalFreq * lastDisplacement;
+            displacement = (coeffA + coeffB * deltaT) * Math.pow(Math.E, -mNaturalFreq * deltaT);
+            currentVelocity = (coeffA + coeffB * deltaT) * Math.pow(Math.E, -mNaturalFreq * deltaT)
+                    * (-mNaturalFreq) + coeffB * Math.pow(Math.E, -mNaturalFreq * deltaT);
+        } else {
+            // Underdamped
+            double cosCoeff = lastDisplacement;
+            double sinCoeff = (1 / mDampedFreq) * (mDampingRatio * mNaturalFreq
+                    * lastDisplacement + lastVelocity);
+            displacement = Math.pow(Math.E, -mDampingRatio * mNaturalFreq * deltaT)
+                    * (cosCoeff * Math.cos(mDampedFreq * deltaT)
+                    + sinCoeff * Math.sin(mDampedFreq * deltaT));
+            currentVelocity = displacement * (-mNaturalFreq) * mDampingRatio
+                    + Math.pow(Math.E, -mDampingRatio * mNaturalFreq * deltaT)
+                    * (-mDampedFreq * cosCoeff * Math.sin(mDampedFreq * deltaT)
+                    + mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT));
+        }
+
+        mMassState.mValue = (float) (displacement + mFinalPosition);
+        mMassState.mVelocity = (float) currentVelocity;
+        return mMassState;
+    }
+
+    /**
+     * This threshold defines how close the animation value needs to be before the animation can
+     * finish. This default value is based on the property being animated, e.g. animations on alpha,
+     * scale, translation or rotation would have different thresholds. This value should be small
+     * enough to avoid visual glitch of "jumping to the end". But it shouldn't be so small that
+     * animations take seconds to finish.
+     *
+     * @param threshold the difference between the animation value and final spring position that
+     *                  is allowed to end the animation when velocity is very low
+     */
+    void setValueThreshold(double threshold) {
+        mValueThreshold = Math.abs(threshold);
+        mVelocityThreshold = mValueThreshold * VELOCITY_THRESHOLD_MULTIPLIER;
+    }
+}
diff --git a/dynamic-animation/tests/AndroidManifest.xml b/dynamic-animation/tests/AndroidManifest.xml
new file mode 100755
index 0000000..2703ffc
--- /dev/null
+++ b/dynamic-animation/tests/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.animation.test">
+
+    <uses-sdk
+        android:minSdkVersion="16"
+        android:targetSdkVersion="23"/>
+    <application android:supportsRtl="true">
+        <uses-library android:name="android.test.runner"/>
+
+        <activity android:name="android.support.dynamicanimation.tests.AnimationActivity"/>
+    </application>
+</manifest>
diff --git a/dynamic-animation/tests/NO_DOCS b/dynamic-animation/tests/NO_DOCS
new file mode 100644
index 0000000..4dad694
--- /dev/null
+++ b/dynamic-animation/tests/NO_DOCS
@@ -0,0 +1,17 @@
+# 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.
+
+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/dynamic-animation/tests/res/layout/anim_layout.xml b/dynamic-animation/tests/res/layout/anim_layout.xml
new file mode 100644
index 0000000..5db7936
--- /dev/null
+++ b/dynamic-animation/tests/res/layout/anim_layout.xml
@@ -0,0 +1,32 @@
+<?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.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <View
+        android:id="@+id/anim_view"
+        android:layout_width="100dp"
+        android:layout_height="100dp"/>
+
+    <View
+        android:id="@+id/anim_another_view"
+        android:layout_width="100dp"
+        android:layout_height="100dp"/>
+
+</FrameLayout>
diff --git a/dynamic-animation/tests/src/android/support/dynamicanimation/tests/AnimationActivity.java b/dynamic-animation/tests/src/android/support/dynamicanimation/tests/AnimationActivity.java
new file mode 100644
index 0000000..8b0799a
--- /dev/null
+++ b/dynamic-animation/tests/src/android/support/dynamicanimation/tests/AnimationActivity.java
@@ -0,0 +1,29 @@
+/*
+ * 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.dynamicanimation.tests;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.dynamicanimation.test.R;
+
+public class AnimationActivity extends Activity {
+    @Override
+    public void onCreate(Bundle bundle) {
+        super.onCreate(bundle);
+        setContentView(R.layout.anim_layout);
+    }
+}
diff --git a/dynamic-animation/tests/src/android/support/dynamicanimation/tests/FlingTests.java b/dynamic-animation/tests/src/android/support/dynamicanimation/tests/FlingTests.java
new file mode 100644
index 0000000..b982470
--- /dev/null
+++ b/dynamic-animation/tests/src/android/support/dynamicanimation/tests/FlingTests.java
@@ -0,0 +1,222 @@
+/*
+ * 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.dynamicanimation.tests;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.floatThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import android.support.animation.DynamicAnimation;
+import android.support.animation.FlingAnimation;
+import android.support.animation.FloatPropertyCompat;
+import android.support.animation.FloatValueHolder;
+import android.support.dynamicanimation.test.R;
+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.view.View;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.internal.matchers.GreaterThan;
+import org.mockito.internal.matchers.LessThan;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class FlingTests {
+    @Rule
+    public final ActivityTestRule<AnimationActivity> mActivityTestRule;
+    public View mView1;
+    public View mView2;
+
+    @Rule
+    public ExpectedException mExpectedException = ExpectedException.none();
+
+    public FlingTests() {
+        mActivityTestRule = new ActivityTestRule<>(AnimationActivity.class);
+    }
+
+    @Before
+    public void setup() throws Exception {
+        mView1 = mActivityTestRule.getActivity().findViewById(R.id.anim_view);
+        mView2 = mActivityTestRule.getActivity().findViewById(R.id.anim_another_view);
+    }
+
+    /**
+     * Test that custom properties are supported.
+     */
+    @Test
+    public void testCustomProperties() {
+        final Object animObj = new Object();
+        FloatPropertyCompat property = new FloatPropertyCompat("") {
+            private float mValue = 0f;
+            @Override
+            public float getValue(Object object) {
+                assertEquals(animObj, object);
+                return mValue;
+            }
+
+            @Override
+            public void setValue(Object object, float value) {
+                assertEquals(animObj, object);
+                assertTrue(value > mValue);
+                assertTrue(value >= 100);
+                mValue = value;
+            }
+        };
+        final FlingAnimation anim = new FlingAnimation(animObj, property);
+        DynamicAnimation.OnAnimationEndListener listener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        anim.addEndListener(listener);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.setStartValue(100).setStartVelocity(2000).start();
+            }
+        });
+        verify(listener, timeout(1000)).onAnimationEnd(eq(anim), eq(false), floatThat(
+                new GreaterThan(110f)), eq(0f));
+    }
+
+    /**
+     * Test that spring animation can work with a single property without an object.
+     */
+    @Test
+    public void testFloatValueHolder() {
+        FloatValueHolder floatValueHolder = new FloatValueHolder();
+        assertEquals(0.0f, floatValueHolder.getValue());
+
+        final FlingAnimation anim = new FlingAnimation(floatValueHolder).setStartVelocity(-2500);
+
+        DynamicAnimation.OnAnimationEndListener listener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        anim.addEndListener(listener);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.start();
+            }
+        });
+        verify(listener, timeout(1000)).onAnimationEnd(eq(anim), eq(false), floatThat(
+                new LessThan(-50f)), eq(0f));
+    }
+
+
+    /**
+     * Test that friction does affect how fast the slow down happens. Fling animation with
+     * higher friction should finish first.
+     */
+    @Test
+    public void testFriction() {
+        FloatValueHolder floatValueHolder = new FloatValueHolder();
+        float lowFriction = 0.5f;
+        float highFriction = 2f;
+        final FlingAnimation animLowFriction = new FlingAnimation(floatValueHolder);
+        final FlingAnimation animHighFriction = new FlingAnimation(floatValueHolder);
+
+        animHighFriction.setFriction(highFriction);
+        animLowFriction.setFriction(lowFriction);
+
+        DynamicAnimation.OnAnimationEndListener listener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        animHighFriction.addEndListener(listener);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                animHighFriction.setStartVelocity(5000).setStartValue(0).start();
+                animLowFriction.setStartVelocity(5000).setStartValue(0).start();
+            }
+        });
+
+        verify(listener, timeout(1000)).onAnimationEnd(eq(animHighFriction), eq(false), floatThat(
+                new GreaterThan(200f)), eq(0f));
+        // By the time high scalar animation finishes, the lower friction animation should still be
+        // running.
+        assertTrue(animLowFriction.isRunning());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                animLowFriction.cancel();
+            }
+        });
+
+        assertEquals(lowFriction, animLowFriction.getFriction(), 0f);
+        assertEquals(highFriction, animHighFriction.getFriction(), 0f);
+
+    }
+
+    /**
+     * Test that velocity threshold does affect how early fling animation ends. An animation with
+     * higher velocity threshold should finish first.
+     */
+    @Test
+    public void testVelocityThreshold() {
+        FloatValueHolder floatValueHolder = new FloatValueHolder();
+        float lowThreshold = 5f;
+        final float highThreshold = 10f;
+        final FlingAnimation animLowThreshold = new FlingAnimation(floatValueHolder);
+        final FlingAnimation animHighThreshold = new FlingAnimation(floatValueHolder);
+
+        animHighThreshold.setMinimumVisibleChange(highThreshold);
+        animHighThreshold.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
+            @Override
+            public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
+                if (velocity != 0f) {
+                    // Other than last frame, velocity should always be above threshold
+                    assertTrue(velocity >= highThreshold);
+                }
+            }
+        });
+        animLowThreshold.setMinimumVisibleChange(lowThreshold);
+
+        DynamicAnimation.OnAnimationEndListener listener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        animHighThreshold.addEndListener(listener);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                animHighThreshold.setStartVelocity(2000).setStartValue(0).start();
+                animLowThreshold.setStartVelocity(2000).setStartValue(0).start();
+            }
+        });
+
+        verify(listener, timeout(1000)).onAnimationEnd(eq(animHighThreshold), eq(false), floatThat(
+                new GreaterThan(200f)), eq(0f));
+        // By the time high scalar animation finishes, the lower friction animation should still be
+        // running.
+        assertTrue(animLowThreshold.isRunning());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                animLowThreshold.cancel();
+            }
+        });
+
+        assertEquals(lowThreshold, animLowThreshold.getMinimumVisibleChange(), 0f);
+        assertEquals(highThreshold, animHighThreshold.getMinimumVisibleChange(), 0f);
+
+    }
+}
diff --git a/dynamic-animation/tests/src/android/support/dynamicanimation/tests/SpringTests.java b/dynamic-animation/tests/src/android/support/dynamicanimation/tests/SpringTests.java
new file mode 100644
index 0000000..eb4eb5f
--- /dev/null
+++ b/dynamic-animation/tests/src/android/support/dynamicanimation/tests/SpringTests.java
@@ -0,0 +1,791 @@
+/*
+ * 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.dynamicanimation.tests;
+
+import static junit.framework.Assert.fail;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.AdditionalMatchers.lt;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyFloat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atMost;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.os.SystemClock;
+import android.support.animation.DynamicAnimation;
+import android.support.animation.FloatPropertyCompat;
+import android.support.animation.FloatValueHolder;
+import android.support.animation.SpringAnimation;
+import android.support.animation.SpringForce;
+import android.support.dynamicanimation.test.R;
+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.v4.view.ViewCompat;
+import android.util.AndroidRuntimeException;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SpringTests {
+    @Rule public final ActivityTestRule<AnimationActivity> mActivityTestRule;
+    public View mView1;
+    public View mView2;
+
+    @Rule
+    public ExpectedException mExpectedException = ExpectedException.none();
+
+    public SpringTests() {
+        mActivityTestRule = new ActivityTestRule<>(AnimationActivity.class);
+    }
+
+    @Before
+    public void setup() throws Exception {
+        mView1 = mActivityTestRule.getActivity().findViewById(R.id.anim_view);
+        mView2 = mActivityTestRule.getActivity().findViewById(R.id.anim_another_view);
+    }
+
+    /**
+     * Test that custom properties are supported.
+     */
+    @Test
+    public void testCustomProperties() {
+        final Object animObj = new Object();
+        FloatPropertyCompat property = new FloatPropertyCompat("") {
+            private float mValue = 0f;
+            @Override
+            public float getValue(Object object) {
+                assertEquals(animObj, object);
+                return mValue;
+            }
+
+            @Override
+            public void setValue(Object object, float value) {
+                assertEquals(animObj, object);
+                assertTrue(value >= mValue);
+                mValue = value;
+            }
+        };
+        final SpringAnimation anim = new SpringAnimation(animObj, property, 1f);
+        DynamicAnimation.OnAnimationEndListener listener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        anim.addEndListener(listener);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.start();
+            }
+        });
+        verify(listener, timeout(1000)).onAnimationEnd(anim, false, 1f, 0f);
+        assertEquals(1f, property.getValue(animObj), 0f);
+    }
+
+    /**
+     * Test that spring animation can work with a single property without an object.
+     */
+    @Test
+    public void testFloatValueHolder() {
+        final FloatValueHolder floatValueHolder = new FloatValueHolder(0f);
+        DynamicAnimation.OnAnimationUpdateListener updateListener =
+                new DynamicAnimation.OnAnimationUpdateListener() {
+            private float mLastValue = 0f;
+            @Override
+            public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
+                // New value >= value from last frame
+                assertTrue(value >= mLastValue);
+                mLastValue = value;
+                assertEquals(value, floatValueHolder.getValue(), 0f);
+            }
+        };
+
+        DynamicAnimation.OnAnimationUpdateListener mockListener =
+                mock(DynamicAnimation.OnAnimationUpdateListener.class);
+
+        final SpringAnimation anim = new SpringAnimation(floatValueHolder)
+                .addUpdateListener(updateListener).addUpdateListener(mockListener);
+        anim.setSpring(new SpringForce(1000).setDampingRatio(1.2f));
+
+        DynamicAnimation.OnAnimationEndListener listener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        anim.addEndListener(listener);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.setStartValue(0).start();
+            }
+        });
+
+        verify(mockListener, timeout(1000).atLeast(10)).onAnimationUpdate(eq(anim), lt(1000f),
+                any(float.class));
+        verify(listener, timeout(1000)).onAnimationEnd(anim, false, 1000f, 0f);
+    }
+
+
+    /**
+     * Check the final position of the default spring against what's being set through the
+     * constructor.
+     */
+    @Test
+    public void testGetFinalPosition() {
+        SpringAnimation animation = new SpringAnimation(mView1, DynamicAnimation.TRANSLATION_X, 20);
+        assertEquals(20, animation.getSpring().getFinalPosition(), 0);
+
+        SpringForce spring = new SpringForce();
+        spring.setFinalPosition(25.0f);
+        assertEquals(25.0f, spring.getFinalPosition(), 0.0f);
+    }
+
+    /**
+     * Verify that for over-damped springs, the higher the damping ratio, the slower it is. Also
+     * verify that critically damped springs finish faster than overdamped springs.
+     */
+    @Test
+    public void testDampingRatioOverAndCriticallyDamped() {
+        // Compare overdamped springs
+        final SpringAnimation anim1 = new SpringAnimation(mView1, DynamicAnimation.X, 0);
+        final SpringAnimation anim2 = new SpringAnimation(mView2, DynamicAnimation.Y, 0);
+        final SpringAnimation anim3 = new SpringAnimation(mView2, DynamicAnimation.Z, 0);
+        final DynamicAnimation.OnAnimationUpdateListener updateListener =
+                new DynamicAnimation.OnAnimationUpdateListener() {
+                    public float position1 = 1000;
+                    public float position2 = 1000;
+                    public float position3 = 1000;
+                    @Override
+                    public void onAnimationUpdate(DynamicAnimation animation, float value,
+                            float velocity) {
+                        if (animation == anim1) {
+                            position1 = value;
+                            if (position1 == 800) {
+                                // first frame
+                                assertEquals(position1, position2, 0);
+                                assertEquals(position1, position3, 0);
+                            } else {
+                                assertTrue(position2 > position1);
+                                assertTrue(position3 > position2);
+                                assertTrue(800 > position3);
+                            }
+                        } else if (animation == anim2) {
+                            position2 = value;
+                        } else {
+                            position3 = value;
+                        }
+                    }
+                };
+        final MyEndListener l1 = new MyEndListener();
+        final MyEndListener l2 = new MyEndListener();
+        final MyEndListener l3 = new MyEndListener();
+
+        final DynamicAnimation.OnAnimationEndListener mockListener =
+                mock(DynamicAnimation.OnAnimationEndListener.class);
+        anim1.getSpring().setStiffness(SpringForce.STIFFNESS_HIGH).setDampingRatio(1f);
+        anim2.getSpring().setStiffness(SpringForce.STIFFNESS_HIGH).setDampingRatio(1.5f);
+        anim3.getSpring().setStiffness(SpringForce.STIFFNESS_HIGH).setDampingRatio(2.0f);
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim2.setStartValue(800).addUpdateListener(updateListener).addEndListener(l2)
+                        .start();
+                anim3.setStartValue(800).addUpdateListener(updateListener).addEndListener(l3)
+                        .addEndListener(mockListener).start();
+                anim1.setStartValue(800).addUpdateListener(updateListener).addEndListener(l1)
+                        .start();
+
+            }
+        });
+        // The spring animation with critically-damped spring should return to rest position faster.
+        verify(mockListener, timeout(2000)).onAnimationEnd(anim3, false, 0, 0);
+        assertTrue(l1.endTime > 0);
+        assertTrue(l2.endTime > l1.endTime);
+        assertTrue(l3.endTime > l2.endTime);
+    }
+
+    /**
+     * Verify that more underdamped springs are bouncier, and that critically damped springs finish
+     * faster than underdamped springs.
+     */
+    @Test
+    public void testDampingRatioUnderDamped() {
+        final SpringAnimation anim1 = new SpringAnimation(mView1, DynamicAnimation.ROTATION, 0);
+        final SpringAnimation anim2 = new SpringAnimation(mView2, DynamicAnimation.ROTATION_X, 0);
+        final SpringAnimation anim3 = new SpringAnimation(mView2, DynamicAnimation.ROTATION_Y, 0);
+
+        final DynamicAnimation.OnAnimationUpdateListener updateListener =
+                new DynamicAnimation.OnAnimationUpdateListener() {
+                    public float bounceCount1 = 0;
+                    public float bounceCount2 = 0;
+
+                    public float velocity1 = 0;
+                    public float velocity2 = 0;
+
+                    @Override
+                    public void onAnimationUpdate(DynamicAnimation animation, float value,
+                            float velocity) {
+                        if (animation == anim1) {
+                            if (velocity > 0 && velocity1 < 0) {
+                                bounceCount1++;
+                            }
+                            velocity1 = velocity;
+                        } else if (animation == anim2) {
+                            velocity2 = velocity;
+                            if (velocity > 0 && velocity2 < 0) {
+                                bounceCount2++;
+                                assertTrue(bounceCount1 > bounceCount2);
+                            }
+                        }
+                    }
+                };
+        final MyEndListener l1 = new MyEndListener();
+        final MyEndListener l2 = new MyEndListener();
+        final MyEndListener l3 = new MyEndListener();
+
+        final DynamicAnimation.OnAnimationEndListener mockListener =
+                mock(DynamicAnimation.OnAnimationEndListener.class);
+        anim1.getSpring().setStiffness(SpringForce.STIFFNESS_MEDIUM).setDampingRatio(0.3f);
+        anim2.getSpring().setStiffness(SpringForce.STIFFNESS_MEDIUM).setDampingRatio(0.5f);
+        anim3.getSpring().setStiffness(SpringForce.STIFFNESS_MEDIUM).setDampingRatio(1f);
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim1.setStartValue(360).addUpdateListener(updateListener).addEndListener(l1)
+                        .start();
+                anim2.setStartValue(360).addUpdateListener(updateListener).addEndListener(l2)
+                        .addEndListener(mockListener).start();
+                anim3.setStartValue(360).addEndListener(l3).start();
+            }
+        });
+        // The spring animation with critically-damped spring should return to rest position faster.
+        verify(mockListener, timeout(2000)).onAnimationEnd(anim2, false, 0, 0);
+        assertFalse(anim3.isRunning());
+        assertTrue(l3.endTime > 0);
+        assertTrue(l2.endTime > l3.endTime);
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                if (anim1.isRunning()) {
+                    anim1.cancel();
+                } else {
+                    assertTrue(l1.endTime > l2.endTime);
+                }
+            }
+        });
+    }
+
+    /**
+     * Verify that stiffer spring animations finish sooner than less stiff spring animations. Run
+     * the same verification on different damping ratios.
+     */
+    @Test
+    public void testStiffness() {
+        float[] dampingRatios = {0.3f, 0.5f, 1f, 5f};
+        final float[] stiffness = {50f, 500f, 1500f, 5000f};
+        DynamicAnimation.ViewProperty[] viewProperties =
+                {DynamicAnimation.SCROLL_X, DynamicAnimation.TRANSLATION_X,
+                        DynamicAnimation.TRANSLATION_Y, DynamicAnimation.TRANSLATION_Z};
+        assertEquals(viewProperties.length, stiffness.length);
+
+        final SpringAnimation[] springAnims = new SpringAnimation[stiffness.length];
+        SpringForce[] springs = new SpringForce[stiffness.length];
+        MyEndListener[] listeners = new MyEndListener[stiffness.length];
+
+        // Sets stiffness
+        for (int i = 0; i < stiffness.length; i++) {
+            springs[i] = new SpringForce(0).setStiffness(stiffness[i]);
+            listeners[i] = new MyEndListener();
+            springAnims[i] = new SpringAnimation(mView1, viewProperties[i]).setSpring(springs[i])
+                    .addEndListener(listeners[i]);
+        }
+
+        for (int i = 0; i < dampingRatios.length; i++) {
+            for (int j = 0; j < stiffness.length; j++) {
+                springs[j].setDampingRatio(dampingRatios[i]);
+                springAnims[j].setStartValue(0).setStartVelocity(500);
+                listeners[j].endTime = -1;
+            }
+            DynamicAnimation.OnAnimationEndListener mockListener = mock(
+                    DynamicAnimation.OnAnimationEndListener.class);
+            springAnims[1].addEndListener(mockListener);
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    for (int j = 0; j < stiffness.length; j++) {
+                        springAnims[j].start();
+                    }
+                }
+            });
+
+            verify(mockListener, timeout(2000)).onAnimationEnd(springAnims[1], false, 0f, 0f);
+
+            if (springAnims[0].isRunning()) {
+                InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+                    @Override
+                    public void run() {
+                        springAnims[0].cancel();
+                    }
+                });
+            }
+            for (int j = 1; j < stiffness.length; j++) {
+                // The stiffer spring should finish no later than the less stiff spring.
+                assertTrue(listeners[j - 1].endTime > listeners[j].endTime);
+            }
+        }
+    }
+
+    /**
+     * Test negative stiffness and expect exception.
+     */
+    @Test
+    public void testInvalidStiffness() {
+        SpringForce spring = new SpringForce();
+        mExpectedException.expect(IllegalArgumentException.class);
+        spring.setStiffness(-5f);
+    }
+
+    /**
+     * Test negative dampingRatio and expect exception.
+     */
+    @Test
+    public void testInvalidDampingRatio() {
+        SpringForce spring = new SpringForce();
+        mExpectedException.expect(IllegalArgumentException.class);
+        spring.setDampingRatio(-5f);
+    }
+
+    /**
+     * Remove an update listener and an end listener, and check that there are no interaction after
+     * removal.
+     */
+    @Test
+    public void testRemoveListeners() {
+        final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0.5f);
+        DynamicAnimation.OnAnimationEndListener endListener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        DynamicAnimation.OnAnimationEndListener removedEndListener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        DynamicAnimation.OnAnimationUpdateListener updateListener = mock(
+                DynamicAnimation.OnAnimationUpdateListener.class);
+        DynamicAnimation.OnAnimationUpdateListener removedUpdateListener = mock(
+                DynamicAnimation.OnAnimationUpdateListener.class);
+
+        anim.addEndListener(removedEndListener);
+        anim.addEndListener(endListener);
+        anim.removeEndListener(removedEndListener);
+
+        anim.addUpdateListener(removedUpdateListener);
+        anim.addUpdateListener(updateListener);
+        anim.removeUpdateListener(removedUpdateListener);
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.start();
+            }
+        });
+
+        verify(endListener, timeout(1000)).onAnimationEnd(anim, false, 0.5f, 0f);
+        verify(updateListener, atLeast(2)).onAnimationUpdate(eq(anim), any(float.class),
+                any(float.class));
+
+        verifyZeroInteractions(removedEndListener);
+        verifyZeroInteractions(removedUpdateListener);
+    }
+
+    /**
+     * Verifies stiffness getter returns the right value.
+     */
+    @Test
+    public void testGetStiffness() {
+        SpringForce spring = new SpringForce();
+        spring.setStiffness(1.0f);
+        assertEquals(1.0f, spring.getStiffness(), 0.0f);
+        spring.setStiffness(2.0f);
+        assertEquals(2.0f, spring.getStiffness(), 0.0f);
+    }
+
+    /**
+     * Verifies damping ratio getter returns the right value.
+     */
+    @Test
+    public void testGetDampingRatio() {
+        SpringForce spring = new SpringForce();
+        spring.setDampingRatio(1.0f);
+        assertEquals(1.0f, spring.getDampingRatio(), 0.0f);
+        spring.setDampingRatio(2.0f);
+        assertEquals(2.0f, spring.getDampingRatio(), 0.0f);
+    }
+
+    /**
+     * Verifies that once min and max value threshold does apply to the values in animation.
+     */
+    @Test
+    public void testSetMinMax() {
+        final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.SCALE_X, 0.0f);
+        anim.setMinValue(0.0f);
+        anim.setMaxValue(1.0f);
+        anim.getSpring().setStiffness(SpringForce.STIFFNESS_HIGH).setDampingRatio(
+                SpringForce.DAMPING_RATIO_HIGH_BOUNCY);
+
+        final DynamicAnimation.OnAnimationUpdateListener mockUpdateListener = mock(
+                DynamicAnimation.OnAnimationUpdateListener.class);
+        final DynamicAnimation.OnAnimationEndListener mockEndListener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        final DynamicAnimation.OnAnimationUpdateListener updateListener =
+                new DynamicAnimation.OnAnimationUpdateListener() {
+
+            @Override
+            public void onAnimationUpdate(DynamicAnimation animation, float value, float velocity) {
+                assertTrue(value >= 0.0f);
+                assertTrue(value <= 1.0f);
+            }
+        };
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.setStartValue(1.0f).setStartVelocity(8000f)
+                        .addEndListener(mockEndListener).addUpdateListener(mockUpdateListener)
+                        .addUpdateListener(updateListener).start();
+            }});
+
+        verify(mockEndListener, timeout(2000)).onAnimationEnd(anim, false, 0f, 0f);
+        verify(mockUpdateListener, atLeast(2)).onAnimationUpdate(eq(anim), any(float.class),
+                any(float.class));
+    }
+
+    /**
+     * Verifies animateToFinalPosition works both when the anim hasn't started and when it's
+     * running.
+     */
+    @Test
+    public void testAnimateToFinalPosition() throws InterruptedException {
+        final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.SCALE_Y, 0.0f);
+        final DynamicAnimation.OnAnimationEndListener mockEndListener = mock(
+                DynamicAnimation.OnAnimationEndListener.class);
+        anim.addEndListener(mockEndListener);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.animateToFinalPosition(0.0f);
+            }
+        });
+        assertTrue(anim.isRunning());
+        Thread.sleep(100);
+        assertTrue(anim.isRunning());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.animateToFinalPosition(1.0f);
+            }
+        });
+
+        assertTrue(anim.isRunning());
+        // Verify that it indeed ends at the value from the second animateToFinalPosition() call.
+        verify(mockEndListener, timeout(1500)).onAnimationEnd(anim, false, 1.0f, 0.0f);
+    }
+
+    /**
+     * Verifies that skip to end will stop the animation, and skips the value to the end value.
+     */
+    @Test
+    public void testSkipToEnd() {
+        final float finalPosition = 10f;
+        final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.SCROLL_X,
+                finalPosition);
+        final DynamicAnimation.OnAnimationEndListener mockListener =
+                mock(DynamicAnimation.OnAnimationEndListener.class);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.addEndListener(mockListener).setStartValue(200).start();
+            }
+        });
+        assertTrue(anim.isRunning());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                int scrollX = mView1.getScrollX();
+                anim.skipToEnd();
+                // Expect no change in the animation values until next frame.
+                assertEquals(scrollX, mView1.getScrollX());
+                assertTrue(anim.isRunning());
+            }
+        });
+        verify(mockListener, timeout(100).times(1)).onAnimationEnd(anim, false, finalPosition, 0);
+
+        // Also make sure the skipToEnd() call doesn't affect next animation run.
+        final DynamicAnimation.OnAnimationEndListener mockListener2 =
+                mock(DynamicAnimation.OnAnimationEndListener.class);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.addEndListener(mockListener2);
+                anim.animateToFinalPosition(finalPosition + 1000f);
+            }
+        });
+        // Verify that the animation doesn't finish right away
+        verify(mockListener2, timeout(300).times(0)).onAnimationEnd(any(DynamicAnimation.class),
+                any(boolean.class), any(float.class), any(float.class));
+
+        // But the animation should eventually finish.
+        verify(mockListener, timeout(1000).times(1)).onAnimationEnd(anim, false,
+                finalPosition + 1000f, 0);
+
+    }
+
+    /**
+     * Check that the min visible change does affect how soon spring animations end.
+     */
+    public void testScaleMinChange() {
+        FloatValueHolder valueHolder = new FloatValueHolder(0.5f);
+        final SpringAnimation anim = new SpringAnimation(valueHolder);
+        DynamicAnimation.OnAnimationUpdateListener mockListener =
+                mock(DynamicAnimation.OnAnimationUpdateListener.class);
+        anim.addUpdateListener(mockListener);
+
+        final DynamicAnimation.OnAnimationEndListener endListener =
+                mock(DynamicAnimation.OnAnimationEndListener.class);
+        anim.addEndListener(endListener);
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.animateToFinalPosition(1f);
+            }
+        });
+
+        verify(endListener, timeout(500)).onAnimationEnd(anim, false, 0, 0);
+        verify(mockListener, atMost(5)).onAnimationUpdate(eq(anim), anyFloat(), anyFloat());
+
+        assertEquals(DynamicAnimation.MIN_VISIBLE_CHANGE_PIXELS, anim.getMinimumVisibleChange());
+
+        // Set the right threshold and start again.
+        anim.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);
+        anim.setStartValue(0.5f);
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                anim.animateToFinalPosition(1f);
+            }
+        });
+
+        verify(endListener, timeout(2000)).onAnimationEnd(anim, false, 0, 0);
+        verify(mockListener, atLeast(10)).onAnimationUpdate(eq(anim), anyFloat(), anyFloat());
+    }
+
+    /**
+     * Makes sure all the properties getter works.
+     */
+    @Test
+    public void testAllProperties() {
+        final DynamicAnimation.ViewProperty[] properties = {
+                DynamicAnimation.ALPHA, DynamicAnimation.TRANSLATION_X,
+                DynamicAnimation.TRANSLATION_Y, DynamicAnimation.TRANSLATION_Z,
+                DynamicAnimation.SCALE_X, DynamicAnimation.SCALE_Y, DynamicAnimation.ROTATION,
+                DynamicAnimation.ROTATION_X, DynamicAnimation.ROTATION_Y,
+                DynamicAnimation.X, DynamicAnimation.Y, DynamicAnimation.Z,
+                DynamicAnimation.SCROLL_X, DynamicAnimation.SCROLL_Y,
+        };
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mView1.setAlpha(0f);
+                mView1.setTranslationX(0f);
+                mView1.setTranslationY(0f);
+                ViewCompat.setTranslationZ(mView1, 0f);
+
+                mView1.setScaleX(0f);
+                mView1.setScaleY(0f);
+
+                mView1.setRotation(0f);
+                mView1.setRotationX(0f);
+                mView1.setRotationY(0f);
+
+                mView1.setX(0f);
+                mView1.setY(0f);
+                ViewCompat.setZ(mView1, 0f);
+
+                mView1.setScrollX(0);
+                mView1.setScrollY(0);
+            }
+        });
+
+        View mockView = mock(View.class);
+
+        final SpringAnimation[] anims = new SpringAnimation[properties.length];
+        final DynamicAnimation.OnAnimationUpdateListener[] mockListeners =
+                new DynamicAnimation.OnAnimationUpdateListener[properties.length];
+        for (int i = 0; i < properties.length; i++) {
+            anims[i] = new SpringAnimation(mView1, properties[i], 1);
+            final int finalI = i;
+            anims[i].addUpdateListener(
+                    new DynamicAnimation.OnAnimationUpdateListener() {
+                        boolean mIsFirstFrame = true;
+                        @Override
+                        public void onAnimationUpdate(DynamicAnimation animation, float value,
+                                float velocity) {
+                            if (mIsFirstFrame) {
+                                assertEquals(value, 0f, 0f);
+                            }
+                            mIsFirstFrame = false;
+                        }
+                    });
+            mockListeners[i] = mock(DynamicAnimation.OnAnimationUpdateListener.class);
+            anims[i].addUpdateListener(mockListeners[i]);
+        }
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = properties.length - 1; i >= 0; i--) {
+                    anims[i].start();
+                }
+            }
+        });
+
+        for (int i = 0; i < properties.length; i++) {
+            int timeout = i == 0 ? 100 : 0;
+            verify(mockListeners[i], timeout(timeout).atLeast(1)).onAnimationUpdate(
+                    any(SpringAnimation.class), any(float.class), any(float.class));
+        }
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < properties.length; i++) {
+                    anims[i].cancel();
+                }
+            }
+        });
+    }
+
+    /**
+     * Test start() on a test thread.
+     */
+    @Test
+    public void testStartOnNonMainThread() {
+        mExpectedException.expect(AndroidRuntimeException.class);
+        SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
+        anim.start();
+    }
+
+    /**
+     * Test cancel() on a test thread.
+     */
+    @Test
+    public void testCancelOnNonMainThread() {
+        mExpectedException.expect(AndroidRuntimeException.class);
+        SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
+        anim.cancel();
+    }
+
+    /**
+     * Test skipToEnd() on a test thread.
+     */
+    @Test
+    public void testSkipToEndOnNonMainThread() {
+        mExpectedException.expect(AndroidRuntimeException.class);
+        SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.ALPHA, 0f);
+        anim.skipToEnd();
+    }
+
+    /**
+     * Test invalid start condition: no spring position specified, final position > max value,
+     * and final position < min. Expect exception in all these cases.
+     */
+    @Test
+    public void testInvalidStartingCondition() {
+        final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.X);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Expect exception from not setting spring final position before calling start.
+                try {
+                    anim.start();
+                    fail("No exception is thrown when calling start() from non-main thread.");
+                } catch (UnsupportedOperationException e) {
+                }
+
+                // Expect exception from having a final position < min value
+                try {
+                    anim.setMinValue(50);
+                    // Final position < min value, expect exception.
+                    anim.setStartValue(50).animateToFinalPosition(40);
+                    fail("No exception is thrown when spring position is less than min value.");
+                } catch (UnsupportedOperationException e) {
+                }
+
+                // Expect exception from not setting spring final position before calling start.
+                try {
+                    anim.setMaxValue(60);
+                    // Final position < min value, expect exception.
+                    anim.setStartValue(60).animateToFinalPosition(70);
+                    fail("No exception is thrown when spring position is greater than max value.");
+                } catch (UnsupportedOperationException e) {
+                }
+            }
+        });
+    }
+
+    /**
+     * Try skipToEnd() on an undamped spring, and expect exception.
+     */
+    @Test
+    public void testUndampedSpring() {
+        final SpringAnimation anim = new SpringAnimation(mView1, DynamicAnimation.Y);
+        anim.setSpring(new SpringForce(10).setDampingRatio(0));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Expect exception for ending an undamped spring.
+                try {
+                    anim.skipToEnd();
+                    fail("No exception is thrown when calling skipToEnd() on an undamped spring");
+                } catch (UnsupportedOperationException e) {
+                }
+            }
+        });
+
+    }
+
+    static class MyEndListener implements DynamicAnimation.OnAnimationEndListener {
+        public long endTime = -1;
+
+        @Override
+        public void onAnimationEnd(DynamicAnimation animation, boolean canceled, float value,
+                float velocity) {
+            endTime = SystemClock.uptimeMillis();
+        }
+    }
+}
diff --git a/exifinterface/AndroidManifest.xml b/exifinterface/AndroidManifest.xml
index bacbdbe..af3dece 100644
--- a/exifinterface/AndroidManifest.xml
+++ b/exifinterface/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.exifinterface">
     <uses-sdk android:minSdkVersion="9"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/exifinterface/src/android/support/media/ExifInterface.java b/exifinterface/src/android/support/media/ExifInterface.java
index 4830ecc..d2bec3a 100644
--- a/exifinterface/src/android/support/media/ExifInterface.java
+++ b/exifinterface/src/android/support/media/ExifInterface.java
@@ -2076,7 +2076,7 @@
      * http://fileformats.archiveteam.org/wiki/Fujifilm_RAF
      */
     private boolean isRafFormat(byte[] signatureCheckBytes) throws IOException {
-        byte[] rafSignatureBytes = RAF_SIGNATURE.getBytes();
+        byte[] rafSignatureBytes = RAF_SIGNATURE.getBytes(Charset.defaultCharset());
         for (int i = 0; i < rafSignatureBytes.length; i++) {
             if (signatureCheckBytes[i] != rafSignatureBytes[i]) {
                 return false;
@@ -2734,11 +2734,11 @@
                     Log.d(TAG, "seek to data offset: " + offset);
                 }
                 if (mMimeType == IMAGE_TYPE_ORF) {
-                    if (tag.name == TAG_MAKER_NOTE) {
+                    if (TAG_MAKER_NOTE.equals(tag.name)) {
                         // Save offset value for reading thumbnail
                         mOrfMakerNoteOffset = offset;
                     } else if (ifdType == IFD_TYPE_ORF_MAKER_NOTE
-                            && tag.name == TAG_ORF_THUMBNAIL_IMAGE) {
+                            && TAG_ORF_THUMBNAIL_IMAGE.equals(tag.name)) {
                         // Retrieve & update values for thumbnail offset and length values for ORF
                         mOrfThumbnailOffset = offset;
                         mOrfThumbnailLength = numberOfComponents;
@@ -2757,7 +2757,7 @@
                                 jpegInterchangeFormatLengthAttribute);
                     }
                 } else if (mMimeType == IMAGE_TYPE_RW2) {
-                    if (tag.name == TAG_RW2_JPG_FROM_RAW) {
+                    if (TAG_RW2_JPG_FROM_RAW.equals(tag.name)) {
                         mRw2JpgFromRawOffset = offset;
                     }
                 }
@@ -2825,16 +2825,16 @@
             // DNG files have a DNG Version tag specifying the version of specifications that the
             // image file is following.
             // See http://fileformats.archiveteam.org/wiki/DNG
-            if (tag.name == TAG_DNG_VERSION) {
+            if (TAG_DNG_VERSION.equals(tag.name)) {
                 mMimeType = IMAGE_TYPE_DNG;
             }
 
             // PEF files have a Make or Model tag that begins with "PENTAX" or a compression tag
             // that is 65535.
             // See http://fileformats.archiveteam.org/wiki/Pentax_PEF
-            if (((tag.name == TAG_MAKE || tag.name == TAG_MODEL)
+            if (((TAG_MAKE.equals(tag.name) || TAG_MODEL.equals(tag.name))
                     && attribute.getStringValue(mExifByteOrder).contains(PEF_SIGNATURE))
-                    || (tag.name == TAG_COMPRESSION
+                    || (TAG_COMPRESSION.equals(tag.name)
                     && attribute.getIntValue(mExifByteOrder) == 65535)) {
                 mMimeType = IMAGE_TYPE_PEF;
             }
@@ -2971,9 +2971,9 @@
 
         if (stripOffsetsAttribute != null && stripByteCountsAttribute != null) {
             long[] stripOffsets =
-                    (long[]) stripOffsetsAttribute.getValue(mExifByteOrder);
+                    convertToLongArray(stripOffsetsAttribute.getValue(mExifByteOrder));
             long[] stripByteCounts =
-                    (long[]) stripByteCountsAttribute.getValue(mExifByteOrder);
+                    convertToLongArray(stripByteCountsAttribute.getValue(mExifByteOrder));
 
             if (stripOffsets == null) {
                 Log.w(TAG, "stripOffsets should not be null.");
@@ -3378,12 +3378,12 @@
             for (int i = 1; i < entryValues.length; ++i) {
                 final Pair<Integer, Integer> guessDataFormat = guessDataFormat(entryValues[i]);
                 int first = -1, second = -1;
-                if (guessDataFormat.first == dataFormat.first
-                        || guessDataFormat.second == dataFormat.first) {
+                if (guessDataFormat.first.equals(dataFormat.first)
+                        || guessDataFormat.second.equals(dataFormat.first)) {
                     first = dataFormat.first;
                 }
-                if (dataFormat.second != -1 && (guessDataFormat.first == dataFormat.second
-                        || guessDataFormat.second == dataFormat.second)) {
+                if (dataFormat.second != -1 && (guessDataFormat.first.equals(dataFormat.second)
+                        || guessDataFormat.second.equals(dataFormat.second))) {
                     second = dataFormat.second;
                 }
                 if (first == -1 && second == -1) {
@@ -3448,13 +3448,11 @@
         private static final ByteOrder BIG_ENDIAN = ByteOrder.BIG_ENDIAN;
 
         private DataInputStream mDataInputStream;
-        private InputStream mInputStream;
         private ByteOrder mByteOrder = ByteOrder.BIG_ENDIAN;
         private final int mLength;
         private int mPosition;
 
         public ByteOrderedDataInputStream(InputStream in) throws IOException {
-            mInputStream = in;
             mDataInputStream = new DataInputStream(in);
             mLength = mDataInputStream.available();
             mPosition = 0;
@@ -3499,6 +3497,13 @@
         }
 
         @Override
+        public int read(byte[] b, int off, int len) throws IOException {
+            int bytesRead = mDataInputStream.read(b, off, len);
+            mPosition += bytesRead;
+            return bytesRead;
+        }
+
+        @Override
         public int readUnsignedByte() throws IOException {
             ++mPosition;
             return mDataInputStream.readUnsignedByte();
@@ -3807,4 +3812,22 @@
         }
         return total;
     }
+
+    /**
+     * Convert given int[] to long[]. If long[] is given, just return it.
+     * Return null for other types of input.
+     */
+    private static long[] convertToLongArray(Object inputObj) {
+        if (inputObj instanceof int[]) {
+            int[] input = (int[]) inputObj;
+            long[] result = new long[input.length];
+            for (int i = 0; i < input.length; i++) {
+                result[i] = input[i];
+            }
+            return result;
+        } else if (inputObj instanceof long[]) {
+            return (long[]) inputObj;
+        }
+        return null;
+    }
 }
diff --git a/fragment/AndroidManifest.xml b/fragment/AndroidManifest.xml
index 9b34e14..6dcb960 100644
--- a/fragment/AndroidManifest.xml
+++ b/fragment/AndroidManifest.xml
@@ -17,6 +17,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.fragment">
     <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.fragment"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/fragment/java/android/support/v4/app/DialogFragment.java b/fragment/java/android/support/v4/app/DialogFragment.java
index baec333..dfd0416 100644
--- a/fragment/java/android/support/v4/app/DialogFragment.java
+++ b/fragment/java/android/support/v4/app/DialogFragment.java
@@ -301,12 +301,10 @@
         }
     }
 
-    /** @hide */
-    @RestrictTo(LIBRARY_GROUP)
     @Override
-    public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
+    public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
         if (!mShowsDialog) {
-            return super.getLayoutInflater(savedInstanceState);
+            return super.onGetLayoutInflater(savedInstanceState);
         }
 
         mDialog = onCreateDialog(savedInstanceState);
diff --git a/fragment/java/android/support/v4/app/Fragment.java b/fragment/java/android/support/v4/app/Fragment.java
index 06d0b1e..8c54d13 100644
--- a/fragment/java/android/support/v4/app/Fragment.java
+++ b/fragment/java/android/support/v4/app/Fragment.java
@@ -326,6 +326,10 @@
     // removal animations.
     float mPostponedAlpha;
 
+    // The cached value from onGetLayoutInflater(Bundle) that will be returned from
+    // getLayoutInflater()
+    LayoutInflater mLayoutInflater;
+
     /**
      * State information that has been retrieved from a fragment instance
      * through {@link FragmentManager#saveFragmentInstanceState(Fragment)
@@ -1120,13 +1124,66 @@
     }
 
     /**
-     * Hack so that DialogFragment can make its Dialog before creating
-     * its views, and the view construction can use the dialog's context for
-     * inflation.  Maybe this should become a public API. Note sure.
-     * @hide
+     * Returns the LayoutInflater used to inflate Views of this Fragment. The default
+     * implementation will throw an exception if the Fragment is not attached.
+     *
+     * @param savedInstanceState If the fragment is being re-created from
+     * a previous saved state, this is the state.
+     * @return The LayoutInflater used to inflate Views of this Fragment.
      */
+    public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
+        // TODO: move the implementation in getLayoutInflater to here
+        return getLayoutInflater(savedInstanceState);
+    }
+
+    /**
+     * Returns the cached LayoutInflater used to inflate Views of this Fragment. If
+     * {@link #onGetLayoutInflater(Bundle)} has not been called {@link #onGetLayoutInflater(Bundle)}
+     * will be called with a {@code null} argument and that value will be cached.
+     * <p>
+     * The cached LayoutInflater will be replaced immediately prior to
+     * {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)} and cleared immediately after
+     * {@link #onDetach()}.
+     *
+     * @return The LayoutInflater used to inflate Views of this Fragment.
+     */
+    public final LayoutInflater getLayoutInflater() {
+        if (mLayoutInflater == null) {
+            return performGetLayoutInflater(null);
+        }
+        return mLayoutInflater;
+    }
+
+    /**
+     * Calls {@link #onGetLayoutInflater(Bundle)} and caches the result for use by
+     * {@link #getLayoutInflater()}.
+     *
+     * @param savedInstanceState If the fragment is being re-created from
+     * a previous saved state, this is the state.
+     * @return The LayoutInflater used to inflate Views of this Fragment.
+     */
+    LayoutInflater performGetLayoutInflater(Bundle savedInstanceState) {
+        LayoutInflater layoutInflater = onGetLayoutInflater(savedInstanceState);
+        mLayoutInflater = layoutInflater;
+        return mLayoutInflater;
+    }
+
+    /**
+     * Override {@link #onGetLayoutInflater(Bundle)} when you need to change the
+     * LayoutInflater or call {@link #getLayoutInflater()} when you want to
+     * retrieve the current LayoutInflater.
+     *
+     * @hide
+     * @deprecated Override {@link #onGetLayoutInflater(Bundle)} or call
+     * {@link #getLayoutInflater()} instead of this method.
+     */
+    @Deprecated
     @RestrictTo(LIBRARY_GROUP)
-    public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
+    public LayoutInflater getLayoutInflater(Bundle savedFragmentState) {
+        if (mHost == null) {
+            throw new IllegalStateException("onGetLayoutInflater() cannot be executed until the "
+                    + "Fragment is attached to the FragmentManager.");
+        }
         LayoutInflater result = mHost.onGetLayoutInflater();
         getChildFragmentManager(); // Init if needed; use raw implementation below.
         LayoutInflaterCompat.setFactory(result, mChildFragmentManager.getLayoutInflaterFactory());
@@ -1393,8 +1450,7 @@
             if (!mCheckedForLoaderManager) {
                 mCheckedForLoaderManager = true;
                 mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
-            }
-            if (mLoaderManager != null) {
+            } else if (mLoaderManager != null) {
                 mLoaderManager.doStart();
             }
         }
@@ -2246,6 +2302,12 @@
         }
     }
 
+    void noteStateNotSaved() {
+        if (mChildFragmentManager != null) {
+            mChildFragmentManager.noteStateNotSaved();
+        }
+    }
+
     void performMultiWindowModeChanged(boolean isInMultiWindowMode) {
         onMultiWindowModeChanged(isInMultiWindowMode);
         if (mChildFragmentManager != null) {
@@ -2442,6 +2504,7 @@
     void performDetach() {
         mCalled = false;
         onDetach();
+        mLayoutInflater = null;
         if (!mCalled) {
             throw new SuperNotCalledException("Fragment " + this
                     + " did not call through to super.onDetach()");
diff --git a/fragment/java/android/support/v4/app/FragmentController.java b/fragment/java/android/support/v4/app/FragmentController.java
index 7894437..48b3602 100644
--- a/fragment/java/android/support/v4/app/FragmentController.java
+++ b/fragment/java/android/support/v4/app/FragmentController.java
@@ -29,7 +29,6 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -78,22 +77,14 @@
      * Returns the number of active fragments.
      */
     public int getActiveFragmentsCount() {
-        final List<Fragment> actives = mHost.mFragmentManager.mActive;
-        return actives == null ? 0 : actives.size();
+        return mHost.mFragmentManager.getActiveFragmentCount();
     }
 
     /**
      * Returns the list of active fragments.
      */
     public List<Fragment> getActiveFragments(List<Fragment> actives) {
-        if (mHost.mFragmentManager.mActive == null) {
-            return null;
-        }
-        if (actives == null) {
-            actives = new ArrayList<Fragment>(getActiveFragmentsCount());
-        }
-        actives.addAll(mHost.mFragmentManager.mActive);
-        return actives;
+        return mHost.mFragmentManager.getActiveFragments();
     }
 
     /**
diff --git a/fragment/java/android/support/v4/app/FragmentHostCallback.java b/fragment/java/android/support/v4/app/FragmentHostCallback.java
index fa51ccd..115425c 100644
--- a/fragment/java/android/support/v4/app/FragmentHostCallback.java
+++ b/fragment/java/android/support/v4/app/FragmentHostCallback.java
@@ -308,6 +308,8 @@
         if (lm == null && create) {
             lm = new LoaderManagerImpl(who, this, started);
             mAllLoaderManagers.put(who, lm);
+        } else if (started && lm != null && !lm.mStarted) {
+            lm.doStart();
         }
         return lm;
     }
@@ -348,7 +350,8 @@
 
     void restoreLoaderNonConfig(SimpleArrayMap<String, LoaderManager> loaderManagers) {
         if (loaderManagers != null) {
-            for (int i = 0, N = loaderManagers.size(); i < N; i++) {
+            final int numLoaderManagers = loaderManagers.size();
+            for (int i = 0; i < numLoaderManagers; i++) {
                 ((LoaderManagerImpl) loaderManagers.valueAt(i)).updateHostController(this);
             }
         }
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/java/android/support/v4/app/FragmentManager.java
index 58c0dd0..5f618bb 100644
--- a/fragment/java/android/support/v4/app/FragmentManager.java
+++ b/fragment/java/android/support/v4/app/FragmentManager.java
@@ -62,6 +62,7 @@
 import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -327,12 +328,16 @@
     public abstract Fragment getFragment(Bundle bundle, String key);
 
     /**
-     * Get a list of all fragments that have been added to the fragment manager.
+     * Get a list of all fragments that are currently added to the FragmentManager.
+     * This may include those that are hidden as well as those that are shown.
+     * This will not include any fragments only in the back stack, or fragments that
+     * are detached or removed.
+     * <p>
+     * The order of the fragments in the list is the order in which they were
+     * added or attached.
      *
-     * @return The list of all fragments or null if none.
-     * @hide
+     * @return A list of all fragments that are added to the FragmentManager.
      */
-    @RestrictTo(LIBRARY_GROUP)
     public abstract List<Fragment> getFragments();
 
     /**
@@ -544,6 +549,7 @@
     FragmentState[] mActive;
     int[] mAdded;
     BackStackState[] mBackStack;
+    int mNextFragmentIndex;
 
     public FragmentManagerState() {
     }
@@ -552,6 +558,7 @@
         mActive = in.createTypedArray(FragmentState.CREATOR);
         mAdded = in.createIntArray();
         mBackStack = in.createTypedArray(BackStackState.CREATOR);
+        mNextFragmentIndex = in.readInt();
     }
 
     @Override
@@ -564,6 +571,7 @@
         dest.writeTypedArray(mActive, flags);
         dest.writeIntArray(mAdded);
         dest.writeTypedArray(mBackStack, flags);
+        dest.writeInt(mNextFragmentIndex);
     }
 
     public static final Parcelable.Creator<FragmentManagerState> CREATOR
@@ -663,12 +671,12 @@
     }
 
     ArrayList<OpGenerator> mPendingActions;
-    Runnable[] mTmpActions;
     boolean mExecutingActions;
 
-    ArrayList<Fragment> mActive;
+    int mNextFragmentIndex = 0;
+
     ArrayList<Fragment> mAdded;
-    ArrayList<Integer> mAvailIndices;
+    SparseArray<Fragment> mActive;
     ArrayList<BackStackRecord> mBackStack;
     ArrayList<Fragment> mCreatedMenus;
 
@@ -827,6 +835,7 @@
         }
 
         doPendingDeferredStart();
+        burpActive();
         return executePop;
     }
 
@@ -870,10 +879,6 @@
         if (index == -1) {
             return null;
         }
-        if (index >= mActive.size()) {
-            throwException(new IllegalStateException("Fragment no longer exists for key "
-                    + key + ": index " + index));
-        }
         Fragment f = mActive.get(index);
         if (f == null) {
             throwException(new IllegalStateException("Fragment no longer exists for key "
@@ -884,7 +889,42 @@
 
     @Override
     public List<Fragment> getFragments() {
-        return mActive;
+        if (mAdded == null) {
+            return Collections.EMPTY_LIST;
+        }
+        synchronized (mAdded) {
+            return (List<Fragment>) mAdded.clone();
+        }
+    }
+
+    /**
+     * This is used by FragmentController to get the Active fragments.
+     *
+     * @return A list of active fragments in the fragment manager, including those that are in the
+     * back stack.
+     */
+    List<Fragment> getActiveFragments() {
+        if (mActive == null) {
+            return null;
+        }
+        final int count = mActive.size();
+        ArrayList<Fragment> fragments = new ArrayList<>(count);
+        for (int i = 0; i < count; i++) {
+            fragments.add(mActive.valueAt(i));
+        }
+        return fragments;
+    }
+
+    /**
+     * Used by FragmentController to get the number of Active Fragments.
+     *
+     * @return The number of active fragments.
+     */
+    int getActiveFragmentCount() {
+        if (mActive == null) {
+            return 0;
+        }
+        return mActive.size();
     }
 
     @Override
@@ -932,7 +972,7 @@
                         writer.print(Integer.toHexString(System.identityHashCode(this)));
                         writer.println(":");
                 for (int i=0; i<N; i++) {
-                    Fragment f = mActive.get(i);
+                    Fragment f = mActive.valueAt(i);
                     writer.print(prefix); writer.print("  #"); writer.print(i);
                             writer.print(": "); writer.println(f);
                     if (f != null) {
@@ -1027,10 +1067,6 @@
             writer.print(prefix); writer.print("  mNoTransactionsBecause=");
                     writer.println(mNoTransactionsBecause);
         }
-        if (mAvailIndices != null && mAvailIndices.size() > 0) {
-            writer.print(prefix); writer.print("  mAvailIndices: ");
-                    writer.println(Arrays.toString(mAvailIndices.toArray()));
-        }
     }
 
     static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f);
@@ -1177,8 +1213,13 @@
             newState = Fragment.CREATED;
         }
         if (f.mRemoving && newState > f.mState) {
-            // While removing a fragment, we can't change it to a higher state.
-            newState = f.mState;
+            if (f.mState == Fragment.INITIALIZING && f.isInBackStack()) {
+                // Allow the fragment to be created so that it can be saved later.
+                newState = Fragment.CREATED;
+            } else {
+                // While removing a fragment, we can't change it to a higher state.
+                newState = f.mState;
+            }
         }
         // Defer start if requested; don't allow it to move to STARTED or higher
         // if it's not already started.
@@ -1252,7 +1293,7 @@
                         // 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.mView = f.performCreateView(f.performGetLayoutInflater(
                                 f.mSavedFragmentState), null, f.mSavedFragmentState);
                         if (f.mView != null) {
                             f.mInnerView = f.mView;
@@ -1296,7 +1337,7 @@
                                 }
                             }
                             f.mContainer = container;
-                            f.mView = f.performCreateView(f.getLayoutInflater(
+                            f.mView = f.performCreateView(f.performGetLayoutInflater(
                                     f.mSavedFragmentState), container, f.mSavedFragmentState);
                             if (f.mView != null) {
                                 f.mInnerView = f.mView;
@@ -1603,7 +1644,7 @@
             // and detached.
             final int numActive = mActive.size();
             for (int i = 0; i < numActive; i++) {
-                Fragment f = mActive.get(i);
+                Fragment f = mActive.valueAt(i);
                 if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
                     moveFragmentToExpectedState(f);
                     if (f.mLoaderManager != null) {
@@ -1627,7 +1668,7 @@
         if (mActive == null) return;
 
         for (int i=0; i<mActive.size(); i++) {
-            Fragment f = mActive.get(i);
+            Fragment f = mActive.valueAt(i);
             if (f != null) {
                 performPendingDeferredStart(f);
             }
@@ -1639,17 +1680,11 @@
             return;
         }
 
-        if (mAvailIndices == null || mAvailIndices.size() <= 0) {
-            if (mActive == null) {
-                mActive = new ArrayList<Fragment>();
-            }
-            f.setIndex(mActive.size(), mParent);
-            mActive.add(f);
-
-        } else {
-            f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent);
-            mActive.set(f.mIndex, f);
+        f.setIndex(mNextFragmentIndex++, mParent);
+        if (mActive == null) {
+            mActive = new SparseArray<>();
         }
+        mActive.put(f.mIndex, f);
         if (DEBUG) Log.v(TAG, "Allocated fragment index " + f);
     }
 
@@ -1659,11 +1694,10 @@
         }
 
         if (DEBUG) Log.v(TAG, "Freeing fragment index " + f);
-        mActive.set(f.mIndex, null);
-        if (mAvailIndices == null) {
-            mAvailIndices = new ArrayList<Integer>();
-        }
-        mAvailIndices.add(f.mIndex);
+        // Don't remove yet. That happens in burpActive(). This prevents
+        // concurrent modification while iterating over mActive
+        mActive.put(f.mIndex, null);
+
         mHost.inactivateFragment(f.mWho);
         f.initState();
     }
@@ -1678,7 +1712,9 @@
             if (mAdded.contains(fragment)) {
                 throw new IllegalStateException("Fragment already added: " + fragment);
             }
-            mAdded.add(fragment);
+            synchronized (mAdded) {
+                mAdded.add(fragment);
+            }
             fragment.mAdded = true;
             fragment.mRemoving = false;
             if (fragment.mView == null) {
@@ -1698,7 +1734,9 @@
         final boolean inactive = !fragment.isInBackStack();
         if (!fragment.mDetached || inactive) {
             if (mAdded != null) {
-                mAdded.remove(fragment);
+                synchronized (mAdded) {
+                    mAdded.remove(fragment);
+                }
             }
             if (fragment.mHasMenu && fragment.mMenuVisible) {
                 mNeedMenuInvalidate = true;
@@ -1748,7 +1786,9 @@
                 // We are not already in back stack, so need to remove the fragment.
                 if (mAdded != null) {
                     if (DEBUG) Log.v(TAG, "remove from detach: " + fragment);
-                    mAdded.remove(fragment);
+                    synchronized (mAdded) {
+                        mAdded.remove(fragment);
+                    }
                 }
                 if (fragment.mHasMenu && fragment.mMenuVisible) {
                     mNeedMenuInvalidate = true;
@@ -1770,7 +1810,9 @@
                     throw new IllegalStateException("Fragment already added: " + fragment);
                 }
                 if (DEBUG) Log.v(TAG, "add from attach: " + fragment);
-                mAdded.add(fragment);
+                synchronized (mAdded) {
+                    mAdded.add(fragment);
+                }
                 fragment.mAdded = true;
                 if (fragment.mHasMenu && fragment.mMenuVisible) {
                     mNeedMenuInvalidate = true;
@@ -1793,7 +1835,7 @@
         if (mActive != null) {
             // Now for any known fragment.
             for (int i=mActive.size()-1; i>=0; i--) {
-                Fragment f = mActive.get(i);
+                Fragment f = mActive.valueAt(i);
                 if (f != null && f.mFragmentId == id) {
                     return f;
                 }
@@ -1816,7 +1858,7 @@
         if (mActive != null && tag != null) {
             // Now for any known fragment.
             for (int i=mActive.size()-1; i>=0; i--) {
-                Fragment f = mActive.get(i);
+                Fragment f = mActive.valueAt(i);
                 if (f != null && tag.equals(f.mTag)) {
                     return f;
                 }
@@ -1828,7 +1870,7 @@
     public Fragment findFragmentByWho(String who) {
         if (mActive != null && who != null) {
             for (int i=mActive.size()-1; i>=0; i--) {
-                Fragment f = mActive.get(i);
+                Fragment f = mActive.valueAt(i);
                 if (f != null && (f=f.findFragmentByWho(who)) != null) {
                     return f;
                 }
@@ -1861,6 +1903,10 @@
         }
         synchronized (this) {
             if (mDestroyed || mHost == null) {
+                if (allowStateLoss) {
+                    // This FragmentManager isn't attached, so drop the entire transaction.
+                    return;
+                }
                 throw new IllegalStateException("Activity has been destroyed");
             }
             if (mPendingActions == null) {
@@ -1977,6 +2023,10 @@
     }
 
     public void execSingleAction(OpGenerator action, boolean allowStateLoss) {
+        if (allowStateLoss && (mHost == null || mDestroyed)) {
+            // This FragmentManager isn't attached, so drop the entire transaction.
+            return;
+        }
         ensureExecReady(allowStateLoss);
         if (action.generateOps(mTmpRecords, mTmpIsPop)) {
             mExecutingActions = true;
@@ -1988,6 +2038,7 @@
         }
 
         doPendingDeferredStart();
+        burpActive();
     }
 
     /**
@@ -2018,6 +2069,7 @@
         }
 
         doPendingDeferredStart();
+        burpActive();
 
         return didSomething;
     }
@@ -2286,7 +2338,7 @@
             for (int i = 0; i < numActive; i++) {
                 // Allow added fragments to be removed during the pop since we aren't going
                 // to move them to the final state with moveToState(mCurState).
-                Fragment fragment = mActive.get(i);
+                Fragment fragment = mActive.valueAt(i);
                 if (fragment != null && fragment.mView != null && fragment.mIsNewlyAdded
                         && record.interactsWith(fragment.mContainerId)) {
                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
@@ -2408,7 +2460,7 @@
     private void endAnimatingAwayFragments() {
         final int numFragments = mActive == null ? 0 : mActive.size();
         for (int i = 0; i < numFragments; i++) {
-            Fragment fragment = mActive.get(i);
+            Fragment fragment = mActive.valueAt(i);
             if (fragment != null && fragment.getAnimatingAway() != null) {
                 // Give up waiting for the animation and just end it.
                 final int stateAfterAnimating = fragment.getStateAfterAnimating();
@@ -2417,6 +2469,9 @@
                 Animation animation = animatingAway.getAnimation();
                 if (animation != null) {
                     animation.cancel();
+                    // force-clear the animation, as Animation#cancel() doesn't work prior to N,
+                    // and will instead cause the animation to infinitely loop
+                    animatingAway.clearAnimation();
                 }
                 moveToState(fragment, stateAfterAnimating, 0, 0, false);
             }
@@ -2455,7 +2510,7 @@
         if (mHavePendingDeferredStart) {
             boolean loadersRunning = false;
             for (int i = 0; i < mActive.size(); i++) {
-                Fragment f = mActive.get(i);
+                Fragment f = mActive.valueAt(i);
                 if (f != null && f.mLoaderManager != null) {
                     loadersRunning |= f.mLoaderManager.hasRunningLoaders();
                 }
@@ -2480,7 +2535,6 @@
             mBackStack = new ArrayList<BackStackRecord>();
         }
         mBackStack.add(state);
-        reportBackStackChanged();
     }
 
     @SuppressWarnings("unused")
@@ -2545,7 +2599,7 @@
         ArrayList<FragmentManagerNonConfig> childFragments = null;
         if (mActive != null) {
             for (int i=0; i<mActive.size(); i++) {
-                Fragment f = mActive.get(i);
+                Fragment f = mActive.valueAt(i);
                 if (f != null) {
                     if (f.mRetainInstance) {
                         if (fragments == null) {
@@ -2661,7 +2715,7 @@
         FragmentState[] active = new FragmentState[N];
         boolean haveFragments = false;
         for (int i=0; i<N; i++) {
-            Fragment f = mActive.get(i);
+            Fragment f = mActive.valueAt(i);
             if (f != null) {
                 if (f.mIndex < 0) {
                     throwException(new IllegalStateException(
@@ -2747,6 +2801,7 @@
         fms.mActive = active;
         fms.mAdded = added;
         fms.mBackStack = backStack;
+        fms.mNextFragmentIndex = mNextFragmentIndex;
         return fms;
     }
 
@@ -2768,7 +2823,15 @@
             for (int i = 0; i < count; i++) {
                 Fragment f = nonConfigFragments.get(i);
                 if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f);
-                FragmentState fs = fms.mActive[f.mIndex];
+                int index = 0; // index into fms.mActive
+                while (index < fms.mActive.length && fms.mActive[index].mIndex != f.mIndex) {
+                    index++;
+                }
+                if (index == fms.mActive.length) {
+                    throwException(new IllegalStateException("Could not find active fragment "
+                            + "with index " + f.mIndex));
+                }
+                FragmentState fs = fms.mActive[index];
                 fs.mInstance = f;
                 f.mSavedViewState = null;
                 f.mBackStackNesting = 0;
@@ -2786,10 +2849,7 @@
 
         // Build the full list of active fragments, instantiating them from
         // their saved state.
-        mActive = new ArrayList<>(fms.mActive.length);
-        if (mAvailIndices != null) {
-            mAvailIndices.clear();
-        }
+        mActive = new SparseArray<>(fms.mActive.length);
         for (int i=0; i<fms.mActive.length; i++) {
             FragmentState fs = fms.mActive[i];
             if (fs != null) {
@@ -2799,18 +2859,11 @@
                 }
                 Fragment f = fs.instantiate(mHost, mParent, childNonConfig);
                 if (DEBUG) Log.v(TAG, "restoreAllState: active #" + i + ": " + f);
-                mActive.add(f);
+                mActive.put(f.mIndex, f);
                 // Now that the fragment is instantiated (or came from being
                 // retained above), clear mInstance in case we end up re-restoring
                 // from this FragmentState again.
                 fs.mInstance = null;
-            } else {
-                mActive.add(null);
-                if (mAvailIndices == null) {
-                    mAvailIndices = new ArrayList<Integer>();
-                }
-                if (DEBUG) Log.v(TAG, "restoreAllState: avail #" + i);
-                mAvailIndices.add(i);
             }
         }
 
@@ -2821,12 +2874,10 @@
             for (int i = 0; i < count; i++) {
                 Fragment f = nonConfigFragments.get(i);
                 if (f.mTargetIndex >= 0) {
-                    if (f.mTargetIndex < mActive.size()) {
-                        f.mTarget = mActive.get(f.mTargetIndex);
-                    } else {
+                    f.mTarget = mActive.get(f.mTargetIndex);
+                    if (f.mTarget == null) {
                         Log.w(TAG, "Re-attaching retained fragment " + f
                                 + " target no longer exists: " + f.mTargetIndex);
-                        f.mTarget = null;
                     }
                 }
             }
@@ -2846,7 +2897,9 @@
                 if (mAdded.contains(f)) {
                     throw new IllegalStateException("Already added!");
                 }
-                mAdded.add(f);
+                synchronized (mAdded) {
+                    mAdded.add(f);
+                }
             }
         } else {
             mAdded = null;
@@ -2873,6 +2926,23 @@
         } else {
             mBackStack = null;
         }
+
+        this.mNextFragmentIndex = fms.mNextFragmentIndex;
+    }
+
+    /**
+     * To prevent list modification errors, mActive sets values to null instead of
+     * removing them when the Fragment becomes inactive. This cleans up the list at the
+     * end of executing the transactions.
+     */
+    private void burpActive() {
+        if (mActive != null) {
+            for (int i = mActive.size() - 1; i >= 0; i--) {
+                if (mActive.valueAt(i) == null) {
+                    mActive.delete(mActive.keyAt(i));
+                }
+            }
+        }
     }
 
     public void attachController(FragmentHostCallback host,
@@ -2885,6 +2955,13 @@
 
     public void noteStateNotSaved() {
         mStateSaved = false;
+        final int addedCount = mAdded == null ? 0 : mAdded.size();
+        for (int i = 0; i < addedCount; i++) {
+            Fragment fragment = mAdded.get(i);
+            if (fragment != null) {
+                fragment.noteStateNotSaved();
+            }
+        }
     }
 
     public void dispatchCreate() {
diff --git a/fragment/java/android/support/v4/app/FragmentTransition.java b/fragment/java/android/support/v4/app/FragmentTransition.java
index 5e0d9e3..f93a5c3 100644
--- a/fragment/java/android/support/v4/app/FragmentTransition.java
+++ b/fragment/java/android/support/v4/app/FragmentTransition.java
@@ -759,7 +759,9 @@
             names = inTransaction.mSharedElementTargetNames;
         }
 
-        inSharedElements.retainAll(names);
+        if (names != null) {
+            inSharedElements.retainAll(names);
+        }
         if (sharedElementCallback != null) {
             sharedElementCallback.onMapSharedElements(names, inSharedElements);
             for (int i = names.size() - 1; i >= 0; i--) {
@@ -809,7 +811,8 @@
             FragmentContainerTransition fragments,
             Object enterTransition, boolean inIsPop) {
         BackStackRecord inTransaction = fragments.lastInTransaction;
-        if (enterTransition != null && inTransaction.mSharedElementSourceNames != null
+        if (enterTransition != null && inSharedElements != null
+                && inTransaction.mSharedElementSourceNames != null
                 && !inTransaction.mSharedElementSourceNames.isEmpty()) {
             final String targetName = inIsPop
                     ? inTransaction.mSharedElementSourceNames.get(0)
@@ -898,7 +901,9 @@
         if (transition != null) {
             viewList = new ArrayList<>();
             View root = fragment.getView();
-            FragmentTransitionCompat21.captureTransitioningViews(viewList, root);
+            if (root != null) {
+                FragmentTransitionCompat21.captureTransitioningViews(viewList, root);
+            }
             if (sharedElements != null) {
                 viewList.removeAll(sharedElements);
             }
diff --git a/fragment/java/android/support/v4/app/LoaderManager.java b/fragment/java/android/support/v4/app/LoaderManager.java
index 72718ae..521b218 100644
--- a/fragment/java/android/support/v4/app/LoaderManager.java
+++ b/fragment/java/android/support/v4/app/LoaderManager.java
@@ -839,6 +839,7 @@
             mInactiveLoaders.valueAt(i).destroy();
         }
         mInactiveLoaders.clear();
+        mHost = null;
     }
 
     @Override
diff --git a/fragment/tests/AndroidManifest.xml b/fragment/tests/AndroidManifest.xml
index 9cab8ca..b442c85 100644
--- a/fragment/tests/AndroidManifest.xml
+++ b/fragment/tests/AndroidManifest.xml
@@ -37,6 +37,11 @@
         <activity android:name="android.support.v4.app.test.EmptyFragmentTestActivity" />
 
         <activity android:name="android.support.v4.app.test.FragmentResultActivity" />
+
+        <activity android:name="android.support.v4.app.test.LoaderActivity" />
+
+        <activity android:name="android.support.v4.app.test.NewIntentActivity"
+                  android:launchMode="singleInstance" />
     </application>
 
     <instrumentation android:name="android.test.InstrumentationTestRunner"
diff --git a/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java b/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
index c9d7351a..f19adb9 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentLifecycleTest.java
@@ -684,6 +684,90 @@
         assertTrue(activity.onDestroyLatch.await(1000, TimeUnit.MILLISECONDS));
     }
 
+    /**
+     * When a fragment is saved in non-config, it should be restored to the same index.
+     */
+    @Test
+    @UiThreadTest
+    public void restoreNonConfig() throws Throwable {
+        FragmentController fc = FragmentTestUtil.createController(mActivityRule);
+        FragmentTestUtil.resume(mActivityRule, fc, null);
+        FragmentManager fm = fc.getSupportFragmentManager();
+
+        Fragment fragment1 = new StrictFragment();
+        fm.beginTransaction()
+                .add(fragment1, "1")
+                .addToBackStack(null)
+                .commit();
+        fm.executePendingTransactions();
+        Fragment fragment2 = new StrictFragment();
+        fragment2.setRetainInstance(true);
+        fragment2.setTargetFragment(fragment1, 0);
+        Fragment fragment3 = new StrictFragment();
+        fm.beginTransaction()
+                .remove(fragment1)
+                .add(fragment2, "2")
+                .add(fragment3, "3")
+                .addToBackStack(null)
+                .commit();
+        fm.executePendingTransactions();
+
+        Pair<Parcelable, FragmentManagerNonConfig> savedState =
+                FragmentTestUtil.destroy(mActivityRule, fc);
+
+        fc = FragmentTestUtil.createController(mActivityRule);
+        FragmentTestUtil.resume(mActivityRule, fc, savedState);
+        boolean foundFragment2 = false;
+        for (Fragment fragment : fc.getSupportFragmentManager().getFragments()) {
+            if (fragment == fragment2) {
+                foundFragment2 = true;
+                assertNotNull(fragment.getTargetFragment());
+                assertEquals("1", fragment.getTargetFragment().getTag());
+            } else {
+                assertNotEquals("2", fragment.getTag());
+            }
+        }
+        assertTrue(foundFragment2);
+    }
+
+    /**
+     * When a fragment has been optimized out, it state should still be saved during
+     * save and restore instance state.
+     */
+    @Test
+    @UiThreadTest
+    public void saveRemovedFragment() throws Throwable {
+        FragmentController fc = FragmentTestUtil.createController(mActivityRule);
+        FragmentTestUtil.resume(mActivityRule, fc, null);
+        FragmentManager fm = fc.getSupportFragmentManager();
+
+        SaveStateFragment fragment1 = SaveStateFragment.create(1);
+        fm.beginTransaction()
+                .add(android.R.id.content, fragment1, "1")
+                .addToBackStack(null)
+                .commit();
+        SaveStateFragment fragment2 = SaveStateFragment.create(2);
+        fm.beginTransaction()
+                .replace(android.R.id.content, fragment2, "2")
+                .addToBackStack(null)
+                .commit();
+        fm.executePendingTransactions();
+
+        Pair<Parcelable, FragmentManagerNonConfig> savedState =
+                FragmentTestUtil.destroy(mActivityRule, fc);
+
+        fc = FragmentTestUtil.createController(mActivityRule);
+        FragmentTestUtil.resume(mActivityRule, fc, savedState);
+        fm = fc.getSupportFragmentManager();
+        fragment2 = (SaveStateFragment) fm.findFragmentByTag("2");
+        assertNotNull(fragment2);
+        assertEquals(2, fragment2.getValue());
+        fm.popBackStackImmediate();
+        fragment1 = (SaveStateFragment) fm.findFragmentByTag("1");
+        assertNotNull(fragment1);
+        assertEquals(1, fragment1.getValue());
+    }
+
     private void assertAnimationsMatch(FragmentManager fm, int enter, int exit, int popEnter,
             int popExit) {
         FragmentManagerImpl fmImpl = (FragmentManagerImpl) fm;
@@ -950,4 +1034,33 @@
             return fragment;
         }
     }
+
+    public static class SaveStateFragment extends Fragment {
+        private static final String VALUE_KEY = "SaveStateFragment.mValue";
+        private int mValue;
+
+        public static SaveStateFragment create(int value) {
+            SaveStateFragment saveStateFragment = new SaveStateFragment();
+            saveStateFragment.mValue = value;
+            return saveStateFragment;
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+            super.onSaveInstanceState(outState);
+            outState.putInt(VALUE_KEY, mValue);
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            if (savedInstanceState != null) {
+                mValue = savedInstanceState.getInt(VALUE_KEY, mValue);
+            }
+        }
+
+        public int getValue() {
+            return mValue;
+        }
+    }
 }
diff --git a/fragment/tests/java/android/support/v4/app/FragmentOptimizationTest.java b/fragment/tests/java/android/support/v4/app/FragmentOptimizationTest.java
index 13901c4..c2fb8bc 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentOptimizationTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentOptimizationTest.java
@@ -190,7 +190,7 @@
         assertEquals(1, fragment1.onHideCount);
         assertEquals(0, fragment1.onShowCount);
         assertEquals(0, fragment1.onDetachCount);
-        assertEquals(0, fragment1.onAttachCount);
+        assertEquals(1, fragment1.onAttachCount);
 
         FragmentTestUtil.popBackStackImmediate(mActivityRule, id[0],
                 FragmentManager.POP_BACK_STACK_INCLUSIVE);
@@ -198,8 +198,8 @@
         assertEquals(0, fragment1.onCreateViewCount);
         assertEquals(1, fragment1.onHideCount);
         assertEquals(1, fragment1.onShowCount);
-        assertEquals(0, fragment1.onDetachCount);
-        assertEquals(0, fragment1.onAttachCount);
+        assertEquals(1, fragment1.onDetachCount);
+        assertEquals(1, fragment1.onAttachCount);
     }
 
     // Ensure that removing and adding the same view results in no operation
diff --git a/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java b/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
index a37b82e..9ee0c48 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentTestUtil.java
@@ -30,6 +30,9 @@
 import android.view.ViewGroup;
 import android.view.animation.Animation;
 
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
 public class FragmentTestUtil {
     private static final Runnable DO_NOTHING = new Runnable() {
         @Override
@@ -64,14 +67,18 @@
     }
 
     public static boolean executePendingTransactions(
-            final ActivityTestRule<FragmentTestActivity> rule) {
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+            final ActivityTestRule<? extends FragmentActivity> rule) {
+        FragmentManager fragmentManager = rule.getActivity().getSupportFragmentManager();
+        return executePendingTransactions(rule, fragmentManager);
+    }
+
+    public static boolean executePendingTransactions(
+            final ActivityTestRule<? extends Activity> rule, final FragmentManager fm) {
         final boolean[] ret = new boolean[1];
-        instrumentation.runOnMainSync(new Runnable() {
+        runOnUiThreadRethrow(rule, new Runnable() {
             @Override
             public void run() {
-                ret[0] =
-                        rule.getActivity().getSupportFragmentManager().executePendingTransactions();
+                ret[0] = fm.executePendingTransactions();
             }
         });
         return ret[0];
@@ -138,9 +145,10 @@
         }
     }
 
-    public static FragmentController createController(ActivityTestRule<FragmentTestActivity> rule) {
+    public static FragmentController createController(
+            ActivityTestRule<? extends FragmentActivity> rule) {
         final FragmentController[] controller = new FragmentController[1];
-        final FragmentTestActivity activity = rule.getActivity();
+        final FragmentActivity activity = rule.getActivity();
         runOnUiThreadRethrow(rule, new Runnable() {
             @Override
             public void run() {
@@ -211,4 +219,21 @@
         } while (!hasEnded[0] && SystemClock.uptimeMillis() < endTime);
         return hasEnded[0];
     }
+
+    /**
+     * Allocates until a garbage collection occurs.
+     */
+    public static void forceGC() {
+        // Do it twice so that we know we're not in the middle of the first collection when
+        // returning.
+        for (int i = 0; i < 2; i++) {
+            // Use a random index in the list to detect the garbage collection each time because
+            // .get() may accidentally trigger a strong reference during collection.
+            ArrayList<WeakReference<byte[]>> leak = new ArrayList<>();
+            do {
+                WeakReference<byte[]> arr = new WeakReference<byte[]>(new byte[100]);
+                leak.add(arr);
+            } while (leak.get((int) (Math.random() * leak.size())).get() != null);
+        }
+    }
 }
diff --git a/fragment/tests/java/android/support/v4/app/FragmentTransactionTest.java b/fragment/tests/java/android/support/v4/app/FragmentTransactionTest.java
index 117ca9d..60f93fd 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentTransactionTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentTransactionTest.java
@@ -18,18 +18,37 @@
 import static junit.framework.TestCase.assertFalse;
 import static junit.framework.TestCase.assertTrue;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.support.annotation.Nullable;
 import android.support.fragment.test.R;
 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.v4.app.test.FragmentTestActivity;
+import android.support.v4.app.test.NewIntentActivity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Collection;
+import java.util.concurrent.TimeUnit;
+
 /**
  * Tests usage of the {@link FragmentTransaction} class.
  */
@@ -42,10 +61,28 @@
             new ActivityTestRule<>(FragmentTestActivity.class);
 
     private FragmentTestActivity mActivity;
+    private int mOnBackStackChangedTimes;
+    private FragmentManager.OnBackStackChangedListener mOnBackStackChangedListener;
 
     @Before
     public void setUp() {
         mActivity = mActivityRule.getActivity();
+        mOnBackStackChangedTimes = 0;
+        mOnBackStackChangedListener = new FragmentManager.OnBackStackChangedListener() {
+            @Override
+            public void onBackStackChanged() {
+                mOnBackStackChangedTimes++;
+            }
+        };
+        mActivity.getSupportFragmentManager()
+                .addOnBackStackChangedListener(mOnBackStackChangedListener);
+    }
+
+    @After
+    public void tearDown() {
+        mActivity.getSupportFragmentManager()
+                .removeOnBackStackChangedListener(mOnBackStackChangedListener);
+        mOnBackStackChangedListener = null;
     }
 
     @Test
@@ -59,6 +96,7 @@
                         .addToBackStack(null)
                         .commit();
                 mActivity.getSupportFragmentManager().executePendingTransactions();
+                assertEquals(1, mOnBackStackChangedTimes);
             }
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
@@ -78,6 +116,7 @@
                             .addToBackStack(null)
                             .commit();
                     mActivity.getSupportFragmentManager().executePendingTransactions();
+                    assertEquals(1, mOnBackStackChangedTimes);
                 } catch (IllegalStateException e) {
                     exceptionThrown = true;
                 } finally {
@@ -102,6 +141,7 @@
                             .addToBackStack(null)
                             .commit();
                     mActivity.getSupportFragmentManager().executePendingTransactions();
+                    assertEquals(1, mOnBackStackChangedTimes);
                 } catch (IllegalStateException e) {
                     exceptionThrown = true;
                 } finally {
@@ -126,6 +166,7 @@
                             .addToBackStack(null)
                             .commit();
                     mActivity.getSupportFragmentManager().executePendingTransactions();
+                    assertEquals(1, mOnBackStackChangedTimes);
                 } catch (IllegalStateException e) {
                     exceptionThrown = true;
                 } finally {
@@ -138,6 +179,54 @@
     }
 
     @Test
+    public void testGetLayoutInflater() throws Throwable {
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final OnGetLayoutInflaterFragment fragment1 = new OnGetLayoutInflaterFragment();
+                assertEquals(0, fragment1.onGetLayoutInflaterCalls);
+                mActivity.getSupportFragmentManager().beginTransaction()
+                        .add(R.id.content, fragment1)
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getSupportFragmentManager().executePendingTransactions();
+                assertEquals(1, fragment1.onGetLayoutInflaterCalls);
+                assertEquals(fragment1.layoutInflater, fragment1.getLayoutInflater());
+                // getLayoutInflater() didn't force onGetLayoutInflater()
+                assertEquals(1, fragment1.onGetLayoutInflaterCalls);
+
+                LayoutInflater layoutInflater = fragment1.layoutInflater;
+                // Replacing fragment1 won't detach it, so the value won't be cleared
+                final OnGetLayoutInflaterFragment fragment2 = new OnGetLayoutInflaterFragment();
+                mActivity.getSupportFragmentManager().beginTransaction()
+                        .replace(R.id.content, fragment2)
+                        .addToBackStack(null)
+                        .commit();
+                mActivity.getSupportFragmentManager().executePendingTransactions();
+
+                assertSame(layoutInflater, fragment1.getLayoutInflater());
+                assertEquals(1, fragment1.onGetLayoutInflaterCalls);
+
+                // Popping it should cause onCreateView again, so a new LayoutInflater...
+                mActivity.getSupportFragmentManager().popBackStackImmediate();
+                assertNotSame(layoutInflater, fragment1.getLayoutInflater());
+                assertEquals(2, fragment1.onGetLayoutInflaterCalls);
+                layoutInflater = fragment1.layoutInflater;
+                assertSame(layoutInflater, fragment1.getLayoutInflater());
+
+                // Popping it should detach it, clearing the cached value again
+                mActivity.getSupportFragmentManager().popBackStackImmediate();
+
+                // once it is detached, the getLayoutInflater() will default to throw
+                // an exception, but we've made it return null instead.
+                assertEquals(2, fragment1.onGetLayoutInflaterCalls);
+                assertNull(fragment1.getLayoutInflater());
+                assertEquals(3, fragment1.onGetLayoutInflaterCalls);
+            }
+        });
+    }
+
+    @Test
     public void testAddTransactionWithNonStaticFragment() throws Throwable {
         final Fragment fragment = new NonStaticFragment();
         mActivityRule.runOnUiThread(new Runnable() {
@@ -150,6 +239,7 @@
                             .addToBackStack(null)
                             .commit();
                     mActivity.getSupportFragmentManager().executePendingTransactions();
+                    assertEquals(1, mOnBackStackChangedTimes);
                 } catch (IllegalStateException e) {
                     exceptionThrown = true;
                 } finally {
@@ -161,6 +251,156 @@
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
     }
 
+    /**
+     * onNewIntent() should note that the state is not saved so that child fragment
+     * managers can execute transactions.
+     */
+    @Test
+    public void newIntentUnlocks() throws Throwable {
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        Intent intent1 = new Intent(mActivity, NewIntentActivity.class)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        NewIntentActivity newIntentActivity =
+                (NewIntentActivity) instrumentation.startActivitySync(intent1);
+        FragmentTestUtil.waitForExecution(mActivityRule);
+
+        Intent intent2 = new Intent(mActivity, FragmentTestActivity.class);
+        intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        Activity coveringActivity = instrumentation.startActivitySync(intent2);
+        FragmentTestUtil.waitForExecution(mActivityRule);
+
+        Intent intent3 = new Intent(mActivity, NewIntentActivity.class)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mActivity.startActivity(intent3);
+        assertTrue(newIntentActivity.newIntent.await(1, TimeUnit.SECONDS));
+        FragmentTestUtil.waitForExecution(mActivityRule);
+
+        for (Fragment fragment : newIntentActivity.getSupportFragmentManager().getFragments()) {
+            // There really should only be one fragment in newIntentActivity.
+            assertEquals(1, fragment.getChildFragmentManager().getFragments().size());
+        }
+    }
+
+    // Ensure that getFragments() works during transactions, even if it is run off thread
+    @Test
+    public void getFragmentsOffThread() throws Throwable {
+        final FragmentManager fm = mActivity.getSupportFragmentManager();
+
+        // Make sure that adding a fragment works
+        Fragment fragment = new CorrectFragment();
+        fm.beginTransaction()
+                .add(R.id.content, fragment)
+                .addToBackStack(null)
+                .commit();
+
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+        Collection<Fragment> fragments = fm.getFragments();
+        assertEquals(1, fragments.size());
+        assertTrue(fragments.contains(fragment));
+
+        // Removed fragments shouldn't show
+        fm.beginTransaction()
+                .remove(fragment)
+                .addToBackStack(null)
+                .commit();
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+        assertTrue(fm.getFragments().isEmpty());
+
+        // Now try detached fragments
+        FragmentTestUtil.popBackStackImmediate(mActivityRule);
+        fm.beginTransaction()
+                .detach(fragment)
+                .addToBackStack(null)
+                .commit();
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+        assertTrue(fm.getFragments().isEmpty());
+
+        // Now try hidden fragments
+        FragmentTestUtil.popBackStackImmediate(mActivityRule);
+        fm.beginTransaction()
+                .hide(fragment)
+                .addToBackStack(null)
+                .commit();
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+        fragments = fm.getFragments();
+        assertEquals(1, fragments.size());
+        assertTrue(fragments.contains(fragment));
+
+        // And showing it again shouldn't change anything:
+        FragmentTestUtil.popBackStackImmediate(mActivityRule);
+        fragments = fm.getFragments();
+        assertEquals(1, fragments.size());
+        assertTrue(fragments.contains(fragment));
+
+        // Now pop back to the start state
+        FragmentTestUtil.popBackStackImmediate(mActivityRule);
+
+        // We can't force concurrency, but we can do it lots of times and hope that
+        // we hit it.
+        for (int i = 0; i < 100; i++) {
+            Fragment fragment2 = new CorrectFragment();
+            fm.beginTransaction()
+                    .add(R.id.content, fragment2)
+                    .addToBackStack(null)
+                    .commit();
+            getFragmentsUntilSize(1);
+
+            fm.popBackStack();
+            getFragmentsUntilSize(0);
+        }
+    }
+
+    /**
+     * When a FragmentManager is detached, it should allow commitAllowingStateLoss()
+     * and commitNowAllowingStateLoss() by just dropping the transaction.
+     */
+    @Test
+    public void commitAllowStateLossDetached() throws Throwable {
+        Fragment fragment1 = new CorrectFragment();
+        mActivity.getSupportFragmentManager()
+                .beginTransaction()
+                .add(fragment1, "1")
+                .commit();
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+        final FragmentManager fm = fragment1.getChildFragmentManager();
+        mActivity.getSupportFragmentManager()
+                .beginTransaction()
+                .remove(fragment1)
+                .commit();
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+        assertEquals(0, mActivity.getSupportFragmentManager().getFragments().size());
+        assertEquals(0, fm.getFragments().size());
+
+        // Now the fragment1's fragment manager should allow commitAllowingStateLoss
+        // by doing nothing since it has been detached.
+        Fragment fragment2 = new CorrectFragment();
+        fm.beginTransaction()
+                .add(fragment2, "2")
+                .commitAllowingStateLoss();
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+        assertEquals(0, fm.getFragments().size());
+
+        // It should also allow commitNowAllowingStateLoss by doing nothing
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Fragment fragment3 = new CorrectFragment();
+                fm.beginTransaction()
+                        .add(fragment3, "3")
+                        .commitNowAllowingStateLoss();
+                assertEquals(0, fm.getFragments().size());
+            }
+        });
+    }
+
+    private void getFragmentsUntilSize(int expectedSize) {
+        final long endTime = SystemClock.uptimeMillis() + 3000;
+
+        do {
+            assertTrue(SystemClock.uptimeMillis() < endTime);
+        } while (mActivity.getSupportFragmentManager().getFragments().size() != expectedSize);
+    }
+
     public static class CorrectFragment extends Fragment {}
 
     private static class PrivateFragment extends Fragment {}
@@ -168,4 +408,27 @@
     static class PackagePrivateFragment extends Fragment {}
 
     private class NonStaticFragment extends Fragment {}
+
+    public static class OnGetLayoutInflaterFragment extends Fragment {
+        public int onGetLayoutInflaterCalls = 0;
+        public LayoutInflater layoutInflater;
+
+        @Override
+        public LayoutInflater onGetLayoutInflater(Bundle savedInstanceState) {
+            onGetLayoutInflaterCalls++;
+            try {
+                layoutInflater = super.onGetLayoutInflater(savedInstanceState);
+            } catch (Exception e) {
+                return null;
+            }
+            return layoutInflater;
+        }
+
+        @Nullable
+        @Override
+        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+                @Nullable Bundle savedInstanceState) {
+            return inflater.inflate(R.layout.fragment_a, container, false);
+        }
+    }
 }
diff --git a/fragment/tests/java/android/support/v4/app/FragmentTransitionTest.java b/fragment/tests/java/android/support/v4/app/FragmentTransitionTest.java
index ab319b77..c5f1fe9 100644
--- a/fragment/tests/java/android/support/v4/app/FragmentTransitionTest.java
+++ b/fragment/tests/java/android/support/v4/app/FragmentTransitionTest.java
@@ -37,6 +37,7 @@
 import android.transition.TransitionSet;
 import android.view.View;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -67,6 +68,8 @@
 
     private Instrumentation mInstrumentation;
     private FragmentManager mFragmentManager;
+    private int mOnBackStackChangedTimes;
+    private FragmentManager.OnBackStackChangedListener mOnBackStackChangedListener;
 
     public FragmentTransitionTest(final boolean optimize) {
         mOptimize = optimize;
@@ -77,6 +80,20 @@
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
         mFragmentManager = mActivityRule.getActivity().getSupportFragmentManager();
         FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
+        mOnBackStackChangedTimes = 0;
+        mOnBackStackChangedListener = new FragmentManager.OnBackStackChangedListener() {
+            @Override
+            public void onBackStackChanged() {
+                mOnBackStackChangedTimes++;
+            }
+        };
+        mFragmentManager.addOnBackStackChangedListener(mOnBackStackChangedListener);
+    }
+
+    @After
+    public void teardown() throws Throwable {
+        mFragmentManager.removeOnBackStackChangedListener(mOnBackStackChangedListener);
+        mOnBackStackChangedListener = null;
     }
 
     // Test that normal view transitions (enter, exit, reenter, return) run with
@@ -98,6 +115,7 @@
         fragment.waitForTransition();
         verifyAndClearTransition(fragment.exitTransition, null, green, blue);
         verifyNoOtherTransitions(fragment);
+        assertEquals(2, mOnBackStackChangedTimes);
 
         // reenter transition
         FragmentTestUtil.popBackStackImmediate(mActivityRule);
@@ -106,12 +124,14 @@
         final View blue2 = findBlue();
         verifyAndClearTransition(fragment.reenterTransition, null, green2, blue2);
         verifyNoOtherTransitions(fragment);
+        assertEquals(3, mOnBackStackChangedTimes);
 
         // return transition
         FragmentTestUtil.popBackStackImmediate(mActivityRule);
         fragment.waitForTransition();
         verifyAndClearTransition(fragment.returnTransition, null, green2, blue2);
         verifyNoOtherTransitions(fragment);
+        assertEquals(4, mOnBackStackChangedTimes);
     }
 
     // Test that shared elements transition from one fragment to the next
@@ -173,6 +193,7 @@
             }
         });
         FragmentTestUtil.waitForExecution(mActivityRule);
+        assertEquals(2, mOnBackStackChangedTimes);
 
         // should be a normal transition from fragment1 to fragment2
         fragment2.waitForTransition();
@@ -185,6 +206,7 @@
 
         // Pop should also do the same thing
         FragmentTestUtil.popBackStackImmediate(mActivityRule);
+        assertEquals(3, mOnBackStackChangedTimes);
 
         fragment1.waitForTransition();
         final View popBlue = findBlue();
@@ -210,6 +232,7 @@
                 .addToBackStack(null)
                 .commit();
         FragmentTestUtil.waitForExecution(mActivityRule);
+        assertEquals(1, mOnBackStackChangedTimes);
 
         fragment1.waitForTransition();
         final View greenSquare1 = findViewById(fragment1, R.id.greenSquare);
@@ -445,6 +468,7 @@
                 .setAllowOptimization(true)
                 .commit();
         FragmentTestUtil.waitForExecution(mActivityRule);
+        assertEquals(2, mOnBackStackChangedTimes);
 
         fragment1.waitForTransition();
         fragment2.waitForTransition();
@@ -460,6 +484,7 @@
 
         // Now see if it works when popped
         FragmentTestUtil.popBackStackImmediate(mActivityRule);
+        assertEquals(3, mOnBackStackChangedTimes);
 
         fragment1.waitForTransition();
         fragment2.waitForTransition();
@@ -698,6 +723,73 @@
         verifyNoOtherTransitions(fragment);
     }
 
+    // No crash when transitioning a shared element and there is no shared element transition.
+    @Test
+    public void noSharedElementTransition() throws Throwable {
+        TransitionFragment fragment1 = setupInitialFragment();
+
+        final View startBlue = findBlue();
+        final View startGreen = findGreen();
+        final Rect startBlueBounds = getBoundsOnScreen(startBlue);
+
+        TransitionFragment fragment2 = new TransitionFragment();
+        fragment2.setLayoutId(R.layout.scene2);
+
+        mFragmentManager.beginTransaction()
+                .setAllowOptimization(mOptimize)
+                .addSharedElement(startBlue, "blueSquare")
+                .replace(R.id.fragmentContainer, fragment2)
+                .addToBackStack(null)
+                .commit();
+
+        fragment1.waitForTransition();
+        fragment2.waitForTransition();
+        final View midGreen = findGreen();
+        final View midBlue = findBlue();
+        final Rect midBlueBounds = getBoundsOnScreen(midBlue);
+        verifyAndClearTransition(fragment1.exitTransition, startBlueBounds, startGreen);
+        verifyAndClearTransition(fragment2.sharedElementEnter, startBlueBounds, startBlue, midBlue);
+        verifyAndClearTransition(fragment2.enterTransition, midBlueBounds, midGreen);
+        verifyNoOtherTransitions(fragment1);
+        verifyNoOtherTransitions(fragment2);
+
+        final TransitionFragment fragment3 = new TransitionFragment();
+        fragment3.setLayoutId(R.layout.scene3);
+
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager();
+                fm.popBackStack();
+                fm.beginTransaction()
+                        .setAllowOptimization(mOptimize)
+                        .replace(R.id.fragmentContainer, fragment3)
+                        .addToBackStack(null)
+                        .commit();
+            }
+        });
+
+        // This shouldn't give an error.
+        FragmentTestUtil.executePendingTransactions(mActivityRule);
+
+        fragment2.waitForTransition();
+        // It does not transition properly for unoptimized transactions, though.
+        if (mOptimize) {
+            verifyAndClearTransition(fragment2.returnTransition, null, midGreen, midBlue);
+            final View endGreen = findGreen();
+            final View endBlue = findBlue();
+            final View endRed = findRed();
+            verifyAndClearTransition(fragment3.enterTransition, null, endGreen, endBlue, endRed);
+            verifyNoOtherTransitions(fragment2);
+            verifyNoOtherTransitions(fragment3);
+        } else {
+            // fragment3 doesn't get a transition since it conflicts with the pop transition
+            verifyNoOtherTransitions(fragment3);
+            // Everything else is just doing its best. Unoptimized transactions can't handle
+            // multiple transitions acting together except for popping multiple together.
+        }
+    }
+
     private TransitionFragment setupInitialFragment() throws Throwable {
         TransitionFragment fragment1 = new TransitionFragment();
         fragment1.setLayoutId(R.layout.scene1);
@@ -707,6 +799,7 @@
                 .addToBackStack(null)
                 .commit();
         FragmentTestUtil.waitForExecution(mActivityRule);
+        assertEquals(1, mOnBackStackChangedTimes);
         fragment1.waitForTransition();
         final View blueSquare1 = findBlue();
         final View greenSquare1 = findGreen();
@@ -787,6 +880,7 @@
 
     private void verifyTransition(TransitionFragment from, TransitionFragment to,
             String sharedElementName) throws Throwable {
+        final int startOnBackStackChanged = mOnBackStackChangedTimes;
         final View startBlue = findBlue();
         final View startGreen = findGreen();
         final View startRed = findRed();
@@ -801,6 +895,7 @@
                 .commit();
 
         FragmentTestUtil.waitForExecution(mActivityRule);
+        assertEquals(startOnBackStackChanged + 1, mOnBackStackChangedTimes);
 
         to.waitForTransition();
         final View endGreen = findGreen();
@@ -826,6 +921,8 @@
 
     private void verifyCrossTransition(boolean swapSource,
             TransitionFragment from1, TransitionFragment from2) throws Throwable {
+        final int startNumOnBackStackChanged = mOnBackStackChangedTimes;
+        final int changesPerOperation = mOptimize ? 1 : 2;
 
         final TransitionFragment to1 = new TransitionFragment();
         to1.setLayoutId(R.layout.scene2);
@@ -862,6 +959,7 @@
             }
         });
         FragmentTestUtil.waitForExecution(mActivityRule);
+        assertEquals(startNumOnBackStackChanged + changesPerOperation, mOnBackStackChangedTimes);
 
         from1.waitForTransition();
         from2.waitForTransition();
@@ -897,6 +995,8 @@
             }
         });
         FragmentTestUtil.waitForExecution(mActivityRule);
+        assertEquals(startNumOnBackStackChanged + changesPerOperation + 1,
+                mOnBackStackChangedTimes);
 
         from1.waitForTransition();
         from2.waitForTransition();
@@ -924,6 +1024,7 @@
 
     private void verifyPopTransition(final int numPops, TransitionFragment from,
             TransitionFragment to, TransitionFragment... others) throws Throwable {
+        final int startOnBackStackChanged = mOnBackStackChangedTimes;
         final View startBlue = findBlue();
         final View startGreen = findGreen();
         final View startRed = findRed();
@@ -938,6 +1039,7 @@
             }
         });
         FragmentTestUtil.waitForExecution(mActivityRule);
+        assertEquals(startOnBackStackChanged + 1, mOnBackStackChangedTimes);
 
         to.waitForTransition();
         final View endGreen = findGreen();
diff --git a/fragment/tests/java/android/support/v4/app/HostCallbacks.java b/fragment/tests/java/android/support/v4/app/HostCallbacks.java
index 9a0ef1c..15698a6 100644
--- a/fragment/tests/java/android/support/v4/app/HostCallbacks.java
+++ b/fragment/tests/java/android/support/v4/app/HostCallbacks.java
@@ -16,20 +16,19 @@
 package android.support.v4.app;
 
 import android.os.Handler;
-import android.support.v4.app.test.FragmentTestActivity;
 import android.view.LayoutInflater;
 import android.view.View;
 
-class HostCallbacks extends FragmentHostCallback<FragmentTestActivity> {
-    private final FragmentTestActivity mActivity;
+class HostCallbacks extends FragmentHostCallback<FragmentActivity> {
+    private final FragmentActivity mActivity;
 
-    HostCallbacks(FragmentTestActivity activity, Handler handler, int windowAnimations) {
+    HostCallbacks(FragmentActivity activity, Handler handler, int windowAnimations) {
         super(activity, handler, windowAnimations);
         mActivity = activity;
     }
 
     @Override
-    public FragmentTestActivity onGetHost() {
+    public FragmentActivity onGetHost() {
         return mActivity;
     }
 
diff --git a/fragment/tests/java/android/support/v4/app/LoaderTest.java b/fragment/tests/java/android/support/v4/app/LoaderTest.java
new file mode 100644
index 0000000..f1eb328
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/LoaderTest.java
@@ -0,0 +1,265 @@
+/*
+ * 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 static junit.framework.Assert.assertNull;
+import static junit.framework.TestCase.assertFalse;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.support.annotation.Nullable;
+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.v4.app.test.LoaderActivity;
+import android.support.v4.content.AsyncTaskLoader;
+import android.support.v4.content.Loader;
+
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class LoaderTest {
+    private static final int DELAY_LOADER = 10;
+
+    @Rule
+    public ActivityTestRule<LoaderActivity> mActivityRule =
+            new ActivityTestRule(LoaderActivity.class);
+
+    @After
+    public void clearActivity() {
+        LoaderActivity.clearState();
+    }
+
+    /**
+     * Test to ensure that there is no Activity leak due to Loader
+     */
+    @Test
+    public void testLeak() throws Throwable {
+        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        Intent intent = new Intent(mActivityRule.getActivity(), LoaderActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        LoaderActivity.sResumed = new CountDownLatch(1);
+        instrumentation.startActivitySync(intent);
+        assertTrue(LoaderActivity.sResumed.await(1, TimeUnit.SECONDS));
+
+        LoaderFragment fragment = new LoaderFragment();
+        FragmentManager fm = LoaderActivity.sActivity.getSupportFragmentManager();
+
+        fm.beginTransaction()
+                .add(fragment, "1")
+                .commit();
+
+        FragmentTestUtil.executePendingTransactions(mActivityRule, fm);
+
+        fm.beginTransaction()
+                .remove(fragment)
+                .addToBackStack(null)
+                .commit();
+
+        FragmentTestUtil.executePendingTransactions(mActivityRule, fm);
+
+        WeakReference<LoaderActivity> weakActivity = new WeakReference(LoaderActivity.sActivity);
+
+        if (!switchOrientation()) {
+            return; // can't switch orientation for square screens
+        }
+
+        // Now force a garbage collection.
+        FragmentTestUtil.forceGC();
+        assertNull(weakActivity.get());
+    }
+
+    /**
+     * When a LoaderManager is reused, it should notify in onResume
+     */
+    @Test
+    public void startWhenReused() throws Throwable {
+        LoaderActivity activity = mActivityRule.getActivity();
+
+        assertEquals("Loaded!", activity.textView.getText().toString());
+
+        if (!switchOrientation()) {
+            return; // can't switch orientation for square screens
+        }
+
+        // After orientation change, the text should still be loaded properly
+        activity = LoaderActivity.sActivity;
+        assertEquals("Loaded!", activity.textView.getText().toString());
+    }
+
+    /**
+     * When a change is interrupted with stop, the data in the LoaderManager remains stale.
+     */
+    @Test
+    public void noStaleData() throws Throwable {
+        final LoaderActivity activity = mActivityRule.getActivity();
+        final String[] value = new String[] { "First Value" };
+
+        final CountDownLatch[] loadedLatch = new CountDownLatch[] { new CountDownLatch(1) };
+        final Loader<String>[] loaders = new Loader[1];
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                final Loader<String> loader =
+                        activity.getSupportLoaderManager().initLoader(DELAY_LOADER, null,
+                                new LoaderManager.LoaderCallbacks<String>() {
+                                    @Override
+                                    public Loader<String> onCreateLoader(int id, Bundle args) {
+                                        return new AsyncTaskLoader<String>(activity) {
+                                            @Override
+                                            protected void onStopLoading() {
+                                                cancelLoad();
+                                            }
+
+                                            @Override
+                                            public String loadInBackground() {
+                                                SystemClock.sleep(50);
+                                                return value[0];
+                                            }
+
+                                            @Override
+                                            protected void onStartLoading() {
+                                                if (takeContentChanged()) {
+                                                    forceLoad();
+                                                }
+                                                super.onStartLoading();
+                                            }
+                                        };
+                                    }
+
+                                    @Override
+                                    public void onLoadFinished(Loader<String> loader, String data) {
+                                        activity.textViewB.setText(data);
+                                        loadedLatch[0].countDown();
+                                    }
+
+                                    @Override
+                                    public void onLoaderReset(Loader<String> loader) {
+                                    }
+                                });
+                loader.forceLoad();
+                loaders[0] = loader;
+            }
+        });
+
+        assertTrue(loadedLatch[0].await(1, TimeUnit.SECONDS));
+        assertEquals("First Value", activity.textViewB.getText().toString());
+
+        loadedLatch[0] = new CountDownLatch(1);
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                value[0] = "Second Value";
+                loaders[0].onContentChanged();
+                loaders[0].stopLoading();
+            }
+        });
+
+        // Since the loader was stopped (and canceled), it shouldn't notify the change
+        assertFalse(loadedLatch[0].await(300, TimeUnit.MILLISECONDS));
+
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                loaders[0].startLoading();
+            }
+        });
+
+        // Since the loader was stopped (and canceled), it shouldn't notify the change
+        assertTrue(loadedLatch[0].await(1, TimeUnit.SECONDS));
+        assertEquals("Second Value", activity.textViewB.getText().toString());
+    }
+
+    private boolean switchOrientation() throws InterruptedException {
+        LoaderActivity activity = LoaderActivity.sActivity;
+
+        int currentOrientation = activity.getResources().getConfiguration().orientation;
+
+        int nextOrientation;
+        if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
+            nextOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+        } else if (currentOrientation == Configuration.ORIENTATION_PORTRAIT) {
+            nextOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+        } else {
+            return false; // Don't know what to do with square or unknown orientations
+        }
+
+        // Now switch the orientation
+        LoaderActivity.sResumed = new CountDownLatch(1);
+
+        activity.setRequestedOrientation(nextOrientation);
+        assertTrue(LoaderActivity.sResumed.await(1, TimeUnit.SECONDS));
+        return true;
+    }
+
+
+    public static class LoaderFragment extends Fragment {
+        private static final int LOADER_ID = 1;
+        private final LoaderManager.LoaderCallbacks<Boolean> mLoaderCallbacks =
+                new LoaderManager.LoaderCallbacks<Boolean>() {
+                    @Override
+                    public Loader<Boolean> onCreateLoader(int id, Bundle args) {
+                        return new DummyLoader(getContext());
+                    }
+
+                    @Override
+                    public void onLoadFinished(Loader<Boolean> loader, Boolean data) {
+
+                    }
+
+                    @Override
+                    public void onLoaderReset(Loader<Boolean> loader) {
+
+                    }
+                };
+
+        @Override
+        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+            super.onActivityCreated(savedInstanceState);
+
+            getLoaderManager().initLoader(LOADER_ID, null, mLoaderCallbacks);
+        }
+    }
+
+    static class DummyLoader extends Loader<Boolean> {
+        DummyLoader(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void onStartLoading() {
+            deliverResult(true);
+        }
+    }
+}
diff --git a/fragment/tests/java/android/support/v4/app/test/LoaderActivity.java b/fragment/tests/java/android/support/v4/app/test/LoaderActivity.java
new file mode 100644
index 0000000..5e81568
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/test/LoaderActivity.java
@@ -0,0 +1,98 @@
+/*
+ * 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.test;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.fragment.test.R;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.AsyncTaskLoader;
+import android.support.v4.content.Loader;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.concurrent.CountDownLatch;
+
+public class LoaderActivity extends FragmentActivity {
+    // These must be cleared after each test using clearState()
+    public static LoaderActivity sActivity;
+    public static CountDownLatch sResumed;
+
+    public TextView textView;
+    public TextView textViewB;
+
+    public static void clearState() {
+        sActivity = null;
+        sResumed = null;
+    }
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        sActivity = this;
+
+        setContentView(R.layout.fragment_a);
+        textView = (TextView) findViewById(R.id.textA);
+        ViewGroup container = (ViewGroup) textView.getParent();
+        textViewB = new TextView(this);
+        textViewB.setId(R.id.textB);
+        container.addView(textViewB);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        getSupportLoaderManager().initLoader(0, null, new TextLoaderCallback());
+        if (sResumed != null) {
+            sResumed.countDown();
+        }
+    }
+
+    class TextLoaderCallback implements LoaderManager.LoaderCallbacks<String> {
+        @Override
+        public Loader<String> onCreateLoader(int id, Bundle args) {
+            return new TextLoader(LoaderActivity.this);
+        }
+
+        @Override
+        public void onLoadFinished(Loader<String> loader, String data) {
+            textView.setText(data);
+        }
+
+        @Override
+        public void onLoaderReset(Loader<String> loader) {
+        }
+    }
+
+    static class TextLoader extends AsyncTaskLoader<String> {
+        TextLoader(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void onStartLoading() {
+            forceLoad();
+        }
+
+        @Override
+        public String loadInBackground() {
+            return "Loaded!";
+        }
+    }
+}
diff --git a/fragment/tests/java/android/support/v4/app/test/NewIntentActivity.java b/fragment/tests/java/android/support/v4/app/test/NewIntentActivity.java
new file mode 100644
index 0000000..371af21
--- /dev/null
+++ b/fragment/tests/java/android/support/v4/app/test/NewIntentActivity.java
@@ -0,0 +1,55 @@
+/*
+ * 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.test;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+
+import java.util.concurrent.CountDownLatch;
+
+public class NewIntentActivity extends FragmentActivity {
+    public final CountDownLatch newIntent = new CountDownLatch(1);
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (savedInstanceState == null) {
+            getSupportFragmentManager()
+                    .beginTransaction()
+                    .add(new FooFragment(), "derp")
+                    .commitNow();
+        }
+    }
+
+    @Override
+    public void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        // Test a child fragment transaction -
+        getSupportFragmentManager()
+                .findFragmentByTag("derp")
+                .getChildFragmentManager()
+                .beginTransaction()
+                .add(new FooFragment(), "derp4")
+                .commitNow();
+        newIntent.countDown();
+    }
+
+    public static class FooFragment extends Fragment {
+    }
+}
diff --git a/graphics/drawable/Android.mk b/graphics/drawable/Android.mk
index 78652aa..a7cd3e1 100644
--- a/graphics/drawable/Android.mk
+++ b/graphics/drawable/Android.mk
@@ -48,7 +48,8 @@
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-compat \
     android-support-vectordrawable \
-    android-support-annotations
+    android-support-annotations \
+    android-support-core-ui
 LOCAL_AAPT_FLAGS := --no-version-vectors --add-javadoc-annotation doconly
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/graphics/drawable/animated/AndroidManifest.xml b/graphics/drawable/animated/AndroidManifest.xml
index 58017dc..b59fa47 100644
--- a/graphics/drawable/animated/AndroidManifest.xml
+++ b/graphics/drawable/animated/AndroidManifest.xml
@@ -16,6 +16,7 @@
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.graphics.drawable.animated">
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application/>
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/graphics/drawable/animated/build.gradle b/graphics/drawable/animated/build.gradle
index 10d112a..c3a1755 100644
--- a/graphics/drawable/animated/build.gradle
+++ b/graphics/drawable/animated/build.gradle
@@ -9,6 +9,7 @@
     androidTestCompile ("com.android.support.test.espresso:espresso-core:${project.rootProject.ext.espressoVersion}") {
         exclude module: 'support-annotations'
     }
+    compile project(path: ':support-core-ui')
     testCompile 'junit:junit:4.12'
 }
 
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/Animatable2Compat.java b/graphics/drawable/animated/src/android/support/graphics/drawable/Animatable2Compat.java
new file mode 100644
index 0000000..d9d0f36
--- /dev/null
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/Animatable2Compat.java
@@ -0,0 +1,92 @@
+/*
+ * 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.graphics.drawable;
+
+import static android.os.Build.VERSION_CODES.M;
+
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Animatable2;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.NonNull;
+import android.support.annotation.RequiresApi;
+
+/**
+ * Abstract class that drawables supporting animations and callbacks should extend in support lib.
+ */
+public interface Animatable2Compat extends Animatable {
+
+    /**
+     * Adds a callback to listen to the animation events.
+     *
+     * @param callback Callback to add.
+     */
+    void registerAnimationCallback(@NonNull AnimationCallback callback);
+
+    /**
+     * Removes the specified animation callback.
+     *
+     * @param callback Callback to remove.
+     * @return {@code false} if callback didn't exist in the call back list, or {@code true} if
+     *         callback has been removed successfully.
+     */
+    boolean unregisterAnimationCallback(@NonNull AnimationCallback callback);
+
+    /**
+     * Removes all existing animation callbacks.
+     */
+    void clearAnimationCallbacks();
+
+    /**
+     * Animation callback interface. Used to notify animation events.
+     */
+    abstract class AnimationCallback {
+        /**
+         * Called when the animation starts.
+         *
+         * @param drawable The drawable started the animation.
+         */
+        public void onAnimationStart(Drawable drawable) {};
+        /**
+         * Called when the animation ends.
+         *
+         * @param drawable The drawable finished the animation.
+         */
+        public void onAnimationEnd(Drawable drawable) {};
+
+        // Only when passing this Animatable2Compat.AnimationCallback to a frameworks' AVD, we need
+        // to bridge this compat version callback with the frameworks' callback.
+        Animatable2.AnimationCallback mPlatformCallback;
+
+        @RequiresApi(M)
+        Animatable2.AnimationCallback getPlatformCallback() {
+            if (mPlatformCallback == null) {
+                mPlatformCallback = new Animatable2.AnimationCallback() {
+                    @Override
+                    public void onAnimationStart(Drawable drawable) {
+                        AnimationCallback.this.onAnimationStart(drawable);
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Drawable drawable) {
+                        AnimationCallback.this.onAnimationEnd(drawable);
+                    }
+                };
+            }
+            return mPlatformCallback;
+        }
+    }
+}
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 33ff2c5..5337dd1 100644
--- a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
@@ -15,7 +15,7 @@
 package android.support.graphics.drawable;
 
 import android.animation.Animator;
-import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ArgbEvaluator;
 import android.animation.ObjectAnimator;
@@ -51,12 +51,14 @@
 import java.util.List;
 
 /**
- * For API 24 and above, this class is delegating to the framework's {@link AnimatedVectorDrawable}.
+ * For API 24 and above, this class is delegating to the framework's {@link
+ * AnimatedVectorDrawable}.
  * 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/>
- * AnimatedVectorDrawableCompat are defined in the same XML format as {@link AnimatedVectorDrawable}.
+ * AnimatedVectorDrawableCompat are defined in the same XML format as
+ * {@link AnimatedVectorDrawable}.
  * <p/>
  * Here are all the animatable attributes in {@link VectorDrawableCompat}:
  * <table border="2" align="center" cellpadding="5">
@@ -97,6 +99,9 @@
  *         <td>fillColor</td>
  *     </tr>
  *     <tr>
+ *         <td>pathData</td>
+ *     </tr>
+ *     <tr>
  *         <td>strokeColor</td>
  *     </tr>
  *     <tr>
@@ -120,19 +125,23 @@
  * 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:
+ * Note that the animation in AnimatedVectorDrawableCompat now can 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>
+ * </ul>
+ * <p/>
+ * But not support this one feature yet:
+ * <ul>
  * <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>
+ * 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 {
+public class AnimatedVectorDrawableCompat extends VectorDrawableCommon
+        implements Animatable2Compat {
     private static final String LOGTAG = "AnimatedVDCompat";
 
     private static final String ANIMATED_VECTOR = "animated-vector";
@@ -148,6 +157,13 @@
 
     AnimatedVectorDrawableDelegateState mCachedConstantStateDelegate;
 
+    // Use internal listener to support AVDC's callback.
+    private Animator.AnimatorListener mAnimatorListener = null;
+
+    // Use an array to keep track of multiple call back associated with one drawable.
+    private ArrayList<Animatable2Compat.AnimationCallback> mAnimationCallbacks = null;
+
+
     AnimatedVectorDrawableCompat() {
         this(null, null, null);
     }
@@ -157,8 +173,8 @@
     }
 
     private AnimatedVectorDrawableCompat(@Nullable Context context,
-                                         @Nullable AnimatedVectorDrawableCompatState state,
-                                         @Nullable Resources res) {
+            @Nullable AnimatedVectorDrawableCompatState state,
+            @Nullable Resources res) {
         mContext = context;
         if (state != null) {
             mAnimatedVectorState = state;
@@ -192,7 +208,7 @@
      */
     @Nullable
     public static AnimatedVectorDrawableCompat create(@NonNull Context context,
-                                                      @DrawableRes int resId) {
+            @DrawableRes int resId) {
         if (Build.VERSION.SDK_INT >= 24) {
             final AnimatedVectorDrawableCompat drawable = new AnimatedVectorDrawableCompat(context);
             drawable.mDelegateDrawable = ResourcesCompat.getDrawable(context.getResources(), resId,
@@ -269,7 +285,7 @@
             return;
         }
         mAnimatedVectorState.mVectorDrawable.draw(canvas);
-        if (isStarted()) {
+        if (mAnimatedVectorState.mAnimatorSet.isStarted()) {
             invalidateSelf();
         }
     }
@@ -433,11 +449,11 @@
                 }
                 if (ANIMATED_VECTOR.equals(tagName)) {
                     final TypedArray a =
-                            VectorDrawableCommon.obtainAttributes(res, theme, attrs,
-                                    AndroidResources.styleable_AnimatedVectorDrawable);
+                            TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                                    AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE);
 
                     int drawableRes = a.getResourceId(
-                            AndroidResources.styleable_AnimatedVectorDrawable_drawable, 0);
+                            AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE_DRAWABLE, 0);
                     if (DBG_ANIMATION_VECTOR_DRAWABLE) {
                         Log.v(LOGTAG, "drawableRes is " + drawableRes);
                     }
@@ -455,15 +471,19 @@
                 } else if (TARGET.equals(tagName)) {
                     final TypedArray a =
                             res.obtainAttributes(attrs,
-                                    AndroidResources.styleable_AnimatedVectorDrawableTarget);
+                                    AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET);
                     final String target = a.getString(
-                            AndroidResources.styleable_AnimatedVectorDrawableTarget_name);
+                            AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET_NAME);
 
                     int id = a.getResourceId(
-                            AndroidResources.styleable_AnimatedVectorDrawableTarget_animation, 0);
+                            AndroidResources.STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET_ANIMATION,
+                            0);
                     if (id != 0) {
                         if (mContext != null) {
-                            Animator objectAnimator = AnimatorInflater.loadAnimator(mContext, id);
+                            // There are some important features (like path morphing), added into
+                            // Animator code to support AVD at API 21.
+                            Animator objectAnimator = AnimatorInflaterCompat.loadAnimator(
+                                    mContext, id);
                             setupAnimatorsForTarget(target, objectAnimator);
                         } else {
                             a.recycle();
@@ -474,9 +494,10 @@
                     a.recycle();
                 }
             }
-
             eventType = parser.next();
         }
+
+        mAnimatedVectorState.setupAnimatorSet();
     }
 
     @Override
@@ -557,7 +578,9 @@
     private static class AnimatedVectorDrawableCompatState extends ConstantState {
         int mChangingConfigurations;
         VectorDrawableCompat mVectorDrawable;
-        ArrayList<Animator> mAnimators;
+        // Combining the array of Animators into a single AnimatorSet to hook up listener easier.
+        AnimatorSet mAnimatorSet;
+        private ArrayList<Animator> mAnimators;
         ArrayMap<Animator, String> mTargetNameMap;
 
         public AnimatedVectorDrawableCompatState(Context context,
@@ -589,6 +612,7 @@
                         mAnimators.add(animClone);
                         mTargetNameMap.put(animClone, targetName);
                     }
+                    setupAnimatorSet();
                 }
             }
         }
@@ -607,6 +631,13 @@
         public int getChangingConfigurations() {
             return mChangingConfigurations;
         }
+
+        public void setupAnimatorSet() {
+            if (mAnimatorSet == null) {
+                mAnimatorSet = new AnimatorSet();
+            }
+            mAnimatorSet.playTogether(mAnimators);
+        }
     }
 
     /**
@@ -657,30 +688,7 @@
         if (mDelegateDrawable != null) {
             return ((AnimatedVectorDrawable) mDelegateDrawable).isRunning();
         }
-        final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
-        final int size = animators.size();
-        for (int i = 0; i < size; i++) {
-            final Animator animator = animators.get(i);
-            if (animator.isRunning()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean isStarted() {
-        final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
-        if (animators == null) {
-            return false;
-        }
-        final int size = animators.size();
-        for (int i = 0; i < size; i++) {
-            final Animator animator = animators.get(i);
-            if (animator.isRunning()) {
-                return true;
-            }
-        }
-        return false;
+        return mAnimatedVectorState.mAnimatorSet.isRunning();
     }
 
     @Override
@@ -690,16 +698,11 @@
             return;
         }
         // If any one of the animator has not ended, do nothing.
-        if (isStarted()) {
+        if (mAnimatedVectorState.mAnimatorSet.isStarted()) {
             return;
         }
-        // Otherwise, kick off every animator.
-        final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
-        final int size = animators.size();
-        for (int i = 0; i < size; i++) {
-            final Animator animator = animators.get(i);
-            animator.start();
-        }
+        // Otherwise, kick off animatorSet.
+        mAnimatedVectorState.mAnimatorSet.start();
         invalidateSelf();
     }
 
@@ -709,12 +712,7 @@
             ((AnimatedVectorDrawable) mDelegateDrawable).stop();
             return;
         }
-        final ArrayList<Animator> animators = mAnimatedVectorState.mAnimators;
-        final int size = animators.size();
-        for (int i = 0; i < size; i++) {
-            final Animator animator = animators.get(i);
-            animator.end();
-        }
+        mAnimatedVectorState.mAnimatorSet.end();
     }
 
     final Callback mCallback = new Callback() {
@@ -733,4 +731,180 @@
             unscheduleSelf(what);
         }
     };
+
+    /**
+     * A helper function to unregister the Animatable2Compat callback from the platform's
+     * Animatable2 callback, while keeping the internal array of callback up to date.
+     */
+    private static boolean unregisterPlatformCallback(AnimatedVectorDrawable dr,
+            Animatable2Compat.AnimationCallback callback) {
+        return dr.unregisterAnimationCallback(callback.getPlatformCallback());
+    }
+
+    @Override
+    public void registerAnimationCallback(@NonNull Animatable2Compat.AnimationCallback
+            callback) {
+        if (mDelegateDrawable != null) {
+            registerPlatformCallback((AnimatedVectorDrawable) mDelegateDrawable, callback);
+            return;
+        }
+
+        if (callback == null) {
+            return;
+        }
+
+        // Add listener accordingly.
+        if (mAnimationCallbacks == null) {
+            mAnimationCallbacks = new ArrayList<>();
+        }
+
+        if (mAnimationCallbacks.contains(callback)) {
+            // If this call back is already in, then don't need to append another copy.
+            return;
+        }
+
+        mAnimationCallbacks.add(callback);
+
+        if (mAnimatorListener == null) {
+            // Create a animator listener and trigger the callback events when listener is
+            // triggered.
+            mAnimatorListener = new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    ArrayList<Animatable2Compat.AnimationCallback> tmpCallbacks =
+                            new ArrayList<>(mAnimationCallbacks);
+                    int size = tmpCallbacks.size();
+                    for (int i = 0; i < size; i++) {
+                        tmpCallbacks.get(i).onAnimationStart(AnimatedVectorDrawableCompat.this);
+                    }
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    ArrayList<Animatable2Compat.AnimationCallback> tmpCallbacks =
+                            new ArrayList<>(mAnimationCallbacks);
+                    int size = tmpCallbacks.size();
+                    for (int i = 0; i < size; i++) {
+                        tmpCallbacks.get(i).onAnimationEnd(AnimatedVectorDrawableCompat.this);
+                    }
+                }
+            };
+        }
+        mAnimatedVectorState.mAnimatorSet.addListener(mAnimatorListener);
+    }
+
+    /**
+     * A helper function to register the Animatable2Compat callback on the platform's Animatable2
+     * callback.
+     */
+    private static void registerPlatformCallback(@NonNull AnimatedVectorDrawable avd,
+            @NonNull final Animatable2Compat.AnimationCallback callback) {
+        avd.registerAnimationCallback(callback.getPlatformCallback());
+    }
+
+    /**
+     * A helper function to clean up the animator listener in the mAnimatorSet.
+     */
+    private void removeAnimatorSetListener() {
+        if (mAnimatorListener != null) {
+            mAnimatedVectorState.mAnimatorSet.removeListener(mAnimatorListener);
+            mAnimatorListener = null;
+        }
+    }
+
+    @Override
+    public boolean unregisterAnimationCallback(
+            @NonNull Animatable2Compat.AnimationCallback callback) {
+        if (mDelegateDrawable != null) {
+            unregisterPlatformCallback((AnimatedVectorDrawable) mDelegateDrawable, callback);
+        }
+
+        if (mAnimationCallbacks == null || callback == null) {
+            // Nothing to be removed.
+            return false;
+        }
+        boolean removed = mAnimationCallbacks.remove(callback);
+
+        //  When the last call back unregistered, remove the listener accordingly.
+        if (mAnimationCallbacks.size() == 0) {
+            removeAnimatorSetListener();
+        }
+        return removed;
+    }
+
+    @Override
+    public void clearAnimationCallbacks() {
+        if (mDelegateDrawable != null) {
+            ((AnimatedVectorDrawable) mDelegateDrawable).clearAnimationCallbacks();
+            return;
+        }
+        removeAnimatorSetListener();
+        if (mAnimationCallbacks == null) {
+            return;
+        }
+
+        mAnimationCallbacks.clear();
+    }
+
+    /**
+     * Utility function to register callback to Drawable, when the drawable is created from XML and
+     * referred in Java code, e.g: ImageView.getDrawable().
+     * From API 24 on, the drawable is treated as an AnimatedVectorDrawable.
+     * Otherwise, it is treated as AnimatedVectorDrawableCompat.
+     */
+    public static void registerAnimationCallback(Drawable dr,
+            Animatable2Compat.AnimationCallback callback) {
+        if (dr == null || callback == null) {
+            return;
+        }
+        if (!(dr instanceof Animatable)) {
+            return;
+        }
+
+        if (Build.VERSION.SDK_INT >= 24) {
+            registerPlatformCallback((AnimatedVectorDrawable) dr, callback);
+        } else {
+            ((AnimatedVectorDrawableCompat) dr).registerAnimationCallback(callback);
+        }
+    }
+
+    /**
+     * Utility function to unregister animation callback from Drawable, when the drawable is
+     * created from XML and referred in Java code, e.g: ImageView.getDrawable().
+     * From API 24 on, the drawable is treated as an AnimatedVectorDrawable.
+     * Otherwise, it is treated as AnimatedVectorDrawableCompat.
+     */
+    public static boolean unregisterAnimationCallback(Drawable dr,
+            Animatable2Compat.AnimationCallback callback) {
+        if (dr == null || callback == null) {
+            return false;
+        }
+        if (!(dr instanceof Animatable)) {
+            return false;
+        }
+
+        if (Build.VERSION.SDK_INT >= 24) {
+            return unregisterPlatformCallback((AnimatedVectorDrawable) dr, callback);
+        } else {
+            return ((AnimatedVectorDrawableCompat) dr).unregisterAnimationCallback(callback);
+        }
+    }
+
+    /**
+     * Utility function to clear animation callbacks from Drawable, when the drawable is
+     * created from XML and referred in Java code, e.g: ImageView.getDrawable().
+     * From API 24 on, the drawable is treated as an AnimatedVectorDrawable.
+     * Otherwise, it is treated as AnimatedVectorDrawableCompat.
+     */
+    public static void clearAnimationCallbacks(Drawable dr) {
+        if (dr == null || !(dr instanceof Animatable)) {
+            return;
+        }
+        if (Build.VERSION.SDK_INT >= 24) {
+            ((AnimatedVectorDrawable) dr).clearAnimationCallbacks();
+        } else {
+            ((AnimatedVectorDrawableCompat) dr).clearAnimationCallbacks();
+        }
+
+    }
 }
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimationUtilsCompat.java b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimationUtilsCompat.java
new file mode 100644
index 0000000..695cc26
--- /dev/null
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimationUtilsCompat.java
@@ -0,0 +1,147 @@
+/*
+ * 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.graphics.drawable;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
+import android.content.res.XmlResourceParser;
+import android.os.Build;
+import android.support.annotation.RestrictTo;
+import android.support.v4.view.animation.FastOutLinearInInterpolator;
+import android.support.v4.view.animation.FastOutSlowInInterpolator;
+import android.support.v4.view.animation.LinearOutSlowInInterpolator;
+import android.util.AttributeSet;
+import android.util.Xml;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.AnticipateInterpolator;
+import android.view.animation.AnticipateOvershootInterpolator;
+import android.view.animation.BounceInterpolator;
+import android.view.animation.CycleInterpolator;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+import android.view.animation.OvershootInterpolator;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * Defines common utilities for working with animations.
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+public class AnimationUtilsCompat {
+    /**
+     * Loads an {@link Interpolator} object from a resource
+     *
+     * @param context Application context used to access resources
+     * @param id      The resource id of the animation to load
+     * @return The animation object reference by the specified id
+     */
+    public static Interpolator loadInterpolator(Context context, int id)
+            throws NotFoundException {
+        // From API 21, we added path Interpolator .
+        if (Build.VERSION.SDK_INT >= 21) {
+            return AnimationUtils.loadInterpolator(context, id);
+        }
+
+        XmlResourceParser parser = null;
+        try {
+            // Special treatment for the interpolator introduced at API 21.
+            if (id == AndroidResources.FAST_OUT_LINEAR_IN) {
+                return new FastOutLinearInInterpolator();
+            } else if (id == AndroidResources.FAST_OUT_SLOW_IN) {
+                return new FastOutSlowInInterpolator();
+            } else if (id == AndroidResources.LINEAR_OUT_SLOW_IN) {
+                return new LinearOutSlowInInterpolator();
+            }
+            parser = context.getResources().getAnimation(id);
+            return createInterpolatorFromXml(context, context.getResources(), context.getTheme(),
+                    parser);
+        } catch (XmlPullParserException ex) {
+            NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x"
+                    + Integer.toHexString(id));
+            rnf.initCause(ex);
+            throw rnf;
+        } catch (IOException ex) {
+            NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x"
+                    + Integer.toHexString(id));
+            rnf.initCause(ex);
+            throw rnf;
+        } finally {
+            if (parser != null) parser.close();
+        }
+
+    }
+
+    private static Interpolator createInterpolatorFromXml(Context context, Resources res,
+            Theme theme,
+            XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+
+        Interpolator interpolator = null;
+
+        // Make sure we are on a start tag.
+        int type;
+        int depth = parser.getDepth();
+
+        while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                && type != XmlPullParser.END_DOCUMENT) {
+
+            if (type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            AttributeSet attrs = Xml.asAttributeSet(parser);
+
+            String name = parser.getName();
+
+            if (name.equals("linearInterpolator")) {
+                interpolator = new LinearInterpolator();
+            } else if (name.equals("accelerateInterpolator")) {
+                interpolator = new AccelerateInterpolator(context, attrs);
+            } else if (name.equals("decelerateInterpolator")) {
+                interpolator = new DecelerateInterpolator(context, attrs);
+            } else if (name.equals("accelerateDecelerateInterpolator")) {
+                interpolator = new AccelerateDecelerateInterpolator();
+            } else if (name.equals("cycleInterpolator")) {
+                interpolator = new CycleInterpolator(context, attrs);
+            } else if (name.equals("anticipateInterpolator")) {
+                interpolator = new AnticipateInterpolator(context, attrs);
+            } else if (name.equals("overshootInterpolator")) {
+                interpolator = new OvershootInterpolator(context, attrs);
+            } else if (name.equals("anticipateOvershootInterpolator")) {
+                interpolator = new AnticipateOvershootInterpolator(context, attrs);
+            } else if (name.equals("bounceInterpolator")) {
+                interpolator = new BounceInterpolator();
+            } else if (name.equals("pathInterpolator")) {
+                interpolator = new PathInterpolatorCompat(context, attrs, parser);
+            } else {
+                throw new RuntimeException("Unknown interpolator name: " + parser.getName());
+            }
+        }
+        return interpolator;
+    }
+}
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatorInflaterCompat.java b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatorInflaterCompat.java
new file mode 100644
index 0000000..1fb12fb
--- /dev/null
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatorInflaterCompat.java
@@ -0,0 +1,837 @@
+/*
+ * 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.graphics.drawable;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.animation.Keyframe;
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.os.Build;
+import android.support.annotation.AnimatorRes;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.util.Xml;
+import android.view.InflateException;
+import android.view.animation.Interpolator;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * This class is used to instantiate animator XML files into Animator objects.
+ * <p>
+ * For performance reasons, inflation relies heavily on pre-processing of
+ * XML files that is done at build time. Therefore, it is not currently possible
+ * to use this inflater with an XmlPullParser over a plain XML file at runtime;
+ * it only works with an XmlPullParser returned from a compiled resource (R.
+ * <em>something</em> file.)
+ * @hide
+ */
+public class AnimatorInflaterCompat {
+    private static final String TAG = "AnimatorInflater";
+    /**
+     * These flags are used when parsing AnimatorSet objects
+     */
+    private static final int TOGETHER = 0;
+    private static final int SEQUENTIALLY = 1;
+
+    /**
+     * Enum values used in XML attributes to indicate the value for mValueType
+     */
+    private static final int VALUE_TYPE_FLOAT = 0;
+    private static final int VALUE_TYPE_INT = 1;
+    private static final int VALUE_TYPE_PATH = 2;
+    private static final int VALUE_TYPE_COLOR = 3;
+    private static final int VALUE_TYPE_UNDEFINED = 4;
+
+    private static final boolean DBG_ANIMATOR_INFLATER = false;
+
+    // used to calculate changing configs for resource references
+    private static final TypedValue sTmpTypedValue = new TypedValue();
+
+    /**
+     * Loads an {@link Animator} object from a context
+     *
+     * @param context Application context used to access resources
+     * @param id      The resource id of the animation to load
+     * @return The animator object reference by the specified id
+     * @throws NotFoundException when the animation cannot be loaded
+     */
+    public static Animator loadAnimator(Context context, @AnimatorRes int id)
+            throws NotFoundException {
+        Animator objectAnimator;
+        // Since AVDC will fall back onto AVD when API is >= 24, therefore, PathParser will need
+        // to match the accordingly to be able to call into the right setter/ getter for animation.
+        if (Build.VERSION.SDK_INT >= 24) {
+            objectAnimator = AnimatorInflater.loadAnimator(context, id);
+        } else {
+            objectAnimator = loadAnimator(context, context.getResources(), context.getTheme(), id);
+        }
+        return objectAnimator;
+    }
+
+    /**
+     * Loads an {@link Animator} object from a resource
+     *
+     * @param resources The resources
+     * @param theme     The theme
+     * @param id        The resource id of the animation to load
+     * @return The animator object reference by the specified id
+     * @throws NotFoundException when the animation cannot be loaded
+     * @hide
+     */
+    public static Animator loadAnimator(Context context, Resources resources, Theme theme,
+            @AnimatorRes int id) throws NotFoundException {
+        return loadAnimator(context, resources, theme, id, 1);
+    }
+
+    /**
+     * Loads an {@link Animator} object from a resource, context is for loading interpolator.
+     */
+    public static Animator loadAnimator(Context context, Resources resources, Theme theme,
+            @AnimatorRes int id, float pathErrorScale) throws NotFoundException {
+        Animator animator;
+
+        XmlResourceParser parser = null;
+        try {
+            parser = resources.getAnimation(id);
+            animator = createAnimatorFromXml(context, resources, theme, parser, pathErrorScale);
+            return animator;
+        } catch (XmlPullParserException ex) {
+            Resources.NotFoundException rnf =
+                    new Resources.NotFoundException("Can't load animation resource ID #0x"
+                            + Integer.toHexString(id));
+            rnf.initCause(ex);
+            throw rnf;
+        } catch (IOException ex) {
+            Resources.NotFoundException rnf =
+                    new Resources.NotFoundException("Can't load animation resource ID #0x"
+                            + Integer.toHexString(id));
+            rnf.initCause(ex);
+            throw rnf;
+        } finally {
+            if (parser != null) parser.close();
+        }
+    }
+
+    /**
+     * PathDataEvaluator is used to interpolate between two paths which are
+     * represented in the same format but different control points' values.
+     * The path is represented as an array of PathDataNode here, which is
+     * fundamentally an array of floating point numbers.
+     */
+    private static class PathDataEvaluator implements
+            TypeEvaluator<PathParser.PathDataNode[]> {
+        private PathParser.PathDataNode[] mNodeArray;
+
+        /**
+         * Create a PathParser.PathDataNode[] that does not reuse the animated value.
+         * Care must be taken when using this option because on every evaluation
+         * a new <code>PathParser.PathDataNode[]</code> will be allocated.
+         */
+        private PathDataEvaluator() {
+        }
+
+        /**
+         * Create a PathDataEvaluator that reuses <code>nodeArray</code> for every evaluate() call.
+         * Caution must be taken to ensure that the value returned from
+         * {@link android.animation.ValueAnimator#getAnimatedValue()} is not cached, modified, or
+         * used across threads. The value will be modified on each <code>evaluate()</code> call.
+         *
+         * @param nodeArray The array to modify and return from <code>evaluate</code>.
+         */
+        PathDataEvaluator(PathParser.PathDataNode[] nodeArray) {
+            mNodeArray = nodeArray;
+        }
+
+        @Override
+        public PathParser.PathDataNode[] evaluate(float fraction,
+                PathParser.PathDataNode[] startPathData,
+                PathParser.PathDataNode[] endPathData) {
+            if (!PathParser.canMorph(startPathData, endPathData)) {
+                throw new IllegalArgumentException("Can't interpolate between"
+                        + " two incompatible pathData");
+            }
+
+            if (mNodeArray == null || !PathParser.canMorph(mNodeArray, startPathData)) {
+                mNodeArray = PathParser.deepCopyNodes(startPathData);
+            }
+
+            for (int i = 0; i < startPathData.length; i++) {
+                mNodeArray[i].interpolatePathDataNode(startPathData[i],
+                        endPathData[i], fraction);
+            }
+
+            return mNodeArray;
+        }
+    }
+
+
+    private static PropertyValuesHolder getPVH(TypedArray styledAttributes, int valueType,
+            int valueFromId, int valueToId, String propertyName) {
+
+        TypedValue tvFrom = styledAttributes.peekValue(valueFromId);
+        boolean hasFrom = (tvFrom != null);
+        int fromType = hasFrom ? tvFrom.type : 0;
+        TypedValue tvTo = styledAttributes.peekValue(valueToId);
+        boolean hasTo = (tvTo != null);
+        int toType = hasTo ? tvTo.type : 0;
+
+        if (valueType == VALUE_TYPE_UNDEFINED) {
+            // Check whether it's color type. If not, fall back to default type (i.e. float type)
+            if ((hasFrom && isColorType(fromType)) || (hasTo && isColorType(toType))) {
+                valueType = VALUE_TYPE_COLOR;
+            } else {
+                valueType = VALUE_TYPE_FLOAT;
+            }
+        }
+
+        boolean getFloats = (valueType == VALUE_TYPE_FLOAT);
+
+        PropertyValuesHolder returnValue = null;
+
+        if (valueType == VALUE_TYPE_PATH) {
+            String fromString = styledAttributes.getString(valueFromId);
+            String toString = styledAttributes.getString(valueToId);
+
+            PathParser.PathDataNode[] nodesFrom =
+                    PathParser.createNodesFromPathData(fromString);
+            PathParser.PathDataNode[] nodesTo =
+                    PathParser.createNodesFromPathData(toString);
+            if (nodesFrom != null || nodesTo != null) {
+                if (nodesFrom != null) {
+                    TypeEvaluator evaluator = new PathDataEvaluator();
+                    if (nodesTo != null) {
+                        if (!PathParser.canMorph(nodesFrom, nodesTo)) {
+                            throw new InflateException(" Can't morph from " + fromString + " to "
+                                    + toString);
+                        }
+                        returnValue = PropertyValuesHolder.ofObject(propertyName, evaluator,
+                                nodesFrom, nodesTo);
+                    } else {
+                        returnValue = PropertyValuesHolder.ofObject(propertyName, evaluator,
+                                (Object) nodesFrom);
+                    }
+                } else if (nodesTo != null) {
+                    TypeEvaluator evaluator = new PathDataEvaluator();
+                    returnValue = PropertyValuesHolder.ofObject(propertyName, evaluator,
+                            (Object) nodesTo);
+                }
+            }
+        } else {
+            TypeEvaluator evaluator = null;
+            // Integer and float value types are handled here.
+            if (valueType == VALUE_TYPE_COLOR) {
+                // special case for colors: ignore valueType and get ints
+                evaluator = ArgbEvaluator.getInstance();
+            }
+            if (getFloats) {
+                float valueFrom;
+                float valueTo;
+                if (hasFrom) {
+                    if (fromType == TypedValue.TYPE_DIMENSION) {
+                        valueFrom = styledAttributes.getDimension(valueFromId, 0f);
+                    } else {
+                        valueFrom = styledAttributes.getFloat(valueFromId, 0f);
+                    }
+                    if (hasTo) {
+                        if (toType == TypedValue.TYPE_DIMENSION) {
+                            valueTo = styledAttributes.getDimension(valueToId, 0f);
+                        } else {
+                            valueTo = styledAttributes.getFloat(valueToId, 0f);
+                        }
+                        returnValue = PropertyValuesHolder.ofFloat(propertyName,
+                                valueFrom, valueTo);
+                    } else {
+                        returnValue = PropertyValuesHolder.ofFloat(propertyName, valueFrom);
+                    }
+                } else {
+                    if (toType == TypedValue.TYPE_DIMENSION) {
+                        valueTo = styledAttributes.getDimension(valueToId, 0f);
+                    } else {
+                        valueTo = styledAttributes.getFloat(valueToId, 0f);
+                    }
+                    returnValue = PropertyValuesHolder.ofFloat(propertyName, valueTo);
+                }
+            } else {
+                int valueFrom;
+                int valueTo;
+                if (hasFrom) {
+                    if (fromType == TypedValue.TYPE_DIMENSION) {
+                        valueFrom = (int) styledAttributes.getDimension(valueFromId, 0f);
+                    } else if (isColorType(fromType)) {
+                        valueFrom = styledAttributes.getColor(valueFromId, 0);
+                    } else {
+                        valueFrom = styledAttributes.getInt(valueFromId, 0);
+                    }
+                    if (hasTo) {
+                        if (toType == TypedValue.TYPE_DIMENSION) {
+                            valueTo = (int) styledAttributes.getDimension(valueToId, 0f);
+                        } else if (isColorType(toType)) {
+                            valueTo = styledAttributes.getColor(valueToId, 0);
+                        } else {
+                            valueTo = styledAttributes.getInt(valueToId, 0);
+                        }
+                        returnValue = PropertyValuesHolder.ofInt(propertyName, valueFrom, valueTo);
+                    } else {
+                        returnValue = PropertyValuesHolder.ofInt(propertyName, valueFrom);
+                    }
+                } else {
+                    if (hasTo) {
+                        if (toType == TypedValue.TYPE_DIMENSION) {
+                            valueTo = (int) styledAttributes.getDimension(valueToId, 0f);
+                        } else if (isColorType(toType)) {
+                            valueTo = styledAttributes.getColor(valueToId, 0);
+                        } else {
+                            valueTo = styledAttributes.getInt(valueToId, 0);
+                        }
+                        returnValue = PropertyValuesHolder.ofInt(propertyName, valueTo);
+                    }
+                }
+            }
+            if (returnValue != null && evaluator != null) {
+                returnValue.setEvaluator(evaluator);
+            }
+        }
+
+        return returnValue;
+    }
+
+    /**
+     * @param anim                The animator, must not be null
+     * @param arrayAnimator       Incoming typed array for Animator's attributes.
+     * @param arrayObjectAnimator Incoming typed array for Object Animator's
+     *                            attributes.
+     * @param pixelSize           The relative pixel size, used to calculate the
+     *                            maximum error for path animations.
+     */
+    private static void parseAnimatorFromTypeArray(ValueAnimator anim,
+            TypedArray arrayAnimator, TypedArray arrayObjectAnimator, float pixelSize,
+            XmlPullParser parser) {
+        long duration = TypedArrayUtils.getNamedInt(arrayAnimator, parser, "duration",
+                AndroidResources.STYLEABLE_ANIMATOR_DURATION, 300);
+        long startDelay = TypedArrayUtils.getNamedInt(arrayAnimator, parser, "startOffset",
+                AndroidResources.STYLEABLE_ANIMATOR_START_OFFSET, 0);
+        int valueType = TypedArrayUtils.getNamedInt(arrayAnimator, parser, "valueType",
+                AndroidResources.STYLEABLE_ANIMATOR_VALUE_TYPE, VALUE_TYPE_UNDEFINED);
+
+        // Change to requiring both value from and to, otherwise, throw exception for now.
+        if (TypedArrayUtils.hasAttribute(parser, "valueFrom")
+                && TypedArrayUtils.hasAttribute(parser, "valueTo")) {
+            if (valueType == VALUE_TYPE_UNDEFINED) {
+                valueType = inferValueTypeFromValues(arrayAnimator,
+                        AndroidResources.STYLEABLE_ANIMATOR_VALUE_FROM,
+                        AndroidResources.STYLEABLE_ANIMATOR_VALUE_TO);
+            }
+            PropertyValuesHolder pvh = getPVH(arrayAnimator, valueType,
+                    AndroidResources.STYLEABLE_ANIMATOR_VALUE_FROM,
+                    AndroidResources.STYLEABLE_ANIMATOR_VALUE_TO, "");
+            if (pvh != null) {
+                anim.setValues(pvh);
+            }
+        } else {
+            throw new IllegalArgumentException("no valueFrom or no valueTo");
+        }
+        anim.setDuration(duration);
+        anim.setStartDelay(startDelay);
+
+        anim.setRepeatCount(TypedArrayUtils.getNamedInt(arrayAnimator, parser, "repeatCount",
+                AndroidResources.STYLEABLE_ANIMATOR_REPEAT_COUNT, 0));
+        anim.setRepeatMode(TypedArrayUtils.getNamedInt(arrayAnimator, parser, "repeatMode",
+                AndroidResources.STYLEABLE_ANIMATOR_REPEAT_MODE, ValueAnimator.RESTART));
+
+        if (arrayObjectAnimator != null) {
+            setupObjectAnimator(anim, arrayObjectAnimator, valueType, pixelSize, parser);
+        }
+    }
+
+
+    /**
+     * Setup ObjectAnimator's property or values from pathData.
+     *
+     * @param getFloats           True if the value type is float.
+     * @param anim                The target Animator which will be updated.
+     * @param arrayObjectAnimator TypedArray for the ObjectAnimator.
+     * @param pixelSize           The relative pixel size, used to calculate the
+     */
+    private static void setupObjectAnimator(ValueAnimator anim, TypedArray arrayObjectAnimator,
+            int valueType, float pixelSize, XmlPullParser parser) {
+        ObjectAnimator oa = (ObjectAnimator) anim;
+        String pathData = TypedArrayUtils.getNamedString(arrayObjectAnimator, parser, "pathData",
+                AndroidResources.STYLEABLE_PROPERTY_ANIMATOR_PATH_DATA);
+
+        // Path can be involved in an ObjectAnimator in the following 3 ways:
+        // 1) Path morphing: the property to be animated is pathData, and valueFrom and valueTo
+        //    are both of pathType. valueType = pathType needs to be explicitly defined.
+        // 2) A property in X or Y dimension can be animated along a path: the property needs to be
+        //    defined in propertyXName or propertyYName attribute, the path will be defined in the
+        //    pathData attribute. valueFrom and valueTo will not be necessary for this animation.
+        // 3) PathInterpolator can also define a path (in pathData) for its interpolation curve.
+        // Here we are dealing with case 2:
+        if (pathData != null) {
+            Log.e(TAG, "We don't support moving along path yet");
+        } else {
+            String propertyName =
+                    TypedArrayUtils.getNamedString(arrayObjectAnimator, parser, "propertyName",
+                            AndroidResources.STYLEABLE_PROPERTY_ANIMATOR_PROPERTY_NAME);
+            oa.setPropertyName(propertyName);
+        }
+
+
+        return;
+
+    }
+
+    private static Animator createAnimatorFromXml(Context context, Resources res, Theme theme,
+            XmlPullParser parser,
+            float pixelSize)
+            throws XmlPullParserException, IOException {
+        return createAnimatorFromXml(context, res, theme, parser, Xml.asAttributeSet(parser), null,
+                0, pixelSize);
+    }
+
+    private static Animator createAnimatorFromXml(Context context, Resources res, Theme theme,
+            XmlPullParser parser,
+            AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize)
+            throws XmlPullParserException, IOException {
+        Animator anim = null;
+        ArrayList<Animator> childAnims = null;
+
+        // Make sure we are on a start tag.
+        int type;
+        int depth = parser.getDepth();
+
+        while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
+                && type != XmlPullParser.END_DOCUMENT) {
+
+            if (type != XmlPullParser.START_TAG) {
+                continue;
+            }
+
+            String name = parser.getName();
+            boolean gotValues = false;
+
+            if (name.equals("objectAnimator")) {
+                anim = loadObjectAnimator(context, res, theme, attrs, pixelSize, parser);
+            } else if (name.equals("animator")) {
+                anim = loadAnimator(context, res, theme, attrs, null, pixelSize, parser);
+            } else if (name.equals("set")) {
+                anim = new AnimatorSet();
+                TypedArray a = TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                        AndroidResources.STYLEABLE_ANIMATOR_SET);
+
+                int ordering = TypedArrayUtils.getNamedInt(a, parser, "ordering",
+                        AndroidResources.STYLEABLE_ANIMATOR_SET_ORDERING, TOGETHER);
+
+                createAnimatorFromXml(context, res, theme, parser, attrs, (AnimatorSet) anim,
+                        ordering, pixelSize);
+                a.recycle();
+            } else if (name.equals("propertyValuesHolder")) {
+                PropertyValuesHolder[] values = loadValues(context, res, theme, parser,
+                        Xml.asAttributeSet(parser));
+                if (values != null && anim != null && (anim instanceof ValueAnimator)) {
+                    ((ValueAnimator) anim).setValues(values);
+                }
+                gotValues = true;
+            } else {
+                throw new RuntimeException("Unknown animator name: " + parser.getName());
+            }
+
+            if (parent != null && !gotValues) {
+                if (childAnims == null) {
+                    childAnims = new ArrayList<Animator>();
+                }
+                childAnims.add(anim);
+            }
+        }
+        if (parent != null && childAnims != null) {
+            Animator[] animsArray = new Animator[childAnims.size()];
+            int index = 0;
+            for (Animator a : childAnims) {
+                animsArray[index++] = a;
+            }
+            if (sequenceOrdering == TOGETHER) {
+                parent.playTogether(animsArray);
+            } else {
+                parent.playSequentially(animsArray);
+            }
+        }
+        return anim;
+    }
+
+    private static PropertyValuesHolder[] loadValues(Context context, Resources res, Theme theme,
+            XmlPullParser parser, AttributeSet attrs) throws XmlPullParserException, IOException {
+        ArrayList<PropertyValuesHolder> values = null;
+
+        int type;
+        while ((type = parser.getEventType()) != XmlPullParser.END_TAG
+                && type != XmlPullParser.END_DOCUMENT) {
+
+            if (type != XmlPullParser.START_TAG) {
+                parser.next();
+                continue;
+            }
+
+            String name = parser.getName();
+
+            if (name.equals("propertyValuesHolder")) {
+                TypedArray a = TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                        AndroidResources.STYLEABLE_PROPERTY_VALUES_HOLDER);
+
+                String propertyName = TypedArrayUtils.getNamedString(a, parser, "propertyName",
+                        AndroidResources.STYLEABLE_PROPERTY_VALUES_HOLDER_PROPERTY_NAME);
+                int valueType = TypedArrayUtils.getNamedInt(a, parser, "valueType",
+                        AndroidResources.STYLEABLE_PROPERTY_VALUES_HOLDER_VALUE_TYPE,
+                        VALUE_TYPE_UNDEFINED);
+
+                PropertyValuesHolder pvh = loadPvh(context, res, theme, parser, propertyName,
+                        valueType);
+                if (pvh == null) {
+                    pvh = getPVH(a, valueType,
+                            AndroidResources.STYLEABLE_PROPERTY_VALUES_HOLDER_VALUE_FROM,
+                            AndroidResources.STYLEABLE_PROPERTY_VALUES_HOLDER_VALUE_TO,
+                            propertyName);
+                }
+                if (pvh != null) {
+                    if (values == null) {
+                        values = new ArrayList<PropertyValuesHolder>();
+                    }
+                    values.add(pvh);
+                }
+                a.recycle();
+            }
+
+            parser.next();
+        }
+
+        PropertyValuesHolder[] valuesArray = null;
+        if (values != null) {
+            int count = values.size();
+            valuesArray = new PropertyValuesHolder[count];
+            for (int i = 0; i < count; ++i) {
+                valuesArray[i] = values.get(i);
+            }
+        }
+        return valuesArray;
+    }
+
+    // When no value type is provided in keyframe, we need to infer the type from the value. i.e.
+    // if value is defined in the style of a color value, then the color type is returned.
+    // Otherwise, default float type is returned.
+    private static int inferValueTypeOfKeyframe(Resources res, Theme theme, AttributeSet attrs,
+            XmlPullParser parser) {
+        int valueType;
+        TypedArray a = TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                AndroidResources.STYLEABLE_KEYFRAME);
+
+        TypedValue keyframeValue = TypedArrayUtils.peekNamedValue(a, parser, "value",
+                AndroidResources.STYLEABLE_KEYFRAME_VALUE);
+        boolean hasValue = (keyframeValue != null);
+        // When no value type is provided, check whether it's a color type first.
+        // If not, fall back to default value type (i.e. float type).
+        if (hasValue && isColorType(keyframeValue.type)) {
+            valueType = VALUE_TYPE_COLOR;
+        } else {
+            valueType = VALUE_TYPE_FLOAT;
+        }
+        a.recycle();
+        return valueType;
+    }
+
+    private static int inferValueTypeFromValues(TypedArray styledAttributes, int valueFromId,
+            int valueToId) {
+        TypedValue tvFrom = styledAttributes.peekValue(valueFromId);
+        boolean hasFrom = (tvFrom != null);
+        int fromType = hasFrom ? tvFrom.type : 0;
+        TypedValue tvTo = styledAttributes.peekValue(valueToId);
+        boolean hasTo = (tvTo != null);
+        int toType = hasTo ? tvTo.type : 0;
+
+        int valueType;
+        // Check whether it's color type. If not, fall back to default type (i.e. float type)
+        if ((hasFrom && isColorType(fromType)) || (hasTo && isColorType(toType))) {
+            valueType = VALUE_TYPE_COLOR;
+        } else {
+            valueType = VALUE_TYPE_FLOAT;
+        }
+        return valueType;
+    }
+
+    private static void dumpKeyframes(Object[] keyframes, String header) {
+        if (keyframes == null || keyframes.length == 0) {
+            return;
+        }
+        Log.d(TAG, header);
+        int count = keyframes.length;
+        for (int i = 0; i < count; ++i) {
+            Keyframe keyframe = (Keyframe) keyframes[i];
+            Log.d(TAG, "Keyframe " + i + ": fraction "
+                    + (keyframe.getFraction() < 0 ? "null" : keyframe.getFraction()) + ", "
+                    + ", value : " + ((keyframe.hasValue()) ? keyframe.getValue() : "null"));
+        }
+    }
+
+    // Load property values holder if there are keyframes defined in it. Otherwise return null.
+    private static PropertyValuesHolder loadPvh(Context context, Resources res, Theme theme,
+            XmlPullParser parser,
+            String propertyName, int valueType)
+            throws XmlPullParserException, IOException {
+
+        PropertyValuesHolder value = null;
+        ArrayList<Keyframe> keyframes = null;
+
+        int type;
+        while ((type = parser.next()) != XmlPullParser.END_TAG
+                && type != XmlPullParser.END_DOCUMENT) {
+            String name = parser.getName();
+            if (name.equals("keyframe")) {
+                if (valueType == VALUE_TYPE_UNDEFINED) {
+                    valueType = inferValueTypeOfKeyframe(res, theme, Xml.asAttributeSet(parser),
+                            parser);
+                }
+                Keyframe keyframe = loadKeyframe(context, res, theme, Xml.asAttributeSet(parser),
+                        valueType, parser);
+                if (keyframe != null) {
+                    if (keyframes == null) {
+                        keyframes = new ArrayList<Keyframe>();
+                    }
+                    keyframes.add(keyframe);
+                }
+                parser.next();
+            }
+        }
+
+        int count;
+        if (keyframes != null && (count = keyframes.size()) > 0) {
+            // make sure we have keyframes at 0 and 1
+            // If we have keyframes with set fractions, add keyframes at start/end
+            // appropriately. If start/end have no set fractions:
+            // if there's only one keyframe, set its fraction to 1 and add one at 0
+            // if >1 keyframe, set the last fraction to 1, the first fraction to 0
+            Keyframe firstKeyframe = keyframes.get(0);
+            Keyframe lastKeyframe = keyframes.get(count - 1);
+            float endFraction = lastKeyframe.getFraction();
+            if (endFraction < 1) {
+                if (endFraction < 0) {
+                    lastKeyframe.setFraction(1);
+                } else {
+                    keyframes.add(keyframes.size(), createNewKeyframe(lastKeyframe, 1));
+                    ++count;
+                }
+            }
+            float startFraction = firstKeyframe.getFraction();
+            if (startFraction != 0) {
+                if (startFraction < 0) {
+                    firstKeyframe.setFraction(0);
+                } else {
+                    keyframes.add(0, createNewKeyframe(firstKeyframe, 0));
+                    ++count;
+                }
+            }
+            Keyframe[] keyframeArray = new Keyframe[count];
+            keyframes.toArray(keyframeArray);
+            for (int i = 0; i < count; ++i) {
+                Keyframe keyframe = keyframeArray[i];
+                if (keyframe.getFraction() < 0) {
+                    if (i == 0) {
+                        keyframe.setFraction(0);
+                    } else if (i == count - 1) {
+                        keyframe.setFraction(1);
+                    } else {
+                        // figure out the start/end parameters of the current gap
+                        // in fractions and distribute the gap among those keyframes
+                        int startIndex = i;
+                        int endIndex = i;
+                        for (int j = startIndex + 1; j < count - 1; ++j) {
+                            if (keyframeArray[j].getFraction() >= 0) {
+                                break;
+                            }
+                            endIndex = j;
+                        }
+                        float gap = keyframeArray[endIndex + 1].getFraction()
+                                - keyframeArray[startIndex - 1].getFraction();
+                        distributeKeyframes(keyframeArray, gap, startIndex, endIndex);
+                    }
+                }
+            }
+            value = PropertyValuesHolder.ofKeyframe(propertyName, keyframeArray);
+            if (valueType == VALUE_TYPE_COLOR) {
+                value.setEvaluator(ArgbEvaluator.getInstance());
+            }
+        }
+
+        return value;
+    }
+
+    private static Keyframe createNewKeyframe(Keyframe sampleKeyframe, float fraction) {
+        return sampleKeyframe.getType() == float.class
+                ? Keyframe.ofFloat(fraction) :
+                (sampleKeyframe.getType() == int.class)
+                        ? Keyframe.ofInt(fraction) :
+                        Keyframe.ofObject(fraction);
+    }
+
+    /**
+     * Utility function to set fractions on keyframes to cover a gap in which the
+     * fractions are not currently set. Keyframe fractions will be distributed evenly
+     * in this gap. For example, a gap of 1 keyframe in the range 0-1 will be at .5, a gap
+     * of .6 spread between two keyframes will be at .2 and .4 beyond the fraction at the
+     * keyframe before startIndex.
+     * Assumptions:
+     * - First and last keyframe fractions (bounding this spread) are already set. So,
+     * for example, if no fractions are set, we will already set first and last keyframe
+     * fraction values to 0 and 1.
+     * - startIndex must be >0 (which follows from first assumption).
+     * - endIndex must be >= startIndex.
+     *
+     * @param keyframes  the array of keyframes
+     * @param gap        The total gap we need to distribute
+     * @param startIndex The index of the first keyframe whose fraction must be set
+     * @param endIndex   The index of the last keyframe whose fraction must be set
+     */
+    private static void distributeKeyframes(Keyframe[] keyframes, float gap,
+            int startIndex, int endIndex) {
+        int count = endIndex - startIndex + 2;
+        float increment = gap / count;
+        for (int i = startIndex; i <= endIndex; ++i) {
+            keyframes[i].setFraction(keyframes[i - 1].getFraction() + increment);
+        }
+    }
+
+    private static Keyframe loadKeyframe(Context context, Resources res, Theme theme,
+            AttributeSet attrs,
+            int valueType, XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+
+        TypedArray a = TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                AndroidResources.STYLEABLE_KEYFRAME);
+
+        Keyframe keyframe = null;
+
+        float fraction = TypedArrayUtils.getNamedFloat(a, parser, "fraction",
+                AndroidResources.STYLEABLE_KEYFRAME_FRACTION, -1);
+
+        TypedValue keyframeValue = TypedArrayUtils.peekNamedValue(a, parser, "value",
+                AndroidResources.STYLEABLE_KEYFRAME_VALUE);
+        boolean hasValue = (keyframeValue != null);
+        if (valueType == VALUE_TYPE_UNDEFINED) {
+            // When no value type is provided, check whether it's a color type first.
+            // If not, fall back to default value type (i.e. float type).
+            if (hasValue && isColorType(keyframeValue.type)) {
+                valueType = VALUE_TYPE_COLOR;
+            } else {
+                valueType = VALUE_TYPE_FLOAT;
+            }
+        }
+
+        if (hasValue) {
+            switch (valueType) {
+                case VALUE_TYPE_FLOAT:
+                    float value = TypedArrayUtils.getNamedFloat(a, parser, "value",
+                            AndroidResources.STYLEABLE_KEYFRAME_VALUE, 0);
+                    keyframe = Keyframe.ofFloat(fraction, value);
+                    break;
+                case VALUE_TYPE_COLOR:
+                case VALUE_TYPE_INT:
+                    int intValue = TypedArrayUtils.getNamedInt(a, parser, "value",
+                            AndroidResources.STYLEABLE_KEYFRAME_VALUE, 0);
+                    keyframe = Keyframe.ofInt(fraction, intValue);
+                    break;
+            }
+        } else {
+            keyframe = (valueType == VALUE_TYPE_FLOAT) ? Keyframe.ofFloat(fraction) :
+                    Keyframe.ofInt(fraction);
+        }
+
+        final int resID = TypedArrayUtils.getNamedResId(a, parser, "interpolator",
+                AndroidResources.STYLEABLE_KEYFRAME_INTERPOLATOR, 0);
+        if (resID > 0) {
+            final Interpolator interpolator = AnimationUtilsCompat.loadInterpolator(context, resID);
+            keyframe.setInterpolator(interpolator);
+        }
+        a.recycle();
+
+        return keyframe;
+    }
+
+    private static ObjectAnimator loadObjectAnimator(Context context, Resources res, Theme theme,
+            AttributeSet attrs,
+            float pathErrorScale, XmlPullParser parser) throws NotFoundException {
+        ObjectAnimator anim = new ObjectAnimator();
+
+        loadAnimator(context, res, theme, attrs, anim, pathErrorScale, parser);
+
+        return anim;
+    }
+
+    /**
+     * Creates a new animation whose parameters come from the specified context
+     * and attributes set.
+     *
+     * @param res   The resources
+     * @param attrs The set of attributes holding the animation parameters
+     * @param anim  Null if this is a ValueAnimator, otherwise this is an
+     */
+    private static ValueAnimator loadAnimator(Context context, Resources res, Theme theme,
+            AttributeSet attrs, ValueAnimator anim, float pathErrorScale, XmlPullParser parser)
+            throws NotFoundException {
+        TypedArray arrayAnimator = TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                AndroidResources.STYLEABLE_ANIMATOR);
+        TypedArray arrayObjectAnimator = TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                AndroidResources.STYLEABLE_PROPERTY_ANIMATOR);
+
+        if (anim == null) {
+            anim = new ValueAnimator();
+        }
+
+        parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator, pathErrorScale,
+                parser);
+
+        final int resID = TypedArrayUtils.getNamedResId(arrayAnimator, parser, "interpolator",
+                AndroidResources.STYLEABLE_ANIMATOR_INTERPOLATOR, 0);
+        if (resID > 0) {
+            final Interpolator interpolator = AnimationUtilsCompat.loadInterpolator(context, resID);
+            anim.setInterpolator(interpolator);
+        }
+
+        arrayAnimator.recycle();
+        if (arrayObjectAnimator != null) {
+            arrayObjectAnimator.recycle();
+        }
+        return anim;
+    }
+
+    private static boolean isColorType(int type) {
+        return (type >= TypedValue.TYPE_FIRST_COLOR_INT) && (type
+                <= TypedValue.TYPE_LAST_COLOR_INT);
+    }
+}
+
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/ArgbEvaluator.java b/graphics/drawable/animated/src/android/support/graphics/drawable/ArgbEvaluator.java
new file mode 100644
index 0000000..cca0de6
--- /dev/null
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/ArgbEvaluator.java
@@ -0,0 +1,94 @@
+/*
+ * 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.graphics.drawable;
+
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
+
+/**
+ * This evaluator can be used to perform type interpolation between integer
+ * values that represent ARGB colors.
+ * @hide
+ */
+public class ArgbEvaluator implements TypeEvaluator {
+    private static final ArgbEvaluator sInstance = new ArgbEvaluator();
+
+    /**
+     * Returns an instance of <code>ArgbEvaluator</code> that may be used in
+     * {@link ValueAnimator#setEvaluator(TypeEvaluator)}. The same instance may
+     * be used in multiple <code>Animator</code>s because it holds no state.
+     *
+     * @return An instance of <code>ArgbEvalutor</code>.
+     * @hide
+     */
+    public static ArgbEvaluator getInstance() {
+        return sInstance;
+    }
+
+    /**
+     * This function returns the calculated in-between value for a color
+     * given integers that represent the start and end values in the four
+     * bytes of the 32-bit int. Each channel is separately linearly interpolated
+     * and the resulting calculated values are recombined into the return value.
+     *
+     * @param fraction   The fraction from the starting to the ending values
+     * @param startValue A 32-bit int value representing colors in the
+     *                   separate bytes of the parameter
+     * @param endValue   A 32-bit int value representing colors in the
+     *                   separate bytes of the parameter
+     * @return A value that is calculated to be the linearly interpolated
+     * result, derived by separating the start and end values into separate
+     * color channels and interpolating each one separately, recombining the
+     * resulting values in the same way.
+     */
+    public Object evaluate(float fraction, Object startValue, Object endValue) {
+        int startInt = (Integer) startValue;
+        float startA = ((startInt >> 24) & 0xff) / 255.0f;
+        float startR = ((startInt >> 16) & 0xff) / 255.0f;
+        float startG = ((startInt >> 8) & 0xff) / 255.0f;
+        float startB = ((startInt) & 0xff) / 255.0f;
+
+        int endInt = (Integer) endValue;
+        float endA = ((endInt >> 24) & 0xff) / 255.0f;
+        float endR = ((endInt >> 16) & 0xff) / 255.0f;
+        float endG = ((endInt >> 8) & 0xff) / 255.0f;
+        float endB = ((endInt) & 0xff) / 255.0f;
+
+        // convert from sRGB to linear
+        startR = (float) Math.pow(startR, 2.2);
+        startG = (float) Math.pow(startG, 2.2);
+        startB = (float) Math.pow(startB, 2.2);
+
+        endR = (float) Math.pow(endR, 2.2);
+        endG = (float) Math.pow(endG, 2.2);
+        endB = (float) Math.pow(endB, 2.2);
+
+        // compute the interpolated color in linear space
+        float a = startA + fraction * (endA - startA);
+        float r = startR + fraction * (endR - startR);
+        float g = startG + fraction * (endG - startG);
+        float b = startB + fraction * (endB - startB);
+
+        // convert back to sRGB in the [0..255] range
+        a = a * 255.0f;
+        r = (float) Math.pow(r, 1.0 / 2.2) * 255.0f;
+        g = (float) Math.pow(g, 1.0 / 2.2) * 255.0f;
+        b = (float) Math.pow(b, 1.0 / 2.2) * 255.0f;
+
+        return Math.round(a) << 24 | Math.round(r) << 16 | Math.round(g) << 8 | Math.round(b);
+    }
+}
diff --git a/graphics/drawable/animated/src/android/support/graphics/drawable/PathInterpolatorCompat.java b/graphics/drawable/animated/src/android/support/graphics/drawable/PathInterpolatorCompat.java
new file mode 100644
index 0000000..0288fe4
--- /dev/null
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/PathInterpolatorCompat.java
@@ -0,0 +1,222 @@
+/*
+ * 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.graphics.drawable;
+
+import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
+
+import static java.lang.Math.abs;
+import static java.lang.Math.min;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
+import android.support.annotation.RestrictTo;
+import android.util.AttributeSet;
+import android.view.InflateException;
+import android.view.animation.Interpolator;
+
+import org.xmlpull.v1.XmlPullParser;
+
+/**
+ * An interpolator that can traverse a Path that extends from <code>Point</code>
+ * <code>(0, 0)</code> to <code>(1, 1)</code>. The x coordinate along the <code>Path</code>
+ * is the input value and the output is the y coordinate of the line at that point.
+ * This means that the Path must conform to a function <code>y = f(x)</code>.
+ *
+ * <p>The <code>Path</code> must not have gaps in the x direction and must not
+ * loop back on itself such that there can be two points sharing the same x coordinate.
+ * It is alright to have a disjoint line in the vertical direction:</p>
+ * <p><blockquote><pre>
+ *     Path path = new Path();
+ *     path.lineTo(0.25f, 0.25f);
+ *     path.moveTo(0.25f, 0.5f);
+ *     path.lineTo(1f, 1f);
+ * </pre></blockquote></p>
+ * @hide
+ */
+@RestrictTo(LIBRARY_GROUP)
+public class PathInterpolatorCompat implements Interpolator {
+
+    // This governs how accurate the approximation of the Path is.
+    private static final float PRECISION = 0.002f;
+    public static final int MAX_NUM_POINTS = 3000;
+    public static final double EPSILON = 0.00001;
+
+    private float[] mX; // x coordinates in the line
+
+    private float[] mY; // y coordinates in the line
+
+    public PathInterpolatorCompat(Context context, AttributeSet attrs, XmlPullParser parser) {
+        this(context.getResources(), context.getTheme(), attrs, parser);
+    }
+
+    public PathInterpolatorCompat(Resources res, Resources.Theme theme, AttributeSet attrs,
+            XmlPullParser parser) {
+        TypedArray a = TypedArrayUtils.obtainAttributes(res, theme,
+                attrs, AndroidResources.STYLEABLE_PATH_INTERPOLATOR);
+        parseInterpolatorFromTypeArray(a, parser);
+        a.recycle();
+    }
+
+    private void parseInterpolatorFromTypeArray(TypedArray a, XmlPullParser parser) {
+        // If there is pathData defined in the xml file, then the controls points
+        // will be all coming from pathData.
+        if (TypedArrayUtils.hasAttribute(parser, "pathData")) {
+            String pathData = TypedArrayUtils.getNamedString(a, parser, "pathData",
+                    AndroidResources.STYLEABLE_PATH_INTERPOLATOR_PATH_DATA);
+            Path path = PathParser.createPathFromPathData(pathData);
+            if (path == null) {
+                throw new InflateException("The path is null, which is created"
+                        + " from " + pathData);
+            }
+            initPath(path);
+        } else {
+            if (!TypedArrayUtils.hasAttribute(parser, "controlX1")) {
+                throw new InflateException("pathInterpolator requires the controlX1 attribute");
+            } else if (!TypedArrayUtils.hasAttribute(parser, "controlY1")) {
+                throw new InflateException("pathInterpolator requires the controlY1 attribute");
+            }
+            float x1 = TypedArrayUtils.getNamedFloat(a, parser, "controlX1",
+                    AndroidResources.STYLEABLE_PATH_INTERPOLATOR_CONTROL_X_1, 0);
+            float y1 = TypedArrayUtils.getNamedFloat(a, parser, "controlY1",
+                    AndroidResources.STYLEABLE_PATH_INTERPOLATOR_CONTROL_Y_1, 0);
+
+            boolean hasX2 = TypedArrayUtils.hasAttribute(parser, "controlX2");
+            boolean hasY2 = TypedArrayUtils.hasAttribute(parser, "controlY2");
+
+            if (hasX2 != hasY2) {
+                throw new InflateException("pathInterpolator requires both controlX2 and"
+                        + " controlY2 for cubic Beziers.");
+            }
+
+            if (!hasX2) {
+                initQuad(x1, y1);
+            } else {
+                float x2 = TypedArrayUtils.getNamedFloat(a, parser, "controlX2",
+                        AndroidResources.STYLEABLE_PATH_INTERPOLATOR_CONTROL_X_2, 0);
+                float y2 = TypedArrayUtils.getNamedFloat(a, parser, "controlY2",
+                        AndroidResources.STYLEABLE_PATH_INTERPOLATOR_CONTROL_Y_2, 0);
+                initCubic(x1, y1, x2, y2);
+            }
+        }
+    }
+
+    private void initQuad(float controlX, float controlY) {
+        Path path = new Path();
+        path.moveTo(0, 0);
+        path.quadTo(controlX, controlY, 1f, 1f);
+        initPath(path);
+    }
+
+    private void initCubic(float x1, float y1, float x2, float y2) {
+        Path path = new Path();
+        path.moveTo(0, 0);
+        path.cubicTo(x1, y1, x2, y2, 1f, 1f);
+        initPath(path);
+    }
+
+    private void initPath(Path path) {
+        final PathMeasure pathMeasure = new PathMeasure(path, false /* forceClosed */);
+
+        final float pathLength = pathMeasure.getLength();
+        final int numPoints = min(MAX_NUM_POINTS, (int) (pathLength / PRECISION) + 1);
+
+        if (numPoints <= 0) {
+            throw new IllegalArgumentException("The Path has a invalid length " + pathLength);
+        }
+
+        mX = new float[numPoints];
+        mY = new float[numPoints];
+
+        final float[] position = new float[2];
+        for (int i = 0; i < numPoints; ++i) {
+            final float distance = (i * pathLength) / (numPoints - 1);
+            pathMeasure.getPosTan(distance, position, null /* tangent */);
+
+            mX[i] = position[0];
+            mY[i] = position[1];
+        }
+
+        if (abs(mX[0]) > EPSILON || abs(mY[0]) > EPSILON || abs(mX[numPoints - 1] - 1) > EPSILON
+                || abs(mY[numPoints - 1] - 1) > EPSILON) {
+            throw new IllegalArgumentException("The Path must start at (0,0) and end at (1,1)"
+                    + " start: " + mX[0] + "," + mY[0] + " end:" + mX[numPoints - 1] + ","
+                    + mY[numPoints - 1]);
+
+        }
+
+        float prevX = 0;
+        int componentIndex = 0;
+        for (int i = 0; i < numPoints; i++) {
+            float x = mX[componentIndex++];
+            if (x < prevX) {
+                throw new IllegalArgumentException("The Path cannot loop back on itself, x :" + x);
+            }
+            mX[i] = x;
+            prevX = x;
+        }
+
+        if (pathMeasure.nextContour()) {
+            throw new IllegalArgumentException("The Path should be continuous,"
+                    + " can't have 2+ contours");
+        }
+    }
+
+    /**
+     * Using the line in the Path in this interpolator that can be described as
+     * <code>y = f(x)</code>, finds the y coordinate of the line given <code>t</code>
+     * as the x coordinate. Values less than 0 will always return 0 and values greater
+     * than 1 will always return 1.
+     *
+     * @param t Treated as the x coordinate along the line.
+     * @return The y coordinate of the Path along the line where x = <code>t</code>.
+     * @see Interpolator#getInterpolation(float)
+     */
+    @Override
+    public float getInterpolation(float t) {
+        if (t <= 0) {
+            return 0;
+        } else if (t >= 1) {
+            return 1;
+        }
+        // Do a binary search for the correct x to interpolate between.
+        int startIndex = 0;
+        int endIndex = mX.length - 1;
+
+        while (endIndex - startIndex > 1) {
+            int midIndex = (startIndex + endIndex) / 2;
+            if (t < mX[midIndex]) {
+                endIndex = midIndex;
+            } else {
+                startIndex = midIndex;
+            }
+        }
+
+        float xRange = mX[endIndex] - mX[startIndex];
+        if (xRange == 0) {
+            return mY[startIndex];
+        }
+
+        float tInRange = t - mX[startIndex];
+        float fraction = tInRange / xRange;
+
+        float startY = mY[startIndex];
+        float endY = mY[endIndex];
+        return startY + (fraction * (endY - startY));
+    }
+}
diff --git a/graphics/drawable/animated/tests/res/anim/animation_grouping_1_01.xml b/graphics/drawable/animated/tests/res/anim/animation_grouping_1_01.xml
index 3119237..e63ed5d 100644
--- a/graphics/drawable/animated/tests/res/anim/animation_grouping_1_01.xml
+++ b/graphics/drawable/animated/tests/res/anim/animation_grouping_1_01.xml
@@ -19,8 +19,9 @@
 
     <objectAnimator
             android:duration="50"
-            android:propertyName="rotation"
-            android:valueFrom="0"
-            android:valueTo="180"
+            android:propertyName="pathData"
+            android:valueFrom="m -25 0 a 25,25 0 1,0 50,0 a 25,25 0 1,0 -50,0"
+            android:valueTo="m -125 0 a 125,125 0 1,0 250,0 a 125,125 0 1,0 -250,0"
+            android:valueType="pathType"
             android:repeatCount="2"/>
 </set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/animation_rect.xml b/graphics/drawable/animated/tests/res/anim/animation_rect.xml
new file mode 100644
index 0000000..4f045aa
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/animation_rect.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.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <objectAnimator
+            android:duration="50"
+            android:propertyName="pathData"
+            android:valueFrom="M0,0L24,0L24,24L0,24z"
+            android:valueTo="M0,0L0,0L0,0L0,0z"
+            android:valueType="pathType"
+            android:repeatCount="2"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/animation_rect_exception.xml b/graphics/drawable/animated/tests/res/anim/animation_rect_exception.xml
new file mode 100644
index 0000000..6d74dc3
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/animation_rect_exception.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.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <objectAnimator
+            android:duration="50"
+            android:propertyName="pathData"
+            android:valueFrom="M0,0L24,0L24,24L0,24z"
+            android:valueTo="m0,0l0,0l0,0l0,0z"
+            android:valueType="pathType"
+            android:repeatCount="2"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/shift_to_center_1.xml b/graphics/drawable/animated/tests/res/anim/shift_to_center_1.xml
new file mode 100644
index 0000000..5c577ec
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/shift_to_center_1.xml
@@ -0,0 +1,31 @@
+<?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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateX"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@interpolator/control_points_interpolator"/>
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateY"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@interpolator/single_control_point_interpolator"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/shift_to_center_2.xml b/graphics/drawable/animated/tests/res/anim/shift_to_center_2.xml
new file mode 100644
index 0000000..9e0fcb8
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/shift_to_center_2.xml
@@ -0,0 +1,32 @@
+<?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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateX"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@interpolator/path_interpolator"/>
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateY"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@android:interpolator/fast_out_slow_in"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_1.xml b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_1.xml
new file mode 100644
index 0000000..dd04c4a
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_1.xml
@@ -0,0 +1,25 @@
+<?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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateX"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@interpolator/wrong_control_point_interpolator"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_2.xml b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_2.xml
new file mode 100644
index 0000000..51ccf7f
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_2.xml
@@ -0,0 +1,26 @@
+<?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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateX"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@interpolator/wrong_control_points_interpolator"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_3.xml b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_3.xml
new file mode 100644
index 0000000..1927dac
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_3.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.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateX"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@interpolator/wrong_path_interpolator_1"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_4.xml b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_4.xml
new file mode 100644
index 0000000..514a0aa
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_4.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.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateX"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@interpolator/wrong_path_interpolator_2"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_5.xml b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_5.xml
new file mode 100644
index 0000000..2aa27fd
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/anim/shift_to_center_exception_5.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.
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+     android:ordering="together">
+    <objectAnimator
+        android:duration="50"
+        android:propertyName="translateX"
+        android:valueFrom="0"
+        android:valueTo="12"
+        android:interpolator="@interpolator/wrong_path_interpolator_3"/>
+</set>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_1.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_1.xml
new file mode 100644
index 0000000..08849ef
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_1.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/small_rect">
+
+    <target
+            android:name="rectGroup"
+            android:animation="@anim/shift_to_center_1"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_2.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_2.xml
new file mode 100644
index 0000000..dac3f2c
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_2.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/small_rect">
+
+    <target
+            android:name="rectGroup"
+            android:animation="@anim/shift_to_center_2"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_1.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_1.xml
new file mode 100644
index 0000000..1f69741
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_1.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/small_rect">
+
+    <target
+            android:name="rectGroup"
+            android:animation="@anim/shift_to_center_exception_1"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_2.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_2.xml
new file mode 100644
index 0000000..893505d
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_2.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/small_rect">
+
+    <target
+            android:name="rectGroup"
+            android:animation="@anim/shift_to_center_exception_2"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_3.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_3.xml
new file mode 100644
index 0000000..a384fa5
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_3.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/small_rect">
+
+    <target
+            android:name="rectGroup"
+            android:animation="@anim/shift_to_center_exception_3"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_4.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_4.xml
new file mode 100644
index 0000000..951c46e
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_4.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/small_rect">
+
+    <target
+            android:name="rectGroup"
+            android:animation="@anim/shift_to_center_exception_4"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_5.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_5.xml
new file mode 100644
index 0000000..32cb93c6
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_interpolator_exception_5.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/small_rect">
+
+    <target
+            android:name="rectGroup"
+            android:animation="@anim/shift_to_center_exception_5"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_morphing_rect.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_morphing_rect.xml
new file mode 100644
index 0000000..c849405
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_morphing_rect.xml
@@ -0,0 +1,22 @@
+<!--
+  ~ 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/rect">
+
+    <target
+            android:name="rectBody"
+            android:animation="@anim/animation_rect"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_path_morphing_rect_exception.xml b/graphics/drawable/animated/tests/res/drawable/animation_path_morphing_rect_exception.xml
new file mode 100644
index 0000000..0a30135
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_path_morphing_rect_exception.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/rect">
+
+    <target
+            android:name="rectBody"
+            android:animation="@anim/animation_rect_exception"/>
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/animation_vector_drawable_circle.xml b/graphics/drawable/animated/tests/res/drawable/animation_vector_drawable_circle.xml
new file mode 100644
index 0000000..11d7924
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/animation_vector_drawable_circle.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+                 android:drawable="@drawable/vector_drawable_circle">
+
+    <target
+            android:name="sun"
+            android:animation="@anim/animation_grouping_1_01"/>
+
+</animated-vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/drawable/rect.xml b/graphics/drawable/animated/tests/res/drawable/rect.xml
index b1fe3fc..5b162f5 100644
--- a/graphics/drawable/animated/tests/res/drawable/rect.xml
+++ b/graphics/drawable/animated/tests/res/drawable/rect.xml
@@ -26,8 +26,6 @@
         <path
                 android:name="rectBody"
                 android:fillColor="#ff0000"
-                android:strokeColor="#ff0000"
-                android:strokeWidth="2"
                 android:pathData="M0,0L24,0L24,24L0,24z" />
 
     </group>
diff --git a/graphics/drawable/animated/tests/res/drawable/small_rect.xml b/graphics/drawable/animated/tests/res/drawable/small_rect.xml
new file mode 100644
index 0000000..2c8d714
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/small_rect.xml
@@ -0,0 +1,28 @@
+<!--
+  ~ 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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportHeight="24.0"
+        android:viewportWidth="24.0">
+    <group
+        android:name="rectGroup">
+        <path
+                android:name="rectBody"
+                android:fillColor="#ff0000"
+                android:pathData="m-2,-2l4,0l0,4l-4,0z" />
+    </group>
+</vector>
diff --git a/graphics/drawable/animated/tests/res/drawable/vector_drawable_circle.xml b/graphics/drawable/animated/tests/res/drawable/vector_drawable_circle.xml
new file mode 100644
index 0000000..eab00d3
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/drawable/vector_drawable_circle.xml
@@ -0,0 +1,53 @@
+<!--
+  ~ 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.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="64dp"
+        android:height="64dp"
+        android:viewportHeight="256"
+        android:viewportWidth="256">
+
+    <group
+        android:name="shape_layer_1"
+        android:translateX="128"
+        android:translateY="128">
+        <group android:name="sun"
+               android:scaleX="2"
+               android:scaleY="2">
+            <path
+                android:name="ellipse_path_1"
+                android:fillColor="#ffff8000"
+                android:pathData="m -25 0 a 25,25 0 1,0 50,0 a 25,25 0 1,0 -50,0"/>
+
+            <group
+                android:name="earth">
+                <path
+                    android:name="ellipse_path_1_1"
+                    android:fillColor="#ff5656ea"
+                    android:pathData="m -10 0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0"/>
+
+                <group
+                    android:name="moon">
+                    <path
+                        android:name="ellipse_path_1_2"
+                        android:fillColor="#ffadadad"
+                        android:pathData="m -5 0 a 5,5 0 1,0 10,0 a 5,5 0 1,0 -10,0"/>
+                </group>
+            </group>
+
+        </group>
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/animated/tests/res/interpolator/control_points_interpolator.xml b/graphics/drawable/animated/tests/res/interpolator/control_points_interpolator.xml
new file mode 100644
index 0000000..109eff1
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/interpolator/control_points_interpolator.xml
@@ -0,0 +1,23 @@
+<?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.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:controlX1="0"
+                  android:controlY1="0"
+                  android:controlX2="0"
+                  android:controlY2="1"/>
diff --git a/graphics/drawable/animated/tests/res/interpolator/path_interpolator.xml b/graphics/drawable/animated/tests/res/interpolator/path_interpolator.xml
new file mode 100644
index 0000000..014df4f
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/interpolator/path_interpolator.xml
@@ -0,0 +1,19 @@
+<?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.
+  -->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.08,0.0 0.04,1.0 0.2,0.8 l 0.6,0.1 L 1.0,1.0"/>
diff --git a/graphics/drawable/animated/tests/res/interpolator/single_control_point_interpolator.xml b/graphics/drawable/animated/tests/res/interpolator/single_control_point_interpolator.xml
new file mode 100644
index 0000000..81ff055
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/interpolator/single_control_point_interpolator.xml
@@ -0,0 +1,21 @@
+<?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.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:controlX1="1"
+                  android:controlY1="0"/>
diff --git a/graphics/drawable/animated/tests/res/interpolator/wrong_control_point_interpolator.xml b/graphics/drawable/animated/tests/res/interpolator/wrong_control_point_interpolator.xml
new file mode 100644
index 0000000..9012023
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/interpolator/wrong_control_point_interpolator.xml
@@ -0,0 +1,20 @@
+<?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.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:controlX1="1"/>
diff --git a/graphics/drawable/animated/tests/res/interpolator/wrong_control_points_interpolator.xml b/graphics/drawable/animated/tests/res/interpolator/wrong_control_points_interpolator.xml
new file mode 100644
index 0000000..26b7e5b
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/interpolator/wrong_control_points_interpolator.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:controlX1="0"
+                  android:controlY1="0"
+                  android:controlX2="0"/>
diff --git a/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_1.xml b/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_1.xml
new file mode 100644
index 0000000..bb90ec6
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_1.xml
@@ -0,0 +1,19 @@
+<?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.
+  -->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.08,0.0 0.04,1.0 0.2,0.8 l 0.6,0.1 L 1.3,1.0"/>
diff --git a/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_2.xml b/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_2.xml
new file mode 100644
index 0000000..f889dfa
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_2.xml
@@ -0,0 +1,20 @@
+<?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.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.5 0.5 l -0.4 0.5 L 1.0,1.0"/>
diff --git a/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_3.xml b/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_3.xml
new file mode 100644
index 0000000..800304e
--- /dev/null
+++ b/graphics/drawable/animated/tests/res/interpolator/wrong_path_interpolator_3.xml
@@ -0,0 +1,20 @@
+<?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.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 l 0.5 0.5 m -0.4 0.5 L 1.0,1.0"/>
diff --git a/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/AnimatedVectorDrawableTest.java b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/AnimatedVectorDrawableTest.java
index aeaaf2a..b598f23 100644
--- a/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/AnimatedVectorDrawableTest.java
+++ b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/AnimatedVectorDrawableTest.java
@@ -16,24 +16,34 @@
 
 package android.support.graphics.drawable.tests;
 
+import static android.support.graphics.drawable.tests.DrawableUtils.saveVectorDrawableIntoPNG;
+
 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.junit.Assert.fail;
+
+import static java.lang.Thread.sleep;
 
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Drawable.ConstantState;
 import android.support.annotation.DrawableRes;
+import android.support.graphics.drawable.Animatable2Compat.AnimationCallback;
 import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
 import android.support.graphics.drawable.animated.test.R;
+import android.support.test.InstrumentationRegistry;
+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.view.ViewCompat;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.Xml;
 import android.view.View;
 import android.widget.ImageButton;
@@ -45,8 +55,6 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import java.io.File;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -55,12 +63,18 @@
 @RunWith(AndroidJUnit4.class)
 public class AnimatedVectorDrawableTest {
     @Rule public final ActivityTestRule<DrawableStubActivity> mActivityTestRule;
+
+    private static final float PIXEL_ERROR_THRESHOLD = 0.3f;
+    private static final float PIXEL_DIFF_THRESHOLD = 0.03f;
+    private static final float PIXEL_DIFF_COUNT_THRESHOLD = 0.1f;
+
     private static final String LOGTAG = AnimatedVectorDrawableTest.class.getSimpleName();
 
     private static final int IMAGE_WIDTH = 64;
     private static final int IMAGE_HEIGHT = 64;
-    private static final @DrawableRes int DRAWABLE_RES_ID =
-            R.drawable.animation_vector_drawable_grouping_1;
+
+    @DrawableRes
+    private static final int DRAWABLE_RES_ID = R.drawable.animation_vector_drawable_grouping_1;
 
     private Context mContext;
     private Resources mResources;
@@ -69,6 +83,26 @@
     private Canvas mCanvas;
     private static final boolean DBG_DUMP_PNG = false;
 
+    // States to check for animation callback tests.
+    private boolean mAnimationStarted = false;
+    private boolean mAnimationEnded = false;
+
+    // Animation callback used for all callback related tests.
+    private AnimationCallback mAnimationCallback =
+            new AnimationCallback() {
+                @Override
+                public void onAnimationStart(
+                        Drawable drawable) {
+                    mAnimationStarted = true;
+                }
+
+                @Override
+                public void onAnimationEnd(
+                        Drawable drawable) {
+                    mAnimationEnded = true;
+                }
+            };
+
     public AnimatedVectorDrawableTest() {
         mActivityTestRule = new ActivityTestRule<>(DrawableStubActivity.class);
     }
@@ -83,37 +117,6 @@
         mAnimatedVectorDrawable = AnimatedVectorDrawableCompat.create(mContext, DRAWABLE_RES_ID);
     }
 
-    // This is only for debugging or golden image (re)generation purpose.
-    private void saveVectorDrawableIntoPNG(Bitmap bitmap, int resId) throws IOException {
-        // Save the image to the disk.
-        FileOutputStream out = null;
-        try {
-            String outputFolder = "/sdcard/temp/";
-            File folder = new File(outputFolder);
-            if (!folder.exists()) {
-                folder.mkdir();
-            }
-            String originalFilePath = mResources.getString(resId);
-            File originalFile = new File(originalFilePath);
-            String fileFullName = originalFile.getName();
-            String fileTitle = fileFullName.substring(0, fileFullName.lastIndexOf("."));
-            String outputFilename = outputFolder + fileTitle + "_golden.png";
-            File outputFile = new File(outputFilename);
-            if (!outputFile.exists()) {
-                outputFile.createNewFile();
-            }
-
-            out = new FileOutputStream(outputFile, false);
-            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
-            Log.v(LOGTAG, "Write test No." + outputFilename + " to file successfully.");
-        } catch (Exception e) {
-            e.printStackTrace();
-        } finally {
-            if (out != null) {
-                out.close();
-            }
-        }
-    }
 
     @Test
     public void testInflate() throws Exception {
@@ -141,10 +144,109 @@
         assertTrue(earthColor == 0xFF5656EA);
 
         if (DBG_DUMP_PNG) {
-            saveVectorDrawableIntoPNG(mBitmap, DRAWABLE_RES_ID);
+            saveVectorDrawableIntoPNG(mResources, mBitmap, DRAWABLE_RES_ID, null);
         }
     }
 
+    /**
+     * Render AVD sequence in an bitmap for several frames with the same content, and make sure
+     * there is no image corruptions.
+     *
+     * @throws IOException only if DBG_DUMP_PNG is true when dumping images for debugging purpose.
+     */
+    @Test
+    public void testRenderCorrectness() throws IOException {
+        final int numTests = 5;
+        final Bitmap bitmap = Bitmap.createBitmap(IMAGE_WIDTH, IMAGE_WIDTH,
+                Bitmap.Config.ARGB_8888);
+        final Canvas c = new Canvas(bitmap);
+
+        final AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(mContext,
+                R.drawable.animation_vector_drawable_circle);
+        avd.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                avd.start();
+            }
+        });
+
+        // First make sure the content is drawn into the bitmap.
+        // Then save the first frame as the golden images.
+        bitmap.eraseColor(0);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                avd.draw(c);
+            }
+        });
+        int centerColor = bitmap.getPixel(IMAGE_WIDTH / 2 , IMAGE_WIDTH / 2);
+        assertTrue(centerColor != 0);
+        Bitmap firstFrame = Bitmap.createBitmap(bitmap);
+        if (DBG_DUMP_PNG) {
+            saveVectorDrawableIntoPNG(mResources, firstFrame, -1, "firstframe");
+        }
+
+        // Now compare the following frames with the 1st frames. Expect some minor difference like
+        // Anti-Aliased edges, so the compare is fuzzy.
+        for (int i = 0; i < numTests; i++) {
+            bitmap.eraseColor(0);
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    avd.draw(c);
+                }
+            });
+            if (DBG_DUMP_PNG) {
+                saveVectorDrawableIntoPNG(mResources, bitmap, -1, "correctness_" + i);
+            }
+            compareImages(firstFrame, bitmap, "correctness_" + i);
+        }
+    }
+
+    /**
+     * Utility function for fuzzy image comparison b/t 2 bitmap. Failed if the difference is bigger
+     * than a threshold.
+     */
+    private void compareImages(Bitmap ideal, Bitmap given, String filename) {
+        int idealWidth = ideal.getWidth();
+        int idealHeight = ideal.getHeight();
+
+        assertTrue(idealWidth == given.getWidth());
+        assertTrue(idealHeight == given.getHeight());
+
+        int totalDiffPixelCount = 0;
+        float totalPixelCount = idealWidth * idealHeight;
+        for (int x = 0; x < idealWidth; x++) {
+            for (int y = 0; y < idealHeight; y++) {
+                int idealColor = ideal.getPixel(x, y);
+                int givenColor = given.getPixel(x, y);
+                if (idealColor == givenColor) {
+                    continue;
+                }
+
+                float totalError = 0;
+                totalError += Math.abs(Color.red(idealColor) - Color.red(givenColor));
+                totalError += Math.abs(Color.green(idealColor) - Color.green(givenColor));
+                totalError += Math.abs(Color.blue(idealColor) - Color.blue(givenColor));
+                totalError += Math.abs(Color.alpha(idealColor) - Color.alpha(givenColor));
+
+                if ((totalError / 1024.0f) >= PIXEL_ERROR_THRESHOLD) {
+                    fail((filename + ": totalError is " + totalError));
+                }
+
+                if ((totalError / 1024.0f) >= PIXEL_DIFF_THRESHOLD) {
+                    totalDiffPixelCount++;
+                }
+            }
+        }
+        if ((totalDiffPixelCount / totalPixelCount) >= PIXEL_DIFF_COUNT_THRESHOLD) {
+            fail((filename + ": totalDiffPixelCount is " + totalDiffPixelCount));
+        }
+
+    }
+
     @Test
     public void testGetChangingConfigurations() {
         AnimatedVectorDrawableCompat d1 = AnimatedVectorDrawableCompat.create(mContext,
@@ -211,7 +313,7 @@
         // Check the view several times during the animation to verify that it only
         // has red color in it
         for (int i = 0; i < numTests; ++i) {
-            Thread.sleep(100);
+            sleep(100);
             // check fill
             verifyRedOnly(pixelX, pixelY, imageButton, bitmap, c, latch);
             // check stroke
@@ -274,4 +376,161 @@
             assertEquals(d1.mutate(), d1);
         }
     }
+
+    /**
+     * A helper function to setup the AVDC for callback tests.
+     */
+    private AnimatedVectorDrawableCompat setupAnimatedVectorDrawableCompat() {
+        final ImageButton imageButton =
+                (ImageButton) mActivityTestRule.getActivity().findViewById(R.id.imageButton);
+        mAnimationStarted = false;
+        mAnimationEnded = false;
+
+        AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(mContext,
+                R.drawable.animation_vector_drawable_grouping_1); // Duration is 50 ms.
+        ViewCompat.setBackground(imageButton, avd);
+        return avd;
+    }
+
+    @Test
+    /**
+     * Test show that callback is successfully registered.
+     * Note that this test requires screen is on.
+     */
+    public void testRegisterCallback() throws Throwable {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                AnimatedVectorDrawableCompat avd = setupAnimatedVectorDrawableCompat();
+                avd.registerAnimationCallback(mAnimationCallback);
+                avd.start();
+            }
+        });
+        Thread.sleep(500);
+        assertTrue(mAnimationStarted);
+        assertTrue(mAnimationEnded);
+    }
+
+    @Test
+    /**
+     * Test show that callback is successfully removed.
+     * Note that this test requires screen is on.
+     */
+    public void testClearCallback() throws Throwable {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                AnimatedVectorDrawableCompat avd =
+                        setupAnimatedVectorDrawableCompat();
+                avd.registerAnimationCallback(mAnimationCallback);
+                avd.clearAnimationCallbacks();
+                avd.start();
+            }
+        });
+        Thread.sleep(500);
+        assertFalse(mAnimationStarted);
+        assertFalse(mAnimationEnded);
+    }
+
+    @Test
+    /**
+     * Test show that callback is successfully unregistered.
+     * Note that this test requires screen is on.
+     */
+    public void testUnregisterCallback() throws Throwable {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                AnimatedVectorDrawableCompat avd =
+                        setupAnimatedVectorDrawableCompat();
+
+                avd.registerAnimationCallback(mAnimationCallback);
+                avd.unregisterAnimationCallback(mAnimationCallback);
+                avd.start();
+            }
+        });
+        Thread.sleep(500);
+        assertFalse(mAnimationStarted);
+        assertFalse(mAnimationEnded);
+    }
+
+    /**
+     * Render AVD with path morphing, make sure the bitmap is different when it render at the start
+     * and the end.
+     *
+     * @throws Exception for time out or I/O problem while dumping debug images.
+     */
+    @Test
+    public void testPathMorphing() throws Exception {
+        final Object lock = new Object();
+        final Bitmap bitmap = Bitmap.createBitmap(IMAGE_WIDTH, IMAGE_WIDTH,
+                Bitmap.Config.ARGB_8888);
+        final Canvas c = new Canvas(bitmap);
+
+        final AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(mContext,
+                R.drawable.animation_path_morphing_rect);
+        avd.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+
+        bitmap.eraseColor(0);
+        avd.draw(c);
+        int centerColor = bitmap.getPixel(IMAGE_WIDTH / 2 , IMAGE_WIDTH / 2);
+        assertTrue(centerColor == 0xffff0000);
+
+        if (DBG_DUMP_PNG) {
+            saveVectorDrawableIntoPNG(mResources, bitmap, -1, "start");
+        }
+
+        avd.registerAnimationCallback(new AnimationCallback() {
+            @Override
+            public void onAnimationStart(Drawable drawable) {
+                // Nothing to do.
+            }
+
+            @Override
+            public void onAnimationEnd(Drawable drawable) {
+                bitmap.eraseColor(0);
+                drawable.draw(c);
+                int centerColor = bitmap.getPixel(IMAGE_WIDTH / 2 , IMAGE_WIDTH / 2);
+                assertTrue(centerColor == 0);
+
+                synchronized (lock) {
+                    lock.notify();
+                }
+            }
+        });
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                avd.start();
+            }
+        });
+
+        synchronized (lock) {
+            lock.wait(1000);
+        }
+
+        if (DBG_DUMP_PNG) {
+            saveVectorDrawableIntoPNG(mResources, bitmap, -1, "ended");
+        }
+    }
+
+    /**
+     * Make sure when path didn't match, we got an exception.
+     */
+    @Test
+    @UiThreadTest
+    public void testPathMorphingException() throws Exception {
+        boolean hasException = false;
+        try {
+            final AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(mContext,
+                    R.drawable.animation_path_morphing_rect_exception);
+        } catch (Exception e) {
+            // Expected to come in here, so nothing happen.
+            hasException = true;
+        }
+
+        assertTrue(hasException);
+
+    }
 }
diff --git a/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/DrawableUtils.java b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/DrawableUtils.java
new file mode 100644
index 0000000..0bd1137
--- /dev/null
+++ b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/DrawableUtils.java
@@ -0,0 +1,72 @@
+/*
+ * 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.graphics.drawable.tests;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+
+public class DrawableUtils {
+
+    private static final String LOGTAG = DrawableUtils.class.getSimpleName();
+
+    // This is only for debugging or golden image (re)generation purpose.
+    public static void saveVectorDrawableIntoPNG(Resources resource, Bitmap bitmap, int resId,
+            String filename) throws IOException {
+        // Save the image to the disk.
+        FileOutputStream out = null;
+        try {
+            String outputFolder = "/sdcard/temp/";
+            File folder = new File(outputFolder);
+            if (!folder.exists()) {
+                folder.mkdir();
+            }
+            String fileTitle = "unname";
+            if (resId >= 0) {
+                String originalFilePath = resource.getString(resId);
+                File originalFile = new File(originalFilePath);
+                String fileFullName = originalFile.getName();
+                fileTitle = fileFullName.substring(0, fileFullName.lastIndexOf("."));
+                if (filename != null) {
+                    fileTitle += "_" + filename;
+                }
+            } else if (filename != null) {
+                fileTitle = filename;
+            }
+            String outputFilename = outputFolder + fileTitle + "_golden.png";
+            File outputFile = new File(outputFilename);
+            if (!outputFile.exists()) {
+                outputFile.createNewFile();
+            }
+
+            out = new FileOutputStream(outputFile, false);
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+            Log.v(LOGTAG, "Write test No." + outputFilename + " to file successfully.");
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+}
diff --git a/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/PathInterpolatorExceptionParameterizedTest.java b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/PathInterpolatorExceptionParameterizedTest.java
new file mode 100644
index 0000000..ba7051f
--- /dev/null
+++ b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/PathInterpolatorExceptionParameterizedTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.graphics.drawable.tests;
+
+import android.app.Activity;
+import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
+import android.support.graphics.drawable.animated.test.R;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@MediumTest
+@RunWith(Parameterized.class)
+public class PathInterpolatorExceptionParameterizedTest {
+    @Rule
+    public ActivityTestRule<DrawableStubActivity> mActivityRule =
+            new ActivityTestRule<>(DrawableStubActivity.class);
+
+
+    private Activity mActivity = null;
+    private int mResId;
+
+    @Rule
+    public ExpectedException thrown = ExpectedException.none();
+
+    @Parameterized.Parameters
+    public static Object[] data() {
+        return new Object[]{
+                R.drawable.animation_path_interpolator_exception_1, // missing control point
+                R.drawable.animation_path_interpolator_exception_2, // missing control points
+                R.drawable.animation_path_interpolator_exception_3, // not from 0,0 to 1,1
+                R.drawable.animation_path_interpolator_exception_4, // loop back
+                R.drawable.animation_path_interpolator_exception_5, // 2 contour
+        };
+    }
+
+    public PathInterpolatorExceptionParameterizedTest(final int resId) throws Throwable {
+        mResId = resId;
+    }
+
+    @Before
+    public void setup() {
+        mActivity = mActivityRule.getActivity();
+    }
+
+    @Test
+    public void testPathMorphingExceptions() throws Exception {
+        thrown.expect(RuntimeException.class);
+        final AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(mActivity,
+                mResId);
+    }
+}
diff --git a/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/PathInterpolatorParameterizedTest.java b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/PathInterpolatorParameterizedTest.java
new file mode 100644
index 0000000..dfa6df9
--- /dev/null
+++ b/graphics/drawable/animated/tests/src/android/support/graphics/drawable/tests/PathInterpolatorParameterizedTest.java
@@ -0,0 +1,125 @@
+/*
+ * 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.graphics.drawable.tests;
+
+import static android.support.graphics.drawable.tests.DrawableUtils.saveVectorDrawableIntoPNG;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.drawable.Drawable;
+import android.support.graphics.drawable.Animatable2Compat;
+import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
+import android.support.graphics.drawable.animated.test.R;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.rule.ActivityTestRule;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@MediumTest
+@RunWith(Parameterized.class)
+public class PathInterpolatorParameterizedTest {
+    @Rule
+    public ActivityTestRule<DrawableStubActivity> mActivityRule =
+            new ActivityTestRule<>(DrawableStubActivity.class);
+
+    private static final int IMAGE_WIDTH = 64;
+    private static final int IMAGE_HEIGHT = 64;
+
+    private Activity mActivity = null;
+    private int mResId;
+
+    private static final boolean DBG_DUMP_PNG = false;
+
+    @Parameterized.Parameters
+    public static Object[] data() {
+        return new Object[] {
+                R.drawable.animation_path_interpolator_1,
+                R.drawable.animation_path_interpolator_2,
+        };
+    }
+
+    public PathInterpolatorParameterizedTest(final int resId) throws Throwable {
+        mResId = resId;
+    }
+
+    @Before
+    public void setup() {
+        mActivity = mActivityRule.getActivity();
+    }
+
+    @Test
+    public void testPathMorphing() throws Exception {
+        final Object lock = new Object();
+        final Bitmap bitmap = Bitmap.createBitmap(IMAGE_WIDTH, IMAGE_WIDTH,
+                Bitmap.Config.ARGB_8888);
+        final Canvas c = new Canvas(bitmap);
+
+        final AnimatedVectorDrawableCompat avd = AnimatedVectorDrawableCompat.create(mActivity,
+                mResId);
+        avd.setBounds(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT);
+
+        bitmap.eraseColor(0);
+        avd.draw(c);
+        int centerColor = bitmap.getPixel(IMAGE_WIDTH / 2 , IMAGE_WIDTH / 2);
+        Assert.assertTrue(centerColor == 0);
+
+        if (DBG_DUMP_PNG) {
+            saveVectorDrawableIntoPNG(mActivity.getResources(), bitmap, mResId, "start");
+        }
+
+        avd.registerAnimationCallback(new Animatable2Compat.AnimationCallback() {
+            @Override
+            public void onAnimationStart(Drawable drawable) {
+                // Nothing to do.
+            }
+
+            @Override
+            public void onAnimationEnd(Drawable drawable) {
+                bitmap.eraseColor(0);
+                drawable.draw(c);
+                int centerColor = bitmap.getPixel(IMAGE_WIDTH / 2 , IMAGE_WIDTH / 2);
+                Assert.assertTrue(centerColor == 0xffff0000);
+
+                synchronized (lock) {
+                    lock.notify();
+                }
+            }
+        });
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                avd.start();
+            }
+        });
+
+        synchronized (lock) {
+            lock.wait(1000);
+        }
+
+        if (DBG_DUMP_PNG) {
+            saveVectorDrawableIntoPNG(mActivity.getResources(), bitmap, mResId, "end");
+        }
+    }
+}
diff --git a/graphics/drawable/static/AndroidManifest.xml b/graphics/drawable/static/AndroidManifest.xml
index 0383e4c..14821a8 100644
--- a/graphics/drawable/static/AndroidManifest.xml
+++ b/graphics/drawable/static/AndroidManifest.xml
@@ -16,6 +16,7 @@
   -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.support.graphics.drawable">
-    <application/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/AndroidResources.java b/graphics/drawable/static/src/android/support/graphics/drawable/AndroidResources.java
index 165d011..5db0b8b 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/AndroidResources.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/AndroidResources.java
@@ -17,66 +17,131 @@
 class AndroidResources {
 
     // Resources ID generated in the latest R.java for framework.
-    static final int[] styleable_VectorDrawableTypeArray = {
+    static final int[] STYLEABLE_VECTOR_DRAWABLE_TYPE_ARRAY = {
             android.R.attr.name, android.R.attr.tint, android.R.attr.height,
             android.R.attr.width, android.R.attr.alpha, android.R.attr.autoMirrored,
             android.R.attr.tintMode, android.R.attr.viewportWidth, android.R.attr.viewportHeight
     };
-    static final int styleable_VectorDrawable_alpha = 4;
-    static final int styleable_VectorDrawable_autoMirrored = 5;
-    static final int styleable_VectorDrawable_height = 2;
-    static final int styleable_VectorDrawable_name = 0;
-    static final int styleable_VectorDrawable_tint = 1;
-    static final int styleable_VectorDrawable_tintMode = 6;
-    static final int styleable_VectorDrawable_viewportHeight = 8;
-    static final int styleable_VectorDrawable_viewportWidth = 7;
-    static final int styleable_VectorDrawable_width = 3;
-    static final int[] styleable_VectorDrawableGroup = {
+    static final int STYLEABLE_VECTOR_DRAWABLE_ALPHA = 4;
+    static final int STYLEABLE_VECTOR_DRAWABLE_AUTO_MIRRORED = 5;
+    static final int STYLEABLE_VECTOR_DRAWABLE_HEIGHT = 2;
+    static final int STYLEABLE_VECTOR_DRAWABLE_NAME = 0;
+    static final int STYLEABLE_VECTOR_DRAWABLE_TINT = 1;
+    static final int STYLEABLE_VECTOR_DRAWABLE_TINT_MODE = 6;
+    static final int STYLEABLE_VECTOR_DRAWABLE_VIEWPORT_HEIGHT = 8;
+    static final int STYLEABLE_VECTOR_DRAWABLE_VIEWPORT_WIDTH = 7;
+    static final int STYLEABLE_VECTOR_DRAWABLE_WIDTH = 3;
+    static final int[] STYLEABLE_VECTOR_DRAWABLE_GROUP = {
             android.R.attr.name, android.R.attr.pivotX, android.R.attr.pivotY,
             android.R.attr.scaleX, android.R.attr.scaleY, android.R.attr.rotation,
             android.R.attr.translateX, android.R.attr.translateY
     };
-    static final int styleable_VectorDrawableGroup_name = 0;
-    static final int styleable_VectorDrawableGroup_pivotX = 1;
-    static final int styleable_VectorDrawableGroup_pivotY = 2;
-    static final int styleable_VectorDrawableGroup_rotation = 5;
-    static final int styleable_VectorDrawableGroup_scaleX = 3;
-    static final int styleable_VectorDrawableGroup_scaleY = 4;
-    static final int styleable_VectorDrawableGroup_translateX = 6;
-    static final int styleable_VectorDrawableGroup_translateY = 7;
-    static final int[] styleable_VectorDrawablePath = {
+    static final int STYLEABLE_VECTOR_DRAWABLE_GROUP_NAME = 0;
+    static final int STYLEABLE_VECTOR_DRAWABLE_GROUP_PIVOT_X = 1;
+    static final int STYLEABLE_VECTOR_DRAWABLE_GROUP_PIVOT_Y = 2;
+    static final int STYLEABLE_VECTOR_DRAWABLE_GROUP_ROTATION = 5;
+    static final int STYLEABLE_VECTOR_DRAWABLE_GROUP_SCALE_X = 3;
+    static final int STYLEABLE_VECTOR_DRAWABLE_GROUP_SCALE_Y = 4;
+    static final int STYLEABLE_VECTOR_DRAWABLE_GROUP_TRANSLATE_X = 6;
+    static final int STYLEABLE_VECTOR_DRAWABLE_GROUP_TRANSLATE_Y = 7;
+    static final int[] STYLEABLE_VECTOR_DRAWABLE_PATH = {
             android.R.attr.name, android.R.attr.fillColor, android.R.attr.pathData,
             android.R.attr.strokeColor, android.R.attr.strokeWidth, android.R.attr.trimPathStart,
             android.R.attr.trimPathEnd, android.R.attr.trimPathOffset, android.R.attr.strokeLineCap,
             android.R.attr.strokeLineJoin, android.R.attr.strokeMiterLimit,
-            android.R.attr.strokeAlpha, android.R.attr.fillAlpha
+            android.R.attr.strokeAlpha, android.R.attr.fillAlpha, android.R.attr.fillType
     };
-    static final int styleable_VectorDrawablePath_fillAlpha = 12;
-    static final int styleable_VectorDrawablePath_fillColor = 1;
-    static final int styleable_VectorDrawablePath_name = 0;
-    static final int styleable_VectorDrawablePath_pathData = 2;
-    static final int styleable_VectorDrawablePath_strokeAlpha = 11;
-    static final int styleable_VectorDrawablePath_strokeColor = 3;
-    static final int styleable_VectorDrawablePath_strokeLineCap = 8;
-    static final int styleable_VectorDrawablePath_strokeLineJoin = 9;
-    static final int styleable_VectorDrawablePath_strokeMiterLimit = 10;
-    static final int styleable_VectorDrawablePath_strokeWidth = 4;
-    static final int styleable_VectorDrawablePath_trimPathEnd = 6;
-    static final int styleable_VectorDrawablePath_trimPathOffset = 7;
-    static final int styleable_VectorDrawablePath_trimPathStart = 5;
-    static final int[] styleable_VectorDrawableClipPath = {
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_FILL_ALPHA = 12;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_FILL_COLOR = 1;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_NAME = 0;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_PATH_DATA = 2;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_ALPHA = 11;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_COLOR = 3;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_LINE_CAP = 8;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_LINE_JOIN = 9;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_MITER_LIMIT = 10;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_WIDTH = 4;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_TRIM_PATH_END = 6;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_TRIM_PATH_OFFSET = 7;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_TRIM_PATH_START = 5;
+    static final int STYLEABLE_VECTOR_DRAWABLE_PATH_TRIM_PATH_FILLTYPE = 13;
+    static final int[] STYLEABLE_VECTOR_DRAWABLE_CLIP_PATH = {
             android.R.attr.name, android.R.attr.pathData
     };
-    static final int styleable_VectorDrawableClipPath_name = 0;
-    static final int styleable_VectorDrawableClipPath_pathData = 1;
+    static final int STYLEABLE_VECTOR_DRAWABLE_CLIP_PATH_NAME = 0;
+    static final int STYLEABLE_VECTOR_DRAWABLE_CLIP_PATH_PATH_DATA = 1;
 
-    static final int[] styleable_AnimatedVectorDrawable = {
+    static final int[] STYLEABLE_ANIMATED_VECTOR_DRAWABLE = {
             android.R.attr.drawable
     };
-    static final int styleable_AnimatedVectorDrawable_drawable = 0;
-    static final int[] styleable_AnimatedVectorDrawableTarget = {
+    static final int STYLEABLE_ANIMATED_VECTOR_DRAWABLE_DRAWABLE = 0;
+    static final int[] STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET = {
             android.R.attr.name, android.R.attr.animation
     };
-    static final int styleable_AnimatedVectorDrawableTarget_animation = 1;
-    static final int styleable_AnimatedVectorDrawableTarget_name = 0;
+    static final int STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET_ANIMATION = 1;
+    static final int STYLEABLE_ANIMATED_VECTOR_DRAWABLE_TARGET_NAME = 0;
+
+    /////////////////////////////////////////////////////////////////////
+
+    public static final int[] STYLEABLE_ANIMATOR = {
+            0x01010141, 0x01010198, 0x010101be, 0x010101bf,
+            0x010101c0, 0x010102de, 0x010102df, 0x010102e0,
+            0x0111009c
+    };
+
+    public static final int STYLEABLE_ANIMATOR_INTERPOLATOR = 0;
+    public static final int STYLEABLE_ANIMATOR_DURATION = 1;
+    public static final int STYLEABLE_ANIMATOR_START_OFFSET = 2;
+    public static final int STYLEABLE_ANIMATOR_REPEAT_COUNT = 3;
+    public static final int STYLEABLE_ANIMATOR_REPEAT_MODE = 4;
+    public static final int STYLEABLE_ANIMATOR_VALUE_FROM = 5;
+    public static final int STYLEABLE_ANIMATOR_VALUE_TO = 6;
+    public static final int STYLEABLE_ANIMATOR_VALUE_TYPE = 7;
+    public static final int STYLEABLE_ANIMATOR_REMOVE_BEFORE_M_RELEASE = 8;
+    public static final int[] STYLEABLE_ANIMATOR_SET = {
+            0x010102e2
+    };
+    public static final int STYLEABLE_ANIMATOR_SET_ORDERING = 0;
+
+    public static final int[] STYLEABLE_PROPERTY_VALUES_HOLDER = {
+            0x010102de, 0x010102df, 0x010102e0, 0x010102e1
+    };
+    public static final int STYLEABLE_PROPERTY_VALUES_HOLDER_VALUE_FROM = 0;
+    public static final int STYLEABLE_PROPERTY_VALUES_HOLDER_VALUE_TO = 1;
+    public static final int STYLEABLE_PROPERTY_VALUES_HOLDER_VALUE_TYPE = 2;
+    public static final int STYLEABLE_PROPERTY_VALUES_HOLDER_PROPERTY_NAME = 3;
+
+    public static final int[] STYLEABLE_KEYFRAME = {
+            0x01010024, 0x01010141, 0x010102e0, 0x010104d8
+    };
+    public static final int STYLEABLE_KEYFRAME_VALUE = 0;
+    public static final int STYLEABLE_KEYFRAME_INTERPOLATOR = 1;
+    public static final int STYLEABLE_KEYFRAME_VALUE_TYPE = 2;
+    public static final int STYLEABLE_KEYFRAME_FRACTION = 3;
+
+    public static final int[] STYLEABLE_PROPERTY_ANIMATOR = {
+            0x010102e1, 0x01010405, 0x01010474, 0x01010475
+    };
+    public static final int STYLEABLE_PROPERTY_ANIMATOR_PROPERTY_NAME = 0;
+    public static final int STYLEABLE_PROPERTY_ANIMATOR_PATH_DATA = 1;
+    public static final int STYLEABLE_PROPERTY_ANIMATOR_PROPERTY_X_NAME = 2;
+    public static final int STYLEABLE_PROPERTY_ANIMATOR_PROPERTY_Y_NAME = 3;
+
+
+    public static final int[] STYLEABLE_PATH_INTERPOLATOR = {
+            0x010103fc, 0x010103fd, 0x010103fe, 0x010103ff,
+            0x01010405
+    };
+
+    public static final int STYLEABLE_PATH_INTERPOLATOR_CONTROL_X_1 = 0;
+    public static final int STYLEABLE_PATH_INTERPOLATOR_CONTROL_Y_1 = 1;
+
+    public static final int STYLEABLE_PATH_INTERPOLATOR_CONTROL_X_2 = 2;
+    public static final int STYLEABLE_PATH_INTERPOLATOR_CONTROL_Y_2 = 3;
+
+    public static final int STYLEABLE_PATH_INTERPOLATOR_PATH_DATA = 4;
+
+    public static final int FAST_OUT_LINEAR_IN = 0x010c000f;
+    public static final int FAST_OUT_SLOW_IN = 0x010c000d;
+    public static final int LINEAR_OUT_SLOW_IN = 0x010c000e;
 }
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java b/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java
index a9b1d1d..086fc9d 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java
@@ -1,15 +1,17 @@
 /*
  * 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
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.graphics.drawable;
@@ -132,8 +134,8 @@
         }
 
         for (int i = 0; i < nodesFrom.length; i++) {
-            if (nodesFrom[i].type != nodesTo[i].type
-                    || nodesFrom[i].params.length != nodesTo[i].params.length) {
+            if (nodesFrom[i].mType != nodesTo[i].mType
+                    || nodesFrom[i].mParams.length != nodesTo[i].mParams.length) {
                 return false;
             }
         }
@@ -149,9 +151,9 @@
      */
     public static void updateNodes(PathDataNode[] target, PathDataNode[] source) {
         for (int i = 0; i < source.length; i++) {
-            target[i].type = source[i].type;
-            for (int j = 0; j < source[i].params.length; j++) {
-                target[i].params[j] = source[i].params[j];
+            target[i].mType = source[i].mType;
+            for (int j = 0; j < source[i].mParams.length; j++) {
+                target[i].mParams[j] = source[i].mParams[j];
             }
         }
     }
@@ -294,17 +296,17 @@
      */
     public static class PathDataNode {
         /*package*/
-        char type;
-        float[] params;
+        char mType;
+        float[] mParams;
 
         PathDataNode(char type, float[] params) {
-            this.type = type;
-            this.params = params;
+            this.mType = type;
+            this.mParams = params;
         }
 
         PathDataNode(PathDataNode n) {
-            type = n.type;
-            params = copyOfRange(n.params, 0, n.params.length);
+            mType = n.mType;
+            mParams = copyOfRange(n.mParams, 0, n.mParams.length);
         }
 
         /**
@@ -317,8 +319,8 @@
             float[] current = new float[6];
             char previousCommand = 'm';
             for (int i = 0; i < node.length; i++) {
-                addCommand(path, current, previousCommand, node[i].type, node[i].params);
-                previousCommand = node[i].type;
+                addCommand(path, current, previousCommand, node[i].mType, node[i].mParams);
+                previousCommand = node[i].mType;
             }
         }
 
@@ -332,15 +334,15 @@
          * @param fraction The fraction to interpolate.
          */
         public void interpolatePathDataNode(PathDataNode nodeFrom,
-                                            PathDataNode nodeTo, float fraction) {
-            for (int i = 0; i < nodeFrom.params.length; i++) {
-                params[i] = nodeFrom.params[i] * (1 - fraction)
-                        + nodeTo.params[i] * fraction;
+                PathDataNode nodeTo, float fraction) {
+            for (int i = 0; i < nodeFrom.mParams.length; i++) {
+                mParams[i] = nodeFrom.mParams[i] * (1 - fraction)
+                        + nodeTo.mParams[i] * fraction;
             }
         }
 
         private static void addCommand(Path path, float[] current,
-                                       char previousCmd, char cmd, float[] val) {
+                char previousCmd, char cmd, float[] val) {
 
             int incr = 2;
             float currentX = current[0];
@@ -590,15 +592,15 @@
         }
 
         private static void drawArc(Path p,
-                                    float x0,
-                                    float y0,
-                                    float x1,
-                                    float y1,
-                                    float a,
-                                    float b,
-                                    float theta,
-                                    boolean isMoreThanHalf,
-                                    boolean isPositiveArc) {
+                float x0,
+                float y0,
+                float x1,
+                float y1,
+                float a,
+                float b,
+                float theta,
+                boolean isMoreThanHalf,
+                boolean isPositiveArc) {
 
             /* Convert rotation angle from degrees to radians */
             double thetaD = Math.toRadians(theta);
@@ -681,15 +683,15 @@
          * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse
          */
         private static void arcToBezier(Path p,
-                                        double cx,
-                                        double cy,
-                                        double a,
-                                        double b,
-                                        double e1x,
-                                        double e1y,
-                                        double theta,
-                                        double start,
-                                        double sweep) {
+                double cx,
+                double cy,
+                double a,
+                double b,
+                double e1x,
+                double e1y,
+                double theta,
+                double start,
+                double sweep) {
             // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html
             // and http://www.spaceroots.org/documents/ellipse/node22.html
 
@@ -721,17 +723,15 @@
                 double q2x = e2x - alpha * ep2x;
                 double q2y = e2y - alpha * ep2y;
 
-                // Use the extra math below and relative cubicTo function, just to work around
-                // one issue with VM and proguard.
-                final float delta_q1x = (float) q1x - (float) e1x;
-                final float delta_q1y = (float) q1y - (float) e1y;
-                final float delta_q2x = (float) q2x - (float) e1x;
-                final float delta_q2y = (float) q2y - (float) e1y;
-                final float delta_e2x = (float) e2x - (float) e1x;
-                final float delta_e2y = (float) e2y - (float) e1y;
+                // Adding this no-op call to workaround a proguard related issue.
+                p.rLineTo(0, 0);
 
-                p.rCubicTo(delta_q1x, delta_q1y, delta_q2x, delta_q2y, delta_e2x, delta_e2y);
-
+                p.cubicTo((float) q1x,
+                        (float) q1y,
+                        (float) q2x,
+                        (float) q2y,
+                        (float) e2x,
+                        (float) e2y);
                 eta1 = eta2;
                 e1x = e2x;
                 e1y = e2y;
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/TypedArrayUtils.java b/graphics/drawable/static/src/android/support/graphics/drawable/TypedArrayUtils.java
index 14200c1..1e196e9 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/TypedArrayUtils.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/TypedArrayUtils.java
@@ -14,7 +14,10 @@
 
 package android.support.graphics.drawable;
 
+import android.content.res.Resources;
 import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.util.TypedValue;
 
 import org.xmlpull.v1.XmlPullParser;
 
@@ -64,4 +67,46 @@
             return a.getColor(resId, defaultValue);
         }
     }
+
+    public static String getNamedString(TypedArray a, XmlPullParser parser, String attrName,
+            int resId) {
+        final boolean hasAttr = hasAttribute(parser, attrName);
+        if (!hasAttr) {
+            return null;
+        } else {
+            return a.getString(resId);
+        }
+    }
+
+    public static int getNamedResId(TypedArray a, XmlPullParser parser, String attrName,
+            int resId, int defaultValue) {
+        final boolean hasAttr = hasAttribute(parser, attrName);
+        if (!hasAttr) {
+            return defaultValue;
+        } else {
+            return a.getResourceId(resId, defaultValue);
+        }
+    }
+
+    public static TypedValue peekNamedValue(TypedArray a, XmlPullParser parser, String attrName,
+            int resId) {
+        final boolean hasAttr = hasAttribute(parser, attrName);
+        if (!hasAttr) {
+            return null;
+        } else {
+            return a.peekValue(resId);
+        }
+    }
+
+    /**
+     * Obtains styled attributes from the theme, if available, or unstyled
+     * resources if the theme is null.
+     */
+    public static TypedArray obtainAttributes(
+            Resources res, Resources.Theme theme, AttributeSet set, int[] attrs) {
+        if (theme == null) {
+            return res.obtainAttributes(set, attrs);
+        }
+        return theme.obtainStyledAttributes(set, attrs, 0, 0);
+    }
 }
diff --git a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java
index 12b0383..fb13e92 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCommon.java
@@ -15,34 +15,18 @@
 package android.support.graphics.drawable;
 
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.ColorFilter;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v4.graphics.drawable.TintAwareDrawable;
-import android.util.AttributeSet;
 
 /**
  * Internal common delegation shared by VectorDrawableCompat and AnimatedVectorDrawableCompat
  */
 abstract class VectorDrawableCommon extends Drawable implements TintAwareDrawable {
-    /**
-     * Obtains styled attributes from the theme, if available, or unstyled
-     * resources if the theme is null.
-     *
-     * @hide
-     */
-    protected static TypedArray obtainAttributes(
-            Resources res, Resources.Theme theme, AttributeSet set, int[] attrs) {
-        if (theme == null) {
-            return res.obtainAttributes(set, attrs);
-        }
-        return theme.obtainStyledAttributes(set, attrs, 0, 0);
-    }
 
     // Drawable delegation for Lollipop and above.
     Drawable mDelegateDrawable;
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 5704d6f..69b34a0 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
@@ -618,8 +618,8 @@
         final VPathRenderer pathRenderer = new VPathRenderer();
         state.mVPathRenderer = pathRenderer;
 
-        final TypedArray a = obtainAttributes(res, theme, attrs,
-                AndroidResources.styleable_VectorDrawableTypeArray);
+        final TypedArray a = TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                AndroidResources.STYLEABLE_VECTOR_DRAWABLE_TYPE_ARRAY);
 
         updateStateFromTypedArray(a, parser);
         a.recycle();
@@ -667,24 +667,24 @@
         // state.mChangingConfigurations |= Utils.getChangingConfigurations(a);
 
         final int mode = TypedArrayUtils.getNamedInt(a, parser, "tintMode",
-                AndroidResources.styleable_VectorDrawable_tintMode, -1);
+                AndroidResources.STYLEABLE_VECTOR_DRAWABLE_TINT_MODE, -1);
         state.mTintMode = parseTintModeCompat(mode, Mode.SRC_IN);
 
         final ColorStateList tint =
-                a.getColorStateList(AndroidResources.styleable_VectorDrawable_tint);
+                a.getColorStateList(AndroidResources.STYLEABLE_VECTOR_DRAWABLE_TINT);
         if (tint != null) {
             state.mTint = tint;
         }
 
         state.mAutoMirrored = TypedArrayUtils.getNamedBoolean(a, parser, "autoMirrored",
-                AndroidResources.styleable_VectorDrawable_autoMirrored, state.mAutoMirrored);
+                AndroidResources.STYLEABLE_VECTOR_DRAWABLE_AUTO_MIRRORED, state.mAutoMirrored);
 
         pathRenderer.mViewportWidth = TypedArrayUtils.getNamedFloat(a, parser, "viewportWidth",
-                AndroidResources.styleable_VectorDrawable_viewportWidth,
+                AndroidResources.STYLEABLE_VECTOR_DRAWABLE_VIEWPORT_WIDTH,
                 pathRenderer.mViewportWidth);
 
         pathRenderer.mViewportHeight = TypedArrayUtils.getNamedFloat(a, parser, "viewportHeight",
-                AndroidResources.styleable_VectorDrawable_viewportHeight,
+                AndroidResources.STYLEABLE_VECTOR_DRAWABLE_VIEWPORT_HEIGHT,
                 pathRenderer.mViewportHeight);
 
         if (pathRenderer.mViewportWidth <= 0) {
@@ -696,9 +696,9 @@
         }
 
         pathRenderer.mBaseWidth = a.getDimension(
-                AndroidResources.styleable_VectorDrawable_width, pathRenderer.mBaseWidth);
+                AndroidResources.STYLEABLE_VECTOR_DRAWABLE_WIDTH, pathRenderer.mBaseWidth);
         pathRenderer.mBaseHeight = a.getDimension(
-                AndroidResources.styleable_VectorDrawable_height, pathRenderer.mBaseHeight);
+                AndroidResources.STYLEABLE_VECTOR_DRAWABLE_HEIGHT, pathRenderer.mBaseHeight);
         if (pathRenderer.mBaseWidth <= 0) {
             throw new XmlPullParserException(a.getPositionDescription() +
                     "<vector> tag requires width > 0");
@@ -709,10 +709,10 @@
 
         // shown up from API 11.
         final float alphaInFloat = TypedArrayUtils.getNamedFloat(a, parser, "alpha",
-                AndroidResources.styleable_VectorDrawable_alpha, pathRenderer.getAlpha());
+                AndroidResources.STYLEABLE_VECTOR_DRAWABLE_ALPHA, pathRenderer.getAlpha());
         pathRenderer.setAlpha(alphaInFloat);
 
-        final String name = a.getString(AndroidResources.styleable_VectorDrawable_name);
+        final String name = a.getString(AndroidResources.STYLEABLE_VECTOR_DRAWABLE_NAME);
         if (name != null) {
             pathRenderer.mRootName = name;
             pathRenderer.mVGTargetsMap.put(name, pathRenderer);
@@ -1223,6 +1223,8 @@
                     final Paint fillPaint = mFillPaint;
                     fillPaint.setColor(applyAlpha(fullPath.mFillColor, fullPath.mFillAlpha));
                     fillPaint.setColorFilter(filter);
+                    mRenderPath.setFillType(fullPath.mFillRule == 0 ? Path.FillType.WINDING
+                            : Path.FillType.EVEN_ODD);
                     canvas.drawPath(mRenderPath, fillPaint);
                 }
 
@@ -1362,8 +1364,8 @@
         }
 
         public void inflate(Resources res, AttributeSet attrs, Theme theme, XmlPullParser parser) {
-            final TypedArray a = obtainAttributes(res, theme, attrs,
-                    AndroidResources.styleable_VectorDrawableGroup);
+            final TypedArray a = TypedArrayUtils.obtainAttributes(res, theme, attrs,
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP);
             updateStateFromTypedArray(a, parser);
             a.recycle();
         }
@@ -1377,26 +1379,26 @@
 
             // This is added in API 11
             mRotate = TypedArrayUtils.getNamedFloat(a, parser, "rotation",
-                    AndroidResources.styleable_VectorDrawableGroup_rotation, mRotate);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP_ROTATION, mRotate);
 
-            mPivotX = a.getFloat(AndroidResources.styleable_VectorDrawableGroup_pivotX, mPivotX);
-            mPivotY = a.getFloat(AndroidResources.styleable_VectorDrawableGroup_pivotY, mPivotY);
+            mPivotX = a.getFloat(AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP_PIVOT_X, mPivotX);
+            mPivotY = a.getFloat(AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP_PIVOT_Y, mPivotY);
 
             // This is added in API 11
             mScaleX = TypedArrayUtils.getNamedFloat(a, parser, "scaleX",
-                    AndroidResources.styleable_VectorDrawableGroup_scaleX, mScaleX);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP_SCALE_X, mScaleX);
 
             // This is added in API 11
             mScaleY = TypedArrayUtils.getNamedFloat(a, parser, "scaleY",
-                    AndroidResources.styleable_VectorDrawableGroup_scaleY, mScaleY);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP_SCALE_Y, mScaleY);
 
             mTranslateX = TypedArrayUtils.getNamedFloat(a, parser, "translateX",
-                    AndroidResources.styleable_VectorDrawableGroup_translateX, mTranslateX);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP_TRANSLATE_X, mTranslateX);
             mTranslateY = TypedArrayUtils.getNamedFloat(a, parser, "translateY",
-                    AndroidResources.styleable_VectorDrawableGroup_translateY, mTranslateY);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP_TRANSLATE_Y, mTranslateY);
 
             final String groupName =
-                    a.getString(AndroidResources.styleable_VectorDrawableGroup_name);
+                    a.getString(AndroidResources.STYLEABLE_VECTOR_DRAWABLE_GROUP_NAME);
             if (groupName != null) {
                 mGroupName = groupName;
             }
@@ -1525,15 +1527,15 @@
                 indent += "    ";
             }
             Log.v(LOGTAG, indent + "current path is :" + mPathName +
-                    " pathData is " + NodesToString(mNodes));
+                    " pathData is " + nodesToString(mNodes));
 
         }
 
-        public String NodesToString(PathParser.PathDataNode[] nodes) {
+        public String nodesToString(PathParser.PathDataNode[] nodes) {
             String result = " ";
             for (int i = 0; i < nodes.length; i++) {
-                result += nodes[i].type + ":";
-                float[] params = nodes[i].params;
+                result += nodes[i].mType + ":";
+                float[] params = nodes[i].mParams;
                 for (int j = 0; j < params.length; j++) {
                     result += params[j] + ",";
                 }
@@ -1604,8 +1606,8 @@
             if (!hasPathData) {
                 return;
             }
-            final TypedArray a = obtainAttributes(r, theme, attrs,
-                    AndroidResources.styleable_VectorDrawableClipPath);
+            final TypedArray a = TypedArrayUtils.obtainAttributes(r, theme, attrs,
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_CLIP_PATH);
             updateStateFromTypedArray(a);
             a.recycle();
         }
@@ -1615,13 +1617,13 @@
             // mChangingConfigurations |= Utils.getChangingConfigurations(a);;
 
             final String pathName =
-                    a.getString(AndroidResources.styleable_VectorDrawableClipPath_name);
+                    a.getString(AndroidResources.STYLEABLE_VECTOR_DRAWABLE_CLIP_PATH_NAME);
             if (pathName != null) {
                 mPathName = pathName;
             }
 
             final String pathData =
-                    a.getString(AndroidResources.styleable_VectorDrawableClipPath_pathData);
+                    a.getString(AndroidResources.STYLEABLE_VECTOR_DRAWABLE_CLIP_PATH_PATH_DATA);
             if (pathData != null) {
                 mNodes = PathParser.createNodesFromPathData(pathData);
             }
@@ -1646,7 +1648,7 @@
 
         int mFillColor = Color.TRANSPARENT;
         float mStrokeAlpha = 1.0f;
-        int mFillRule;
+        int mFillRule = 0; // 0 is default value as "non-zero" fill type.
         float mFillAlpha = 1.0f;
         float mTrimPathStart = 0;
         float mTrimPathEnd = 1;
@@ -1711,8 +1713,8 @@
         }
 
         public void inflate(Resources r, AttributeSet attrs, Theme theme, XmlPullParser parser) {
-            final TypedArray a = obtainAttributes(r, theme, attrs,
-                    AndroidResources.styleable_VectorDrawablePath);
+            final TypedArray a = TypedArrayUtils.obtainAttributes(r, theme, attrs,
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH);
             updateStateFromTypedArray(a, parser);
             a.recycle();
         }
@@ -1736,41 +1738,47 @@
                 return;
             }
 
-            final String pathName = a.getString(AndroidResources.styleable_VectorDrawablePath_name);
+            final String pathName = a.getString(
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_NAME);
             if (pathName != null) {
                 mPathName = pathName;
             }
             final String pathData =
-                    a.getString(AndroidResources.styleable_VectorDrawablePath_pathData);
+                    a.getString(AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_PATH_DATA);
             if (pathData != null) {
                 mNodes = PathParser.createNodesFromPathData(pathData);
             }
 
             mFillColor = TypedArrayUtils.getNamedColor(a, parser, "fillColor",
-                    AndroidResources.styleable_VectorDrawablePath_fillColor, mFillColor);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_FILL_COLOR, mFillColor);
             mFillAlpha = TypedArrayUtils.getNamedFloat(a, parser, "fillAlpha",
-                    AndroidResources.styleable_VectorDrawablePath_fillAlpha, mFillAlpha);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_FILL_ALPHA, mFillAlpha);
             final int lineCap = TypedArrayUtils.getNamedInt(a, parser, "strokeLineCap",
-                    AndroidResources.styleable_VectorDrawablePath_strokeLineCap, -1);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_LINE_CAP, -1);
             mStrokeLineCap = getStrokeLineCap(lineCap, mStrokeLineCap);
             final int lineJoin = TypedArrayUtils.getNamedInt(a, parser, "strokeLineJoin",
-                    AndroidResources.styleable_VectorDrawablePath_strokeLineJoin, -1);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_LINE_JOIN, -1);
             mStrokeLineJoin = getStrokeLineJoin(lineJoin, mStrokeLineJoin);
             mStrokeMiterlimit = TypedArrayUtils.getNamedFloat(a, parser, "strokeMiterLimit",
-                    AndroidResources.styleable_VectorDrawablePath_strokeMiterLimit,
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_MITER_LIMIT,
                     mStrokeMiterlimit);
             mStrokeColor = TypedArrayUtils.getNamedColor(a, parser, "strokeColor",
-                    AndroidResources.styleable_VectorDrawablePath_strokeColor, mStrokeColor);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_COLOR, mStrokeColor);
             mStrokeAlpha = TypedArrayUtils.getNamedFloat(a, parser, "strokeAlpha",
-                    AndroidResources.styleable_VectorDrawablePath_strokeAlpha, mStrokeAlpha);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_ALPHA, mStrokeAlpha);
             mStrokeWidth = TypedArrayUtils.getNamedFloat(a, parser, "strokeWidth",
-                    AndroidResources.styleable_VectorDrawablePath_strokeWidth, mStrokeWidth);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_STROKE_WIDTH, mStrokeWidth);
             mTrimPathEnd = TypedArrayUtils.getNamedFloat(a, parser, "trimPathEnd",
-                    AndroidResources.styleable_VectorDrawablePath_trimPathEnd, mTrimPathEnd);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_TRIM_PATH_END, mTrimPathEnd);
             mTrimPathOffset = TypedArrayUtils.getNamedFloat(a, parser, "trimPathOffset",
-                    AndroidResources.styleable_VectorDrawablePath_trimPathOffset, mTrimPathOffset);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_TRIM_PATH_OFFSET,
+                    mTrimPathOffset);
             mTrimPathStart = TypedArrayUtils.getNamedFloat(a, parser, "trimPathStart",
-                    AndroidResources.styleable_VectorDrawablePath_trimPathStart, mTrimPathStart);
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_TRIM_PATH_START,
+                    mTrimPathStart);
+            mFillRule = TypedArrayUtils.getNamedInt(a, parser, "fillType",
+                    AndroidResources.STYLEABLE_VECTOR_DRAWABLE_PATH_TRIM_PATH_FILLTYPE,
+                    mFillRule);
         }
 
         @Override
diff --git a/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png b/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
new file mode 100644
index 0000000..28e9236
--- /dev/null
+++ b/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_filltype_evenodd_golden.png
Binary files differ
diff --git a/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png b/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
new file mode 100644
index 0000000..b27bdbd
--- /dev/null
+++ b/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_filltype_nonzero_golden.png
Binary files differ
diff --git a/graphics/drawable/static/tests/res/drawable/vector_icon_filltype_evenodd.xml b/graphics/drawable/static/tests/res/drawable/vector_icon_filltype_evenodd.xml
new file mode 100644
index 0000000..08fdd05
--- /dev/null
+++ b/graphics/drawable/static/tests/res/drawable/vector_icon_filltype_evenodd.xml
@@ -0,0 +1,33 @@
+<?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.
+ */
+-->
+<vector android:height="24dp" android:viewportHeight="400.0"
+        android:viewportWidth="1200.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillType="evenOdd"
+          android:fillColor="#f00"
+          android:pathData="M250,75L323,301 131,161 369,161 177,301z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+    <path android:fillType="evenOdd"
+          android:fillColor="#f00"
+          android:pathData="M600,81A107,107 0,0 1,600 295A107,107 0,0 1,600 81zM600,139A49,49 0,0 1,600 237A49,49 0,0 1,600 139z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+    <path android:fillType="evenOdd"
+          android:fillColor="#f00"
+          android:pathData="M950,81A107,107 0,0 1,950 295A107,107 0,0 1,950 81zM950,139A49,49 0,0 0,950 237A49,49 0,0 0,950 139z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/static/tests/res/drawable/vector_icon_filltype_nonzero.xml b/graphics/drawable/static/tests/res/drawable/vector_icon_filltype_nonzero.xml
new file mode 100644
index 0000000..9200d449
--- /dev/null
+++ b/graphics/drawable/static/tests/res/drawable/vector_icon_filltype_nonzero.xml
@@ -0,0 +1,33 @@
+<?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.
+ */
+-->
+<vector android:height="24dp" android:viewportHeight="400.0"
+        android:viewportWidth="1200.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillType="nonZero"
+          android:fillColor="#f00"
+          android:pathData="M250,75L323,301 131,161 369,161 177,301z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+    <path android:fillType="nonZero"
+          android:fillColor="#f00"
+          android:pathData="M600,81A107,107 0,0 1,600 295A107,107 0,0 1,600 81zM600,139A49,49 0,0 1,600 237A49,49 0,0 1,600 139z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+    <path android:fillType="nonZero"
+          android:fillColor="#f00"
+          android:pathData="M950,81A107,107 0,0 1,950 295A107,107 0,0 1,950 81zM950,139A49,49 0,0 0,950 237A49,49 0,0 0,950 139z"
+          android:strokeColor="#000" android:strokeWidth="3"/>
+</vector>
\ No newline at end of file
diff --git a/graphics/drawable/static/tests/src/android/support/graphics/drawable/tests/VectorDrawableTest.java b/graphics/drawable/static/tests/src/android/support/graphics/drawable/tests/VectorDrawableTest.java
index 97b19e7..f1b0b9a 100644
--- a/graphics/drawable/static/tests/src/android/support/graphics/drawable/tests/VectorDrawableTest.java
+++ b/graphics/drawable/static/tests/src/android/support/graphics/drawable/tests/VectorDrawableTest.java
@@ -78,6 +78,8 @@
             R.drawable.vector_icon_share,
             R.drawable.vector_icon_wishlist,
             R.drawable.vector_icon_five_bars,
+            R.drawable.vector_icon_filltype_evenodd,
+            R.drawable.vector_icon_filltype_nonzero,
     };
 
     private static final int[] GOLDEN_IMAGES = new int[]{
@@ -107,6 +109,8 @@
             R.drawable.vector_icon_share_golden,
             R.drawable.vector_icon_wishlist_golden,
             R.drawable.vector_icon_five_bars_golden,
+            R.drawable.vector_icon_filltype_evenodd_golden,
+            R.drawable.vector_icon_filltype_nonzero_golden,
     };
 
     private static final int TEST_ICON = R.drawable.vector_icon_create;
diff --git a/media-compat/AndroidManifest.xml b/media-compat/AndroidManifest.xml
index 5f7b051..7e9421e 100644
--- a/media-compat/AndroidManifest.xml
+++ b/media-compat/AndroidManifest.xml
@@ -17,6 +17,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.mediacompat">
     <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.mediacompat"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java b/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
index 4035e63..aa63588 100644
--- a/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
@@ -120,7 +120,7 @@
         public MediaBrowserService.BrowserRoot onGetRoot(String clientPackageName, int clientUid,
                 Bundle rootHints) {
             MediaBrowserServiceCompatApi21.BrowserRoot browserRoot = mServiceProxy.onGetRoot(
-                    clientPackageName, clientUid, rootHints);
+                    clientPackageName, clientUid, rootHints == null ? null : new Bundle(rootHints));
             return browserRoot == null ? null : new MediaBrowserService.BrowserRoot(
                     browserRoot.mRootId, browserRoot.mExtras);
         }
diff --git a/media-compat/api24/android/support/v4/media/MediaBrowserCompatApi24.java b/media-compat/api24/android/support/v4/media/MediaBrowserCompatApi24.java
deleted file mode 100644
index 45a428c..0000000
--- a/media-compat/api24/android/support/v4/media/MediaBrowserCompatApi24.java
+++ /dev/null
@@ -1,68 +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.v4.media;
-
-import android.annotation.TargetApi;
-import android.media.browse.MediaBrowser;
-import android.os.Bundle;
-import android.support.annotation.NonNull;
-import android.support.annotation.RequiresApi;
-
-import java.util.List;
-
-@RequiresApi(24)
-@TargetApi(24)
-class MediaBrowserCompatApi24 {
-    public static Object createSubscriptionCallback(SubscriptionCallback callback) {
-        return new SubscriptionCallbackProxy<>(callback);
-    }
-
-    public static void subscribe(Object browserObj, String parentId, Bundle options,
-            Object subscriptionCallbackObj) {
-        ((MediaBrowser) browserObj).subscribe(parentId, options,
-                (MediaBrowser.SubscriptionCallback) subscriptionCallbackObj);
-    }
-
-    public static void unsubscribe(Object browserObj, String parentId,
-            Object subscriptionCallbackObj) {
-        ((MediaBrowser) browserObj).unsubscribe(parentId,
-                (MediaBrowser.SubscriptionCallback) subscriptionCallbackObj);
-    }
-
-    interface SubscriptionCallback extends MediaBrowserCompatApi21.SubscriptionCallback {
-        void onChildrenLoaded(@NonNull String parentId, List<?> children, @NonNull Bundle options);
-        void onError(@NonNull String parentId, @NonNull  Bundle options);
-    }
-
-    static class SubscriptionCallbackProxy<T extends SubscriptionCallback>
-            extends MediaBrowserCompatApi21.SubscriptionCallbackProxy<T> {
-        public SubscriptionCallbackProxy(T callback) {
-            super(callback);
-        }
-
-        @Override
-        public void onChildrenLoaded(@NonNull String parentId,
-                List<MediaBrowser.MediaItem> children, @NonNull Bundle options) {
-            mSubscriptionCallback.onChildrenLoaded(parentId, children, options);
-        }
-
-        @Override
-        public void onError(@NonNull String parentId, @NonNull Bundle options) {
-            mSubscriptionCallback.onError(parentId, options);
-        }
-    }
-}
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
index 414662a..10feb0df 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
@@ -23,10 +23,12 @@
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_REGISTER_CALLBACK_MESSENGER;
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_REMOVE_SUBSCRIPTION;
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_SEARCH;
-import static android.support.v4.media.MediaBrowserProtocol
-        .CLIENT_MSG_UNREGISTER_CALLBACK_MESSENGER;
+import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_SEND_CUSTOM_ACTION;
+import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_UNREGISTER_CALLBACK_MESSENGER;
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_VERSION_CURRENT;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_CALLBACK_TOKEN;
+import static android.support.v4.media.MediaBrowserProtocol.DATA_CUSTOM_ACTION;
+import static android.support.v4.media.MediaBrowserProtocol.DATA_CUSTOM_ACTION_EXTRAS;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_MEDIA_ITEM_ID;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_MEDIA_ITEM_LIST;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_MEDIA_SESSION_TOKEN;
@@ -38,6 +40,7 @@
 import static android.support.v4.media.MediaBrowserProtocol.DATA_SEARCH_QUERY;
 import static android.support.v4.media.MediaBrowserProtocol.EXTRA_CLIENT_VERSION;
 import static android.support.v4.media.MediaBrowserProtocol.EXTRA_MESSENGER_BINDER;
+import static android.support.v4.media.MediaBrowserProtocol.EXTRA_SESSION_BINDER;
 import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_CONNECT;
 import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_CONNECT_FAILED;
 import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_LOAD_CHILDREN;
@@ -61,6 +64,7 @@
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
 import android.support.v4.app.BundleCompat;
+import android.support.v4.media.session.IMediaSession;
 import android.support.v4.media.session.MediaControllerCompat.TransportControls;
 import android.support.v4.media.session.MediaSessionCompat;
 import android.support.v4.os.BuildCompat;
@@ -82,6 +86,8 @@
  * <p>
  * This object is not thread-safe. All calls should happen on the thread on which the browser
  * was constructed.
+ * </p><p>
+ * All callback methods will be called from the thread on which the browser was constructed.
  * </p>
  */
 public final class MediaBrowserCompat {
@@ -124,11 +130,7 @@
      */
     public MediaBrowserCompat(Context context, ComponentName serviceComponent,
             ConnectionCallback callback, Bundle rootHints) {
-        // To workaround an issue of {@link #unsubscribe(String, SubscriptionCallback)} on API 24
-        // and 25 devices, use the support library version of implementation on those devices.
-        if (Build.VERSION.SDK_INT >= 26 || BuildCompat.isAtLeastO()) {
-            mImpl = new MediaBrowserImplApi24(context, serviceComponent, callback, rootHints);
-        } else if (Build.VERSION.SDK_INT >= 23) {
+        if (Build.VERSION.SDK_INT >= 23) {
             mImpl = new MediaBrowserImplApi23(context, serviceComponent, callback, rootHints);
         } else if (Build.VERSION.SDK_INT >= 21) {
             mImpl = new MediaBrowserImplApi21(context, serviceComponent, callback, rootHints);
@@ -336,6 +338,7 @@
      * @param extras The bundle of service-specific arguments to send to the media browser service.
      *            The contents of this bundle may affect the search result.
      * @param callback The callback to receive the search result. Must be non-null.
+     * @throws IllegalStateException if the browser is not connected to the media browser service.
      */
     public void search(@NonNull final String query, final Bundle extras,
             @NonNull SearchCallback callback) {
@@ -349,6 +352,23 @@
     }
 
     /**
+     * Sends a custom action to the connected service. If the service doesn't support the given
+     * action, {@link CustomActionCallback#onError} will be called.
+     *
+     * @param action The custom action that will be sent to the connected service. Should not be an
+     *            empty string.
+     * @param extras The bundle of service-specific arguments to send to the media browser service.
+     * @param callback The callback to receive the result of the custom action.
+     */
+    public void sendCustomAction(@NonNull String action, Bundle extras,
+            @Nullable CustomActionCallback callback) {
+        if (TextUtils.isEmpty(action)) {
+            throw new IllegalArgumentException("action cannot be empty");
+        }
+        mImpl.sendCustomAction(action, extras, callback);
+    }
+
+    /**
      * A class with information on a single media item for use in browsing/searching media.
      * MediaItems are application dependent so we cannot guarantee that they contain the
      * right values.
@@ -601,11 +621,7 @@
         WeakReference<Subscription> mSubscriptionRef;
 
         public SubscriptionCallback() {
-            if (Build.VERSION.SDK_INT >= 26 || BuildCompat.isAtLeastO()) {
-                mSubscriptionCallbackObj =
-                        MediaBrowserCompatApi24.createSubscriptionCallback(new StubApi24());
-                mToken = null;
-            } else if (Build.VERSION.SDK_INT >= 21) {
+            if (Build.VERSION.SDK_INT >= 21) {
                 mSubscriptionCallbackObj =
                         MediaBrowserCompatApi21.createSubscriptionCallback(new StubApi21());
                 mToken = new Binder();
@@ -722,24 +738,6 @@
             }
 
         }
-
-        private class StubApi24 extends StubApi21
-                implements MediaBrowserCompatApi24.SubscriptionCallback {
-            StubApi24() {
-            }
-
-            @Override
-            public void onChildrenLoaded(@NonNull String parentId, List<?> children,
-                    @NonNull Bundle options) {
-                SubscriptionCallback.this.onChildrenLoaded(
-                        parentId, MediaItem.fromMediaItemList(children), options);
-            }
-
-            @Override
-            public void onError(@NonNull String parentId, @NonNull Bundle options) {
-                SubscriptionCallback.this.onError(parentId, options);
-            }
-        }
     }
 
     /**
@@ -822,6 +820,43 @@
         }
     }
 
+    /**
+     * Callback for receiving the result of {@link #sendCustomAction}.
+     */
+    public abstract static class CustomActionCallback {
+        /**
+         * Called when an interim update was delivered from the connected service while performing
+         * the custom action.
+         *
+         * @param action The custom action sent to the connected service.
+         * @param extras The bundle of service-specific arguments sent to the connected service.
+         * @param data The additional data delivered from the connected service.
+         */
+        public void onProgressUpdate(String action, Bundle extras, Bundle data) {
+        }
+
+        /**
+         * Called when the custom action finished successfully.
+         *
+         * @param action The custom action sent to the connected service.
+         * @param extras The bundle of service-specific arguments sent to the connected service.
+         * @param resultData The additional data delivered from the connected service.
+         */
+        public void onResult(String action, Bundle extras, Bundle resultData) {
+        }
+
+        /**
+         * Called when an error happens while performing the custom action or the connected service
+         * doesn't support the requested custom action.
+         *
+         * @param action The custom action sent to the connected service.
+         * @param extras The bundle of service-specific arguments sent to the connected service.
+         * @param data The additional data delivered from the connected service.
+         */
+        public void onError(String action, Bundle extras, Bundle data) {
+        }
+    }
+
     interface MediaBrowserImpl {
         void connect();
         void disconnect();
@@ -835,6 +870,7 @@
         void unsubscribe(@NonNull String parentId, SubscriptionCallback callback);
         void getItem(final @NonNull String mediaId, @NonNull final ItemCallback cb);
         void search(@NonNull String query, Bundle extras, @NonNull SearchCallback callback);
+        void sendCustomAction(String action, Bundle extras, final CustomActionCallback callback);
     }
 
     interface MediaBrowserServiceCallbackImpl {
@@ -846,10 +882,11 @@
 
     static class MediaBrowserImplBase
             implements MediaBrowserImpl, MediaBrowserServiceCallbackImpl {
-        static final int CONNECT_STATE_DISCONNECTED = 0;
-        static final int CONNECT_STATE_CONNECTING = 1;
-        private static final int CONNECT_STATE_CONNECTED = 2;
-        static final int CONNECT_STATE_SUSPENDED = 3;
+        static final int CONNECT_STATE_DISCONNECTING = 0;
+        static final int CONNECT_STATE_DISCONNECTED = 1;
+        static final int CONNECT_STATE_CONNECTING = 2;
+        static final int CONNECT_STATE_CONNECTED = 3;
+        static final int CONNECT_STATE_SUSPENDED = 4;
 
         final Context mContext;
         final ComponentName mServiceComponent;
@@ -949,21 +986,26 @@
             // It's ok to call this any state, because allowing this lets apps not have
             // to check isConnected() unnecessarily. They won't appreciate the extra
             // assertions for this. We do everything we can here to go back to a sane state.
-            if (mCallbacksMessenger != null) {
-                try {
-                    mServiceBinderWrapper.disconnect(mCallbacksMessenger);
-                } catch (RemoteException ex) {
-                    // We are disconnecting anyway. Log, just for posterity but it's not
-                    // a big problem.
-                    Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
+            mState = CONNECT_STATE_DISCONNECTING;
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    if (mCallbacksMessenger != null) {
+                        try {
+                            mServiceBinderWrapper.disconnect(mCallbacksMessenger);
+                        } catch (RemoteException ex) {
+                            // We are disconnecting anyway. Log, just for posterity but it's not
+                            // a big problem.
+                            Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
+                        }
+                    }
+                    forceCloseConnection();
+                    if (DEBUG) {
+                        Log.d(TAG, "disconnect...");
+                        dump();
+                    }
                 }
-            }
-            forceCloseConnection();
-
-            if (DEBUG) {
-                Log.d(TAG, "disconnect...");
-                dump();
-            }
+            });
         }
 
         /**
@@ -1044,7 +1086,7 @@
 
             // If we are connected, tell the service that we are watching. If we aren't
             // connected, the service will be told when we connect.
-            if (mState == CONNECT_STATE_CONNECTED) {
+            if (isConnected()) {
                 try {
                     mServiceBinderWrapper.addSubscription(parentId, callback.mToken, copiedOptions,
                             mCallbacksMessenger);
@@ -1066,7 +1108,7 @@
             // Tell the service if necessary.
             try {
                 if (callback == null) {
-                    if (mState == CONNECT_STATE_CONNECTED) {
+                    if (isConnected()) {
                         mServiceBinderWrapper.removeSubscription(parentId, null,
                                 mCallbacksMessenger);
                     }
@@ -1075,7 +1117,7 @@
                     final List<Bundle> optionsList = sub.getOptionsList();
                     for (int i = callbacks.size() - 1; i >= 0; --i) {
                         if (callbacks.get(i) == callback) {
-                            if (mState == CONNECT_STATE_CONNECTED) {
+                            if (isConnected()) {
                                 mServiceBinderWrapper.removeSubscription(
                                         parentId, callback.mToken, mCallbacksMessenger);
                             }
@@ -1103,7 +1145,7 @@
             if (cb == null) {
                 throw new IllegalArgumentException("cb is null");
             }
-            if (mState != CONNECT_STATE_CONNECTED) {
+            if (!isConnected()) {
                 Log.i(TAG, "Not connected, unable to retrieve the MediaItem.");
                 mHandler.post(new Runnable() {
                     @Override
@@ -1117,7 +1159,7 @@
             try {
                 mServiceBinderWrapper.getMediaItem(mediaId, receiver, mCallbacksMessenger);
             } catch (RemoteException e) {
-                Log.i(TAG, "Remote error getting media item.");
+                Log.i(TAG, "Remote error getting media item: " + mediaId);
                 mHandler.post(new Runnable() {
                     @Override
                     public void run() {
@@ -1131,14 +1173,8 @@
         public void search(@NonNull final String query, final Bundle extras,
                 @NonNull final SearchCallback callback) {
             if (!isConnected()) {
-                Log.i(TAG, "Not connected, unable to search.");
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onError(query, extras);
-                    }
-                });
-                return;
+                throw new IllegalStateException("search() called while not connected"
+                        + " (state=" + getStateLabel(mState) + ")");
             }
 
             ResultReceiver receiver = new SearchResultReceiver(query, extras, callback, mHandler);
@@ -1156,6 +1192,32 @@
         }
 
         @Override
+        public void sendCustomAction(@NonNull final String action, final Bundle extras,
+                @Nullable final CustomActionCallback callback) {
+            if (!isConnected()) {
+                throw new IllegalStateException("Cannot send a custom action (" + action + ") with "
+                        + "extras " + extras + " because the browser is not connected to the "
+                        + "service.");
+            }
+
+            ResultReceiver receiver = new CustomActionResultReceiver(action, extras, callback,
+                    mHandler);
+            try {
+                mServiceBinderWrapper.sendCustomAction(action, extras, receiver,
+                        mCallbacksMessenger);
+            } catch (RemoteException e) {
+                Log.i(TAG, "Remote error sending a custom action: action=" + action + ", extras="
+                        + extras, e);
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onError(action, extras, null);
+                    }
+                });
+            }
+        }
+
+        @Override
         public void onServiceConnected(final Messenger callback, final String root,
                 final MediaSessionCompat.Token session, final Bundle extra) {
             // Check to make sure there hasn't been a disconnect or a different ServiceConnection.
@@ -1267,6 +1329,8 @@
          */
         private static String getStateLabel(int state) {
             switch (state) {
+                case CONNECT_STATE_DISCONNECTING:
+                    return "CONNECT_STATE_DISCONNECTING";
                 case CONNECT_STATE_DISCONNECTED:
                     return "CONNECT_STATE_DISCONNECTED";
                 case CONNECT_STATE_CONNECTING:
@@ -1431,20 +1495,15 @@
 
         protected ServiceBinderWrapper mServiceBinderWrapper;
         protected Messenger mCallbacksMessenger;
+        private MediaSessionCompat.Token mMediaSessionToken;
 
         public MediaBrowserImplApi21(Context context, ComponentName serviceComponent,
                 ConnectionCallback callback, Bundle rootHints) {
-            // Do not send the client version for API 26 and higher, since we don't need to use
-            // EXTRA_MESSENGER_BINDER for API 26 and higher.
-            if (Build.VERSION.SDK_INT <= 25) {
-                if (rootHints == null) {
-                    rootHints = new Bundle();
-                }
-                rootHints.putInt(EXTRA_CLIENT_VERSION, CLIENT_VERSION_CURRENT);
-                mRootHints = new Bundle(rootHints);
-            } else {
-                mRootHints = rootHints == null ? null : new Bundle(rootHints);
+            if (rootHints == null) {
+                rootHints = new Bundle();
             }
+            rootHints.putInt(EXTRA_CLIENT_VERSION, CLIENT_VERSION_CURRENT);
+            mRootHints = new Bundle(rootHints);
             callback.setInternalConnectionCallback(this);
             mBrowserObj = MediaBrowserCompatApi21.createBrowser(context, serviceComponent,
                     callback.mConnectionCallbackObj, mRootHints);
@@ -1492,8 +1551,11 @@
         @NonNull
         @Override
         public MediaSessionCompat.Token getSessionToken() {
-            return MediaSessionCompat.Token.fromToken(
-                    MediaBrowserCompatApi21.getSessionToken(mBrowserObj));
+            if (mMediaSessionToken == null) {
+                mMediaSessionToken = MediaSessionCompat.Token.fromToken(
+                        MediaBrowserCompatApi21.getSessionToken(mBrowserObj));
+            }
+            return mMediaSessionToken;
         }
 
         @Override
@@ -1626,14 +1688,7 @@
         public void search(@NonNull final String query, final Bundle extras,
                 @NonNull final SearchCallback callback) {
             if (!isConnected()) {
-                Log.i(TAG, "Not connected, unable to search.");
-                mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        callback.onError(query, extras);
-                    }
-                });
-                return;
+                throw new IllegalStateException("search() called while not connected");
             }
             if (mServiceBinderWrapper == null) {
                 Log.i(TAG, "The connected service doesn't support search.");
@@ -1662,6 +1717,41 @@
         }
 
         @Override
+        public void sendCustomAction(final String action, final Bundle extras,
+                final CustomActionCallback callback) {
+            if (!isConnected()) {
+                throw new IllegalStateException("Cannot send a custom action (" + action + ") with "
+                        + "extras " + extras + " because the browser is not connected to the "
+                        + "service.");
+            }
+            if (mServiceBinderWrapper == null) {
+                Log.i(TAG, "The connected service doesn't support sendCustomAction.");
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onError(action, extras, null);
+                    }
+                });
+            }
+
+            ResultReceiver receiver = new CustomActionResultReceiver(action, extras, callback,
+                    mHandler);
+            try {
+                mServiceBinderWrapper.sendCustomAction(action, extras, receiver,
+                        mCallbacksMessenger);
+            } catch (RemoteException e) {
+                Log.i(TAG, "Remote error sending a custom action: action=" + action + ", extras="
+                        + extras, e);
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        callback.onError(action, extras, null);
+                    }
+                });
+            }
+        }
+
+        @Override
         public void onConnected() {
             Bundle extras = MediaBrowserCompatApi21.getExtras(mBrowserObj);
             if (extras == null) {
@@ -1678,12 +1768,19 @@
                     Log.i(TAG, "Remote error registering client messenger." );
                 }
             }
+            IMediaSession sessionToken = IMediaSession.Stub.asInterface(
+                    BundleCompat.getBinder(extras, EXTRA_SESSION_BINDER));
+            if (sessionToken != null) {
+                mMediaSessionToken = MediaSessionCompat.Token.fromToken(
+                        MediaBrowserCompatApi21.getSessionToken(mBrowserObj), sessionToken);
+            }
         }
 
         @Override
         public void onConnectionSuspended() {
             mServiceBinderWrapper = null;
             mCallbacksMessenger = null;
+            mMediaSessionToken = null;
             mHandler.setCallbacksMessenger(null);
         }
 
@@ -1754,36 +1851,6 @@
         }
     }
 
-    // TODO: Rename to MediaBrowserImplApi26 once O is released
-    static class MediaBrowserImplApi24 extends MediaBrowserImplApi23 {
-        public MediaBrowserImplApi24(Context context, ComponentName serviceComponent,
-                ConnectionCallback callback, Bundle rootHints) {
-            super(context, serviceComponent, callback, rootHints);
-        }
-
-        @Override
-        public void subscribe(@NonNull String parentId, @NonNull Bundle options,
-                @NonNull SubscriptionCallback callback) {
-            if (options == null) {
-                MediaBrowserCompatApi21.subscribe(
-                        mBrowserObj, parentId, callback.mSubscriptionCallbackObj);
-            } else {
-                MediaBrowserCompatApi24.subscribe(
-                        mBrowserObj, parentId, options, callback.mSubscriptionCallbackObj);
-            }
-        }
-
-        @Override
-        public void unsubscribe(@NonNull String parentId, SubscriptionCallback callback) {
-            if (callback == null) {
-                MediaBrowserCompatApi21.unsubscribe(mBrowserObj, parentId);
-            } else {
-                MediaBrowserCompatApi24.unsubscribe(mBrowserObj, parentId,
-                        callback.mSubscriptionCallbackObj);
-            }
-        }
-    }
-
     private static class Subscription {
         private final List<SubscriptionCallback> mCallbacks;
         private final List<Bundle> mOptionsList;
@@ -1938,6 +2005,15 @@
             sendRequest(CLIENT_MSG_SEARCH, data, callbacksMessenger);
         }
 
+        void sendCustomAction(String action, Bundle extras, ResultReceiver receiver,
+                Messenger callbacksMessenger) throws RemoteException {
+            Bundle data = new Bundle();
+            data.putString(DATA_CUSTOM_ACTION, action);
+            data.putBundle(DATA_CUSTOM_ACTION_EXTRAS, extras);
+            data.putParcelable(DATA_RESULT_RECEIVER, receiver);
+            sendRequest(CLIENT_MSG_SEND_CUSTOM_ACTION, data, callbacksMessenger);
+        }
+
         private void sendRequest(int what, Bundle data, Messenger cbMessenger)
                 throws RemoteException {
             Message msg = Message.obtain();
@@ -1993,6 +2069,9 @@
 
         @Override
         protected void onReceiveResult(int resultCode, Bundle resultData) {
+            if (resultData != null) {
+                resultData.setClassLoader(MediaBrowserCompat.class.getClassLoader());
+            }
             if (resultCode != MediaBrowserServiceCompat.RESULT_OK || resultData == null
                     || !resultData.containsKey(MediaBrowserServiceCompat.KEY_SEARCH_RESULTS)) {
                 mCallback.onError(mQuery, mExtras);
@@ -2010,4 +2089,40 @@
             mCallback.onSearchResult(mQuery, mExtras, results);
         }
     }
+
+    private static class CustomActionResultReceiver extends ResultReceiver {
+        private final String mAction;
+        private final Bundle mExtras;
+        private final CustomActionCallback mCallback;
+
+        CustomActionResultReceiver(String action, Bundle extras, CustomActionCallback callback,
+                Handler handler) {
+            super(handler);
+            mAction = action;
+            mExtras = extras;
+            mCallback = callback;
+        }
+
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            if (mCallback == null) {
+                return;
+            }
+            switch (resultCode) {
+                case MediaBrowserServiceCompat.RESULT_PROGRESS_UPDATE:
+                    mCallback.onProgressUpdate(mAction, mExtras, resultData);
+                    break;
+                case MediaBrowserServiceCompat.RESULT_OK:
+                    mCallback.onResult(mAction, mExtras, resultData);
+                    break;
+                case MediaBrowserServiceCompat.RESULT_ERROR:
+                    mCallback.onError(mAction, mExtras, resultData);
+                    break;
+                default:
+                    Log.w(TAG, "Unknown result code: " + resultCode + " (extras=" + mExtras
+                            + ", resultData=" + resultData + ")");
+                    break;
+            }
+        }
+    }
 }
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java b/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
index 2401d09..7c23d26 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
@@ -31,10 +31,13 @@
     public static final String DATA_ROOT_HINTS = "data_root_hints";
     public static final String DATA_SEARCH_EXTRAS = "data_search_extras";
     public static final String DATA_SEARCH_QUERY = "data_search_query";
+    public static final String DATA_CUSTOM_ACTION = "data_custom_action";
+    public static final String DATA_CUSTOM_ACTION_EXTRAS = "data_custom_action_extras";
 
     public static final String EXTRA_CLIENT_VERSION = "extra_client_version";
     public static final String EXTRA_SERVICE_VERSION = "extra_service_version";
     public static final String EXTRA_MESSENGER_BINDER = "extra_messenger";
+    public static final String EXTRA_SESSION_BINDER = "extra_session_binder";
 
     /**
      * MediaBrowserCompat will check the version of the connected MediaBrowserServiceCompat,
@@ -166,8 +169,20 @@
      *     DATA_SEARCH_QUERY : A string for search query that contains keywords separated by space.
      *     DATA_SEARCH_EXTRAS : A bundle of service-specific arguments to send to the media browser
      *                          service.
-     *     DATA_RESULT_RECEIVER : Result receiver to get the result
+     *     DATA_RESULT_RECEIVER : Result receiver to get the result.
      * - replyTo : Callback messenger
      */
     public static final int CLIENT_MSG_SEARCH = 8;
+
+    /** (client v1)
+     * Sent to request a custom action from the media browser.
+     * - arg1 : The client version
+     * - data
+     *     DATA_CUSTOM_ACTION : A string for the custom action.
+     *     DATA_CUSTOM_ACTION_EXTRAS : A bundle of service-specific arguments to send to the media
+     *                                 browser service.
+     *     DATA_RESULT_RECEIVER : Result receiver to get the result.
+     * - replyTo : Callback messenger
+     */
+    public static final int CLIENT_MSG_SEND_CUSTOM_ACTION = 9;
 }
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
index 9c65ce6..7ff6a20 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
@@ -24,9 +24,13 @@
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_REGISTER_CALLBACK_MESSENGER;
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_REMOVE_SUBSCRIPTION;
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_SEARCH;
-import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_UNREGISTER_CALLBACK_MESSENGER;
+import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_SEND_CUSTOM_ACTION;
+import static android.support.v4.media.MediaBrowserProtocol
+        .CLIENT_MSG_UNREGISTER_CALLBACK_MESSENGER;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_CALLBACK_TOKEN;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_CALLING_UID;
+import static android.support.v4.media.MediaBrowserProtocol.DATA_CUSTOM_ACTION;
+import static android.support.v4.media.MediaBrowserProtocol.DATA_CUSTOM_ACTION_EXTRAS;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_MEDIA_ITEM_ID;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_MEDIA_ITEM_LIST;
 import static android.support.v4.media.MediaBrowserProtocol.DATA_MEDIA_SESSION_TOKEN;
@@ -39,6 +43,7 @@
 import static android.support.v4.media.MediaBrowserProtocol.EXTRA_CLIENT_VERSION;
 import static android.support.v4.media.MediaBrowserProtocol.EXTRA_MESSENGER_BINDER;
 import static android.support.v4.media.MediaBrowserProtocol.EXTRA_SERVICE_VERSION;
+import static android.support.v4.media.MediaBrowserProtocol.EXTRA_SESSION_BINDER;
 import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_CONNECT;
 import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_CONNECT_FAILED;
 import static android.support.v4.media.MediaBrowserProtocol.SERVICE_MSG_ON_LOAD_CHILDREN;
@@ -61,8 +66,8 @@
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
 import android.support.v4.app.BundleCompat;
+import android.support.v4.media.session.IMediaSession;
 import android.support.v4.media.session.MediaSessionCompat;
-import android.support.v4.os.BuildCompat;
 import android.support.v4.os.ResultReceiver;
 import android.support.v4.util.ArrayMap;
 import android.support.v4.util.Pair;
@@ -133,6 +138,7 @@
 
     static final int RESULT_ERROR = -1;
     static final int RESULT_OK = 0;
+    static final int RESULT_PROGRESS_UPDATE = 1;
 
     /** @hide */
     @RestrictTo(LIBRARY_GROUP)
@@ -215,8 +221,8 @@
         @Override
         public Bundle getBrowserRootHints() {
             if (mCurConnection == null) {
-                throw new IllegalStateException("This should be called inside of onLoadChildren or"
-                        + " onLoadItem methods");
+                throw new IllegalStateException("This should be called inside of onLoadChildren,"
+                        + " onLoadItem or onSearch methods");
             }
             return mCurConnection.rootHints == null ? null : new Bundle(mCurConnection.rootHints);
         }
@@ -277,8 +283,8 @@
                 return null;
             }
             if (mCurConnection == null) {
-                throw new IllegalStateException("This should be called inside of onLoadChildren or"
-                        + " onLoadItem methods");
+                throw new IllegalStateException("This should be called inside of onLoadChildren,"
+                        + " onLoadItem or onSearch methods");
             }
             return mCurConnection.rootHints == null ? null : new Bundle(mCurConnection.rootHints);
         }
@@ -293,6 +299,11 @@
                 rootExtras = new Bundle();
                 rootExtras.putInt(EXTRA_SERVICE_VERSION, SERVICE_VERSION_CURRENT);
                 BundleCompat.putBinder(rootExtras, EXTRA_MESSENGER_BINDER, mMessenger.getBinder());
+                if (mSession != null) {
+                    IMediaSession extraBinder = mSession.getExtraBinder();
+                    BundleCompat.putBinder(rootExtras, EXTRA_SESSION_BINDER,
+                            extraBinder == null ? null : extraBinder.asBinder());
+                }
             }
             BrowserRoot root = MediaBrowserServiceCompat.this.onGetRoot(
                     clientPackageName, clientUid, rootHints);
@@ -314,7 +325,7 @@
             final Result<List<MediaBrowserCompat.MediaItem>> result
                     = new Result<List<MediaBrowserCompat.MediaItem>>(parentId) {
                 @Override
-                void onResultSent(List<MediaBrowserCompat.MediaItem> list, @ResultFlags int flags) {
+                void onResultSent(List<MediaBrowserCompat.MediaItem> list) {
                     List<Parcel> parcelList = null;
                     if (list != null) {
                         parcelList = new ArrayList<>();
@@ -351,7 +362,7 @@
             final Result<MediaBrowserCompat.MediaItem> result
                     = new Result<MediaBrowserCompat.MediaItem>(itemId) {
                 @Override
-                void onResultSent(MediaBrowserCompat.MediaItem item, @ResultFlags int flags) {
+                void onResultSent(MediaBrowserCompat.MediaItem item) {
                     if (item == null) {
                         resultWrapper.sendResult(null);
                     } else {
@@ -370,64 +381,6 @@
         }
     }
 
-    // TODO: Rename to MediaBrowserServiceImplApi26 once O is released
-    class MediaBrowserServiceImplApi24 extends MediaBrowserServiceImplApi23 implements
-            MediaBrowserServiceCompatApi24.ServiceCompatProxy {
-        @Override
-        public void onCreate() {
-            mServiceObj = MediaBrowserServiceCompatApi24.createService(
-                    MediaBrowserServiceCompat.this, this);
-            MediaBrowserServiceCompatApi21.onCreate(mServiceObj);
-        }
-
-        @Override
-        public void notifyChildrenChanged(final String parentId, final Bundle options) {
-            if (options == null) {
-                MediaBrowserServiceCompatApi21.notifyChildrenChanged(mServiceObj, parentId);
-            } else {
-                MediaBrowserServiceCompatApi24.notifyChildrenChanged(mServiceObj, parentId,
-                        options);
-            }
-        }
-
-        @Override
-        public void onLoadChildren(String parentId,
-                final MediaBrowserServiceCompatApi24.ResultWrapper resultWrapper, Bundle options) {
-            final Result<List<MediaBrowserCompat.MediaItem>> result
-                    = new Result<List<MediaBrowserCompat.MediaItem>>(parentId) {
-                @Override
-                void onResultSent(List<MediaBrowserCompat.MediaItem> list, @ResultFlags int flags) {
-                    List<Parcel> parcelList = null;
-                    if (list != null) {
-                        parcelList = new ArrayList<>();
-                        for (MediaBrowserCompat.MediaItem item : list) {
-                            Parcel parcel = Parcel.obtain();
-                            item.writeToParcel(parcel, 0);
-                            parcelList.add(parcel);
-                        }
-                    }
-                    resultWrapper.sendResult(parcelList, flags);
-                }
-
-                @Override
-                public void detach() {
-                    resultWrapper.detach();
-                }
-            };
-            MediaBrowserServiceCompat.this.onLoadChildren(parentId, result, options);
-        }
-
-        @Override
-        public Bundle getBrowserRootHints() {
-            // If EXTRA_MESSENGER_BINDER is used, mCurConnection is not null.
-            if (mCurConnection != null) {
-                return mCurConnection.rootHints == null ? null
-                        : new Bundle(mCurConnection.rootHints);
-            }
-            return MediaBrowserServiceCompatApi24.getBrowserRootHints(mServiceObj);
-        }
-    }
-
     private final class ServiceHandler extends Handler {
         private final ServiceBinderImpl mServiceBinderImpl = new ServiceBinderImpl();
 
@@ -475,6 +428,12 @@
                             (ResultReceiver) data.getParcelable(DATA_RESULT_RECEIVER),
                             new ServiceCallbacksCompat(msg.replyTo));
                     break;
+                case CLIENT_MSG_SEND_CUSTOM_ACTION:
+                    mServiceBinderImpl.sendCustomAction(data.getString(DATA_CUSTOM_ACTION),
+                            data.getBundle(DATA_CUSTOM_ACTION_EXTRAS),
+                            (ResultReceiver) data.getParcelable(DATA_RESULT_RECEIVER),
+                            new ServiceCallbacksCompat(msg.replyTo));
+                    break;
                 default:
                     Log.w(TAG, "Unhandled message: " + msg
                             + "\n  Service version: " + SERVICE_VERSION_CURRENT
@@ -518,20 +477,29 @@
     /**
      * Completion handler for asynchronous callback methods in {@link MediaBrowserServiceCompat}.
      * <p>
-     * Each of the methods that takes one of these to send the result must call
-     * {@link #sendResult} to respond to the caller with the given results. If those
-     * functions return without calling {@link #sendResult}, they must instead call
-     * {@link #detach} before returning, and then may call {@link #sendResult} when
-     * they are done. If more than one of those methods is called, an exception will
-     * be thrown.
+     * Each of the methods that takes one of these to send the result must call either
+     * {@link #sendResult} or {@link #sendError} to respond to the caller with the given results or
+     * errors. If those functions return without calling {@link #sendResult} or {@link #sendError},
+     * they must instead call {@link #detach} before returning, and then may call
+     * {@link #sendResult} or {@link #sendError} when they are done. If {@link #sendResult},
+     * {@link #sendError}, or {@link #detach} is called twice, an exception will be thrown.
+     * </p><p>
+     * Those functions might also want to call {@link #sendProgressUpdate} to send interim updates
+     * to the caller. If it is called after calling {@link #sendResult} or {@link #sendError}, an
+     * exception will be thrown.
+     * </p>
      *
      * @see MediaBrowserServiceCompat#onLoadChildren
      * @see MediaBrowserServiceCompat#onLoadItem
+     * @see MediaBrowserServiceCompat#onSearch
+     * @see MediaBrowserServiceCompat#onCustomAction
      */
     public static class Result<T> {
-        private Object mDebug;
+        private final Object mDebug;
         private boolean mDetachCalled;
         private boolean mSendResultCalled;
+        private boolean mSendProgressUpdateCalled;
+        private boolean mSendErrorCalled;
         private int mFlags;
 
         Result(Object debug) {
@@ -542,11 +510,42 @@
          * Send the result back to the caller.
          */
         public void sendResult(T result) {
-            if (mSendResultCalled) {
-                throw new IllegalStateException("sendResult() called twice for: " + mDebug);
+            if (mSendResultCalled || mSendErrorCalled) {
+                throw new IllegalStateException("sendResult() called when either sendResult() or "
+                        + "sendError() had already been called for: " + mDebug);
             }
             mSendResultCalled = true;
-            onResultSent(result, mFlags);
+            onResultSent(result);
+        }
+
+        /**
+         * Send an interim update to the caller. This method is supported only when it is used in
+         * {@link #onCustomAction}.
+         *
+         * @param extras A bundle that contains extra data.
+         */
+        public void sendProgressUpdate(Bundle extras) {
+            if (mSendResultCalled || mSendErrorCalled) {
+                throw new IllegalStateException("sendProgressUpdate() called when either "
+                        + "sendResult() or sendError() had already been called for: " + mDebug);
+            }
+            mSendProgressUpdateCalled = true;
+            onProgressUpdateSent(extras);
+        }
+
+        /**
+         * Notify the caller of a failure. This is supported only when it is used in
+         * {@link #onCustomAction}.
+         *
+         * @param extras A bundle that contains extra data.
+         */
+        public void sendError(Bundle extras) {
+            if (mSendResultCalled || mSendErrorCalled) {
+                throw new IllegalStateException("sendError() called when either sendResult() or "
+                        + "sendError() had already been called for: " + mDebug);
+            }
+            mSendErrorCalled = true;
+            onErrorSent(extras);
         }
 
         /**
@@ -562,22 +561,47 @@
                 throw new IllegalStateException("detach() called when sendResult() had already"
                         + " been called for: " + mDebug);
             }
+            if (mSendErrorCalled) {
+                throw new IllegalStateException("detach() called when sendError() had already"
+                        + " been called for: " + mDebug);
+            }
             mDetachCalled = true;
         }
 
         boolean isDone() {
-            return mDetachCalled || mSendResultCalled;
+            return mDetachCalled || mSendResultCalled || mSendErrorCalled;
         }
 
         void setFlags(@ResultFlags int flags) {
             mFlags = flags;
         }
 
+        int getFlags() {
+            return mFlags;
+        }
+
         /**
-         * Called when the result is sent, after assertions about not being called twice
-         * have happened.
+         * Called when the result is sent, after assertions about not being called twice have
+         * happened.
          */
-        void onResultSent(T result, @ResultFlags int flags) {
+        void onResultSent(T result) {
+        }
+
+        /**
+         * Called when an interim update is sent.
+         */
+        void onProgressUpdateSent(Bundle extras) {
+            throw new UnsupportedOperationException("It is not supported to send an interim update "
+                    + "for " + mDebug);
+        }
+
+        /**
+         * Called when an error is sent, after assertions about not being called twice have
+         * happened.
+         */
+        void onErrorSent(Bundle extras) {
+            throw new UnsupportedOperationException("It is not supported to send an error for "
+                    + mDebug);
         }
     }
 
@@ -762,6 +786,28 @@
                 }
             });
         }
+
+        public void sendCustomAction(final String action, final Bundle extras,
+                final ResultReceiver receiver, final ServiceCallbacks callbacks) {
+            if (TextUtils.isEmpty(action) || receiver == null) {
+                return;
+            }
+
+            mHandler.postOrRun(new Runnable() {
+                @Override
+                public void run() {
+                    final IBinder b = callbacks.asBinder();
+
+                    ConnectionRecord connection = mConnections.get(b);
+                    if (connection == null) {
+                        Log.w(TAG, "sendCustomAction for callback that isn't registered action="
+                                + action + ", extras=" + extras);
+                        return;
+                    }
+                    performCustomAction(action, extras, connection, receiver);
+                }
+            });
+        }
     }
 
     private interface ServiceCallbacks {
@@ -829,9 +875,7 @@
     @Override
     public void onCreate() {
         super.onCreate();
-        if (Build.VERSION.SDK_INT >= 26 || BuildCompat.isAtLeastO()) {
-            mImpl = new MediaBrowserServiceImplApi24();
-        } else if (Build.VERSION.SDK_INT >= 23) {
+        if (Build.VERSION.SDK_INT >= 23) {
             mImpl = new MediaBrowserServiceImplApi23();
         } else if (Build.VERSION.SDK_INT >= 21) {
             mImpl = new MediaBrowserServiceImplApi21();
@@ -981,6 +1025,28 @@
     }
 
     /**
+     * Called to request a custom action to this service.
+     * <p>
+     * Implementations must call either {@link Result#sendResult} or {@link Result#sendError}. If
+     * the requested custom action will be an expensive operation {@link Result#detach} may be
+     * called before returning from this function, and then the service can send the result later
+     * when the custom action is completed. Implementation can also call
+     * {@link Result#sendProgressUpdate} to send an interim update to the requester.
+     * </p><p>
+     * If the requested custom action is not supported by this service, call
+     * {@link Result#sendError}. The default implementation will invoke {@link Result#sendError}.
+     * </p>
+     *
+     * @param action The custom action sent from the media browser.
+     * @param extras The bundle of service-specific arguments sent from the media browser.
+     * @param result The {@link Result} to send the result of the requested custom action.
+     */
+    public void onCustomAction(@NonNull String action, Bundle extras,
+            @NonNull Result<Bundle> result) {
+        result.sendError(null);
+    }
+
+    /**
      * Call to set the media session.
      * <p>
      * This should be called as soon as possible during the service's startup.
@@ -1016,8 +1082,8 @@
      * Note that this will return null when connected to {@link android.media.browse.MediaBrowser}
      * and running on API 23 or lower.
      *
-     * @throws IllegalStateException If this method is called outside of {@link #onLoadChildren}
-     *             or {@link #onLoadItem}
+     * @throws IllegalStateException If this method is called outside of {@link #onLoadChildren},
+     *             {@link #onLoadItem} or {@link #onSearch}.
      * @see MediaBrowserServiceCompat.BrowserRoot#EXTRA_RECENT
      * @see MediaBrowserServiceCompat.BrowserRoot#EXTRA_OFFLINE
      * @see MediaBrowserServiceCompat.BrowserRoot#EXTRA_SUGGESTED
@@ -1136,7 +1202,7 @@
         final Result<List<MediaBrowserCompat.MediaItem>> result
                 = new Result<List<MediaBrowserCompat.MediaItem>>(parentId) {
             @Override
-            void onResultSent(List<MediaBrowserCompat.MediaItem> list, @ResultFlags int flags) {
+            void onResultSent(List<MediaBrowserCompat.MediaItem> list) {
                 if (mConnections.get(connection.callbacks.asBinder()) != connection) {
                     if (DEBUG) {
                         Log.d(TAG, "Not sending onLoadChildren result for connection that has"
@@ -1146,7 +1212,7 @@
                 }
 
                 List<MediaBrowserCompat.MediaItem> filteredList =
-                        (flags & RESULT_FLAG_OPTION_NOT_HANDLED) != 0
+                        (getFlags() & RESULT_FLAG_OPTION_NOT_HANDLED) != 0
                                 ? applyOptions(list, options) : list;
                 try {
                     connection.callbacks.onLoadChildren(parentId, filteredList, options);
@@ -1198,8 +1264,8 @@
         final Result<MediaBrowserCompat.MediaItem> result =
                 new Result<MediaBrowserCompat.MediaItem>(itemId) {
                     @Override
-                    void onResultSent(MediaBrowserCompat.MediaItem item, @ResultFlags int flags) {
-                        if ((flags & RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED) != 0) {
+                    void onResultSent(MediaBrowserCompat.MediaItem item) {
+                        if ((getFlags() & RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED) != 0) {
                             receiver.send(RESULT_ERROR, null);
                             return;
                         }
@@ -1224,8 +1290,8 @@
         final Result<List<MediaBrowserCompat.MediaItem>> result =
                 new Result<List<MediaBrowserCompat.MediaItem>>(query) {
             @Override
-            void onResultSent(List<MediaBrowserCompat.MediaItem> items, @ResultFlags int flag) {
-                if ((flag & RESULT_FLAG_ON_SEARCH_NOT_IMPLEMENTED) != 0
+            void onResultSent(List<MediaBrowserCompat.MediaItem> items) {
+                if ((getFlags() & RESULT_FLAG_ON_SEARCH_NOT_IMPLEMENTED) != 0
                         || items == null) {
                     receiver.send(RESULT_ERROR, null);
                     return;
@@ -1247,6 +1313,36 @@
         }
     }
 
+    void performCustomAction(final String action, Bundle extras, ConnectionRecord connection,
+            final ResultReceiver receiver) {
+        final Result<Bundle> result = new Result<Bundle>(action) {
+                @Override
+                void onResultSent(Bundle result) {
+                    receiver.send(RESULT_OK, result);
+                }
+
+                @Override
+                void onProgressUpdateSent(Bundle data) {
+                    receiver.send(RESULT_PROGRESS_UPDATE, data);
+                }
+
+                @Override
+                void onErrorSent(Bundle data) {
+                    receiver.send(RESULT_ERROR, data);
+                }
+            };
+
+        mCurConnection = connection;
+        onCustomAction(action, extras, result);
+        mCurConnection = null;
+
+        if (!result.isDone()) {
+            throw new IllegalStateException("onCustomAction must call detach() or sendResult() or "
+                    + "sendError() before returning for action=" + action + " extras="
+                    + extras);
+        }
+    }
+
     /**
      * Contains information that the browser service needs to send to the client
      * when first connected.
@@ -1320,8 +1416,9 @@
          * @see #EXTRA_RECENT
          * @see #EXTRA_OFFLINE
          * @see #EXTRA_SUGGESTED
-         * @deprecated Use {@link MediaBrowserCompat#search(String, Bundle,
-         *             MediaBrowserCompat.SearchCallback)} instead.
+         * @deprecated The search functionality is now supported by the methods
+         *             {@link MediaBrowserCompat#search} and {@link #onSearch}. Use those methods
+         *             instead.
          */
         @Deprecated
         public static final String EXTRA_SUGGESTION_KEYWORDS
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 d1d143d..ac0de3d 100644
--- a/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl
+++ b/media-compat/java/android/support/v4/media/session/IMediaControllerCallback.aidl
@@ -39,4 +39,5 @@
     void onVolumeInfoChanged(in ParcelableVolumeInfo info);
     void onRepeatModeChanged(int repeatMode);
     void onShuffleModeChanged(boolean enabled);
+    void onCaptioningEnabledChanged(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 969b803..39cfbe6 100644
--- a/media-compat/java/android/support/v4/media/session/IMediaSession.aidl
+++ b/media-compat/java/android/support/v4/media/session/IMediaSession.aidl
@@ -34,7 +34,7 @@
  * @hide
  */
 interface IMediaSession {
-    // Next ID: 44
+    // Next ID: 46
     void sendCommand(String command, in Bundle args, in MediaSessionCompat.ResultReceiverWrapper cb) = 0;
     boolean sendMediaButton(in KeyEvent mediaButton) = 1;
     void registerCallbackListener(in IMediaControllerCallback cb) = 2;
@@ -53,6 +53,7 @@
     CharSequence getQueueTitle() = 29;
     Bundle getExtras() = 30;
     int getRatingType() = 31;
+    boolean isCaptioningEnabled() = 44;
     int getRepeatMode() = 36;
     boolean isShuffleModeEnabled() = 37;
     void addQueueItem(in MediaDescriptionCompat description) = 40;
@@ -78,6 +79,7 @@
     void rewind() = 22;
     void seekTo(long pos) = 23;
     void rate(in RatingCompat rating) = 24;
+    void setCaptioningEnabled(boolean enabled) = 45;
     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 2783d3b..13661ab 100644
--- a/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
@@ -58,6 +58,17 @@
  * <p>
  * This is a helper for accessing features in {@link android.media.session.MediaSession}
  * introduced after API level 4 in a backwards compatible fashion.
+ * <p class="note">
+ * If MediaControllerCompat is created with a {@link MediaSessionCompat.Token session token}
+ * from another process, following methods will not work directly after the creation if the
+ * {@link MediaSessionCompat.Token session token} is not passed through a
+ * {@link android.support.v4.media.MediaBrowserCompat}:
+ * <ul>
+ * <li>{@link #getPlaybackState()}.{@link PlaybackStateCompat#getExtras() getExtras()}</li>
+ * <li>{@link #isCaptioningEnabled()}</li>
+ * <li>{@link #getRepeatMode()}</li>
+ * <li>{@link #isShuffleModeEnabled()}</li>
+ * </ul></p>
  */
 public final class MediaControllerCompat {
     static final String TAG = "MediaControllerCompat";
@@ -253,11 +264,14 @@
 
     /**
      * Add a queue item from the given {@code description} at the end of the play queue
-     * of this session. Not all sessions may support this.
+     * of this session. Not all sessions may support this. To know whether the session supports
+     * this, get the session's flags with {@link #getFlags()} and check that the flag
+     * {@link MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS} is set.
      *
      * @param description The {@link MediaDescriptionCompat} for creating the
      *            {@link MediaSessionCompat.QueueItem} to be inserted.
      * @throws UnsupportedOperationException If this session doesn't support this.
+     * @see #getFlags()
      * @see MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS
      */
     public void addQueueItem(MediaDescriptionCompat description) {
@@ -268,13 +282,16 @@
      * Add a queue item from the given {@code description} at the specified position
      * in the play queue of this session. Shifts the queue item currently at that position
      * (if any) and any subsequent queue items to the right (adds one to their indices).
-     * Not all sessions may support this.
+     * Not all sessions may support this. To know whether the session supports this,
+     * get the session's flags with {@link #getFlags()} and check that the flag
+     * {@link MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS} is set.
      *
      * @param description The {@link MediaDescriptionCompat} for creating the
      *            {@link MediaSessionCompat.QueueItem} to be inserted.
      * @param index The index at which the created {@link MediaSessionCompat.QueueItem}
      *            is to be inserted.
      * @throws UnsupportedOperationException If this session doesn't support this.
+     * @see #getFlags()
      * @see MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS
      */
     public void addQueueItem(MediaDescriptionCompat description, int index) {
@@ -284,11 +301,14 @@
     /**
      * Remove the first occurrence of the specified {@link MediaSessionCompat.QueueItem}
      * with the given {@link MediaDescriptionCompat description} in the play queue of the
-     * associated session. Not all sessions may support this.
+     * associated session. Not all sessions may support this. To know whether the session supports
+     * this, get the session's flags with {@link #getFlags()} and check that the flag
+     * {@link MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS} is set.
      *
      * @param description The {@link MediaDescriptionCompat} for denoting the
      *            {@link MediaSessionCompat.QueueItem} to be removed.
      * @throws UnsupportedOperationException If this session doesn't support this.
+     * @see #getFlags()
      * @see MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS
      */
     public void removeQueueItem(MediaDescriptionCompat description) {
@@ -297,10 +317,13 @@
 
     /**
      * Remove an queue item at the specified position in the play queue
-     * of this session. Not all sessions may support this.
+     * of this session. Not all sessions may support this. To know whether the session supports
+     * this, get the session's flags with {@link #getFlags()} and check that the flag
+     * {@link MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS} is set.
      *
      * @param index The index of the element to be removed.
      * @throws UnsupportedOperationException If this session doesn't support this.
+     * @see #getFlags()
      * @see MediaSessionCompat#FLAG_HANDLES_QUEUE_COMMANDS
      */
     public void removeQueueItemAt(int index) {
@@ -340,6 +363,15 @@
     }
 
     /**
+     * Return whether captioning is enabled for this session.
+     *
+     * @return {@code true} if captioning is enabled, {@code false} if disabled or not set.
+     */
+    public boolean isCaptioningEnabled() {
+        return mImpl.isCaptioningEnabled();
+    }
+
+    /**
      * Get the repeat mode for this session.
      *
      * @return The latest repeat mode set to the session, or
@@ -494,15 +526,6 @@
         return mImpl.getPackageName();
     }
 
-    @VisibleForTesting
-    boolean isExtraBinderReady() {
-        if (mImpl instanceof MediaControllerImplApi21) {
-            return ((MediaControllerImplApi21) mImpl).mExtraBinder != null;
-        } else {
-            return false;
-        }
-    }
-
     /**
      * Gets the underlying framework
      * {@link android.media.session.MediaController} object.
@@ -610,6 +633,14 @@
         }
 
         /**
+         * Override to handle changes to the captioning enabled status.
+         *
+         * @param enabled {@code true} if captioning is enabled, {@code false} otherwise.
+         */
+        public void onCaptioningEnabledChanged(boolean enabled) {
+        }
+
+        /**
          * Override to handle changes to the repeat mode.
          *
          * @param repeatMode The repeat mode. It should be one of followings:
@@ -732,6 +763,11 @@
             }
 
             @Override
+            public void onCaptioningEnabledChanged(boolean enabled) throws RemoteException {
+                mHandler.post(MessageHandler.MSG_UPDATE_CAPTIONING_ENABLED, enabled, null);
+            }
+
+            @Override
             public void onRepeatModeChanged(int repeatMode) throws RemoteException {
                 mHandler.post(MessageHandler.MSG_UPDATE_REPEAT_MODE, repeatMode, null);
             }
@@ -768,6 +804,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;
+            private static final int MSG_UPDATE_CAPTIONING_ENABLED = 11;
 
             public MessageHandler(Looper looper) {
                 super(looper);
@@ -794,6 +831,9 @@
                     case MSG_UPDATE_QUEUE_TITLE:
                         onQueueTitleChanged((CharSequence) msg.obj);
                         break;
+                    case MSG_UPDATE_CAPTIONING_ENABLED:
+                        onCaptioningEnabledChanged((boolean) msg.obj);
+                        break;
                     case MSG_UPDATE_REPEAT_MODE:
                         onRepeatModeChanged((int) msg.obj);
                         break;
@@ -975,6 +1015,13 @@
         public abstract void setRating(RatingCompat rating);
 
         /**
+         * Enable/disable captioning for this session.
+         *
+         * @param enabled {@code true} to enable captioning, {@code false} to disable.
+         */
+        public abstract void setCaptioningEnabled(boolean enabled);
+
+        /**
          * Set the repeat mode for this session.
          *
          * @param repeatMode The repeat mode. Must be one of the followings:
@@ -1007,6 +1054,8 @@
          *
          * @see #sendCustomAction(PlaybackStateCompat.CustomAction action,
          *      Bundle args)
+         * @see MediaSessionCompat#ACTION_FLAG_AS_INAPPROPRIATE
+         * @see MediaSessionCompat#ACTION_SKIP_AD
          * @param action The action identifier of the
          *            {@link PlaybackStateCompat.CustomAction} as specified by
          *            the {@link MediaSessionCompat}.
@@ -1120,6 +1169,7 @@
         CharSequence getQueueTitle();
         Bundle getExtras();
         int getRatingType();
+        boolean isCaptioningEnabled();
         int getRepeatMode();
         boolean isShuffleModeEnabled();
         long getFlags();
@@ -1135,12 +1185,10 @@
     }
 
     static class MediaControllerImplBase implements MediaControllerImpl {
-        private MediaSessionCompat.Token mToken;
         private IMediaSession mBinder;
         private TransportControls mTransportControls;
 
         public MediaControllerImplBase(MediaSessionCompat.Token token) {
-            mToken = token;
             mBinder = IMediaSession.Stub.asInterface((IBinder) token.getToken());
         }
 
@@ -1314,6 +1362,16 @@
         }
 
         @Override
+        public boolean isCaptioningEnabled() {
+            try {
+                return mBinder.isCaptioningEnabled();
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in isCaptioningEnabled.", e);
+            }
+            return false;
+        }
+
+        @Override
         public int getRepeatMode() {
             try {
                 return mBinder.getRepeatMode();
@@ -1571,6 +1629,15 @@
         }
 
         @Override
+        public void setCaptioningEnabled(boolean enabled) {
+            try {
+                mBinder.setCaptioningEnabled(enabled);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in setCaptioningEnabled.", e);
+            }
+        }
+
+        @Override
         public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
             try {
                 mBinder.setRepeatMode(repeatMode);
@@ -1615,7 +1682,10 @@
         public MediaControllerImplApi21(Context context, MediaSessionCompat session) {
             mControllerObj = MediaControllerCompatApi21.fromToken(context,
                     session.getSessionToken().getToken());
-            requestExtraBinder();
+            mExtraBinder = session.getSessionToken().getExtraBinder();
+            if (mExtraBinder == null) {
+                requestExtraBinder();
+            }
         }
 
         public MediaControllerImplApi21(Context context, MediaSessionCompat.Token sessionToken)
@@ -1623,7 +1693,10 @@
             mControllerObj = MediaControllerCompatApi21.fromToken(context,
                     sessionToken.getToken());
             if (mControllerObj == null) throw new RemoteException();
-            requestExtraBinder();
+            mExtraBinder = sessionToken.getExtraBinder();
+            if (mExtraBinder == null) {
+                requestExtraBinder();
+            }
         }
 
         @Override
@@ -1706,6 +1779,11 @@
 
         @Override
         public void addQueueItem(MediaDescriptionCompat description) {
+            long flags = getFlags();
+            if ((flags & MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+                throw new UnsupportedOperationException(
+                        "This session doesn't support queue management operations");
+            }
             Bundle params = new Bundle();
             params.putParcelable(COMMAND_ARGUMENT_MEDIA_DESCRIPTION, description);
             sendCommand(COMMAND_ADD_QUEUE_ITEM, params, null);
@@ -1713,6 +1791,11 @@
 
         @Override
         public void addQueueItem(MediaDescriptionCompat description, int index) {
+            long flags = getFlags();
+            if ((flags & MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+                throw new UnsupportedOperationException(
+                        "This session doesn't support queue management operations");
+            }
             Bundle params = new Bundle();
             params.putParcelable(COMMAND_ARGUMENT_MEDIA_DESCRIPTION, description);
             params.putInt(COMMAND_ARGUMENT_INDEX, index);
@@ -1721,6 +1804,11 @@
 
         @Override
         public void removeQueueItem(MediaDescriptionCompat description) {
+            long flags = getFlags();
+            if ((flags & MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+                throw new UnsupportedOperationException(
+                        "This session doesn't support queue management operations");
+            }
             Bundle params = new Bundle();
             params.putParcelable(COMMAND_ARGUMENT_MEDIA_DESCRIPTION, description);
             sendCommand(COMMAND_REMOVE_QUEUE_ITEM, params, null);
@@ -1728,6 +1816,11 @@
 
         @Override
         public void removeQueueItemAt(int index) {
+            long flags = getFlags();
+            if ((flags & MediaSessionCompat.FLAG_HANDLES_QUEUE_COMMANDS) == 0) {
+                throw new UnsupportedOperationException(
+                        "This session doesn't support queue management operations");
+            }
             Bundle params = new Bundle();
             params.putInt(COMMAND_ARGUMENT_INDEX, index);
             sendCommand(COMMAND_REMOVE_QUEUE_ITEM_AT, params, null);
@@ -1756,6 +1849,18 @@
         }
 
         @Override
+        public boolean isCaptioningEnabled() {
+            if (mExtraBinder != null) {
+                try {
+                    return mExtraBinder.isCaptioningEnabled();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Dead object in isCaptioningEnabled.", e);
+                }
+            }
+            return false;
+        }
+
+        @Override
         public int getRepeatMode() {
             if (mExtraBinder != null) {
                 try {
@@ -1825,7 +1930,6 @@
             return mControllerObj;
         }
 
-        // TODO: Handle the case of calling other methods before receiving the extra binder.
         private void requestExtraBinder() {
             sendCommand(COMMAND_GET_EXTRA_BINDER, null,
                     new ExtraBinderRequestResultReceiver(this, new Handler()));
@@ -1925,6 +2029,16 @@
             }
 
             @Override
+            public void onCaptioningEnabledChanged(final boolean enabled) throws RemoteException {
+                mCallback.mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mCallback.onCaptioningEnabledChanged(enabled);
+                    }
+                });
+            }
+
+            @Override
             public void onRepeatModeChanged(final int repeatMode) throws RemoteException {
                 mCallback.mHandler.post(new Runnable() {
                     @Override
@@ -2041,6 +2155,13 @@
         }
 
         @Override
+        public void setCaptioningEnabled(boolean enabled) {
+            Bundle bundle = new Bundle();
+            bundle.putBoolean(MediaSessionCompat.ACTION_ARGUMENT_CAPTIONING_ENABLED, enabled);
+            sendCustomAction(MediaSessionCompat.ACTION_SET_CAPTIONING_ENABLED, bundle);
+        }
+
+        @Override
         public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
             Bundle bundle = new Bundle();
             bundle.putInt(MediaSessionCompat.ACTION_ARGUMENT_REPEAT_MODE, repeatMode);
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 01ac807..eac0d6d 100644
--- a/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -120,6 +120,22 @@
     public static final int FLAG_HANDLES_QUEUE_COMMANDS = 1 << 2;
 
     /**
+     * Predefined custom action to flag the media that is currently playing as inappropriate.
+     *
+     * @see Callback#onCustomAction
+     */
+    public static final String ACTION_FLAG_AS_INAPPROPRIATE =
+            "android.support.v4.media.session.action.FLAG_AS_INAPPROPRIATE";
+
+    /**
+     * Predefined custom action to skip the advertisement that is currently playing.
+     *
+     * @see Callback#onCustomAction
+     */
+    public static final String ACTION_SKIP_AD =
+            "android.support.v4.media.session.action.SKIP_AD";
+
+    /**
      * Custom action to invoke playFromUri() for the forward compatibility.
      */
     static final String ACTION_PLAY_FROM_URI =
@@ -149,6 +165,12 @@
             "android.support.v4.media.session.action.PREPARE_FROM_URI";
 
     /**
+     * Custom action to invoke setCaptioningEnabled() for the forward compatibility.
+     */
+    static final String ACTION_SET_CAPTIONING_ENABLED =
+            "android.support.v4.media.session.action.SET_CAPTIONING_ENABLED";
+
+    /**
      * Custom action to invoke setRepeatMode() for the forward compatibility.
      */
     static final String ACTION_SET_REPEAT_MODE =
@@ -186,6 +208,13 @@
             "android.support.v4.media.session.action.ARGUMENT_EXTRAS";
 
     /**
+     * Argument for use with {@link #ACTION_SET_CAPTIONING_ENABLED} indicating whether captioning is
+     * enabled.
+     */
+    static final String ACTION_ARGUMENT_CAPTIONING_ENABLED =
+            "android.support.v4.media.session.action.ARGUMENT_CAPTIONING_ENABLED";
+
+    /**
      * Argument for use with {@link #ACTION_SET_REPEAT_MODE} indicating repeat mode.
      */
     static final String ACTION_ARGUMENT_REPEAT_MODE =
@@ -537,6 +566,15 @@
     }
 
     /**
+     * Enable/disable captioning for this session.
+     *
+     * @param enabled {@code true} to enable captioning, {@code false} to disable.
+     */
+    public void setCaptioningEnabled(boolean enabled) {
+        mImpl.setCaptioningEnabled(enabled);
+    }
+
+    /**
      * Set the repeat mode for this session.
      * <p>
      * Note that if this method is not called before, {@link MediaControllerCompat#getRepeatMode}
@@ -675,6 +713,39 @@
         return new MediaSessionCompat(context, new MediaSessionImplApi21(mediaSession));
     }
 
+    private static PlaybackStateCompat getStateWithUpdatedPosition(
+            PlaybackStateCompat state, MediaMetadataCompat metadata) {
+        if (state == null || state.getPosition() == PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN) {
+            return state;
+        }
+
+        if (state.getState() == PlaybackStateCompat.STATE_PLAYING
+                || state.getState() == PlaybackStateCompat.STATE_FAST_FORWARDING
+                || state.getState() == PlaybackStateCompat.STATE_REWINDING) {
+            long updateTime = state.getLastPositionUpdateTime();
+            if (updateTime > 0) {
+                long currentTime = SystemClock.elapsedRealtime();
+                long position = (long) (state.getPlaybackSpeed() * (currentTime - updateTime))
+                        + state.getPosition();
+                long duration = -1;
+                if (metadata != null && metadata.containsKey(
+                        MediaMetadataCompat.METADATA_KEY_DURATION)) {
+                    duration = metadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION);
+                }
+
+                if (duration >= 0 && position > duration) {
+                    position = duration;
+                } else if (position < 0) {
+                    position = 0;
+                }
+                return new PlaybackStateCompat.Builder(state)
+                        .setState(state.getState(), position, state.getPlaybackSpeed(), currentTime)
+                        .build();
+            }
+        }
+        return state;
+    }
+
     /**
      * Receives transport controls, media buttons, and commands from controllers
      * and the system. The callback may be set using {@link #setCallback}.
@@ -850,6 +921,14 @@
         }
 
         /**
+         * Override to handle requests to enable/disable captioning.
+         *
+         * @param enabled {@code true} to enable captioning, {@code false} to disable.
+         */
+        public void onSetCaptioningEnabled(boolean enabled) {
+        }
+
+        /**
          * Override to handle the setting of the repeat mode.
          * <p>
          * You should call {@link #setRepeatMode} before end of this method in order to notify
@@ -884,6 +963,8 @@
          *            {@link PlaybackStateCompat.CustomAction}.
          * @param extras Optional extras specified by the
          *            {@link MediaControllerCompat}.
+         * @see #ACTION_FLAG_AS_INAPPROPRIATE
+         * @see #ACTION_SKIP_AD
          */
         public void onCustomAction(String action, Bundle extras) {
         }
@@ -941,7 +1022,9 @@
                     MediaSessionImplApi21 impl = (MediaSessionImplApi21) mSessionImpl.get();
                     if (impl != null) {
                         Bundle result = new Bundle();
-                        BundleCompat.putBinder(result, EXTRA_BINDER, impl.getExtraSessionBinder());
+                        IMediaSession extraBinder = impl.getSessionToken().getExtraBinder();
+                        BundleCompat.putBinder(result, EXTRA_BINDER,
+                                extraBinder == null ? null : extraBinder.asBinder());
                         cb.send(0, result);
                     }
                 } else if (command.equals(MediaControllerCompat.COMMAND_ADD_QUEUE_ITEM)) {
@@ -1053,6 +1136,9 @@
                     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_CAPTIONING_ENABLED)) {
+                    boolean enabled = extras.getBoolean(ACTION_ARGUMENT_CAPTIONING_ENABLED);
+                    Callback.this.onSetCaptioningEnabled(enabled);
                 } else if (action.equals(ACTION_SET_REPEAT_MODE)) {
                     int repeatMode = extras.getInt(ACTION_ARGUMENT_REPEAT_MODE);
                     Callback.this.onSetRepeatMode(repeatMode);
@@ -1110,9 +1196,15 @@
      */
     public static final class Token implements Parcelable {
         private final Object mInner;
+        private final IMediaSession mExtraBinder;
 
         Token(Object inner) {
+            this(inner, null);
+        }
+
+        Token(Object inner, IMediaSession extraBinder) {
             mInner = inner;
+            mExtraBinder = extraBinder;
         }
 
         /**
@@ -1127,10 +1219,28 @@
          * @return A compat Token for use with {@link MediaControllerCompat}.
          */
         public static Token fromToken(Object token) {
+            return fromToken(token, null);
+        }
+
+        /**
+         * Creates a compat Token from a framework
+         * {@link android.media.session.MediaSession.Token} object, and the extra binder.
+         * <p>
+         * This method is only supported on
+         * {@link android.os.Build.VERSION_CODES#LOLLIPOP} and later.
+         * </p>
+         *
+         * @param token The framework token object.
+         * @param extraBinder The extra binder.
+         * @return A compat Token for use with {@link MediaControllerCompat}.
+         * @hide
+         */
+        @RestrictTo(LIBRARY_GROUP)
+        public static Token fromToken(Object token, IMediaSession extraBinder) {
             if (token == null || android.os.Build.VERSION.SDK_INT < 21) {
                 return null;
             }
-            return new Token(MediaSessionCompatApi21.verifyToken(token));
+            return new Token(MediaSessionCompatApi21.verifyToken(token), extraBinder);
         }
 
         @Override
@@ -1187,6 +1297,14 @@
             return mInner;
         }
 
+        /**
+         * @hide
+         */
+        @RestrictTo(LIBRARY_GROUP)
+        public IMediaSession getExtraBinder() {
+            return mExtraBinder;
+        }
+
         public static final Parcelable.Creator<Token> CREATOR
                 = new Parcelable.Creator<Token>() {
             @Override
@@ -1438,6 +1556,7 @@
         void setQueueTitle(CharSequence title);
 
         void setRatingType(@RatingCompat.Style int type);
+        void setCaptioningEnabled(boolean enabled);
         void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode);
         void setShuffleModeEnabled(boolean enabled);
         void setExtras(Bundle extras);
@@ -1479,6 +1598,7 @@
         List<QueueItem> mQueue;
         CharSequence mQueueTitle;
         @RatingCompat.Style int mRatingType;
+        boolean mCaptioningEnabled;
         @PlaybackStateCompat.RepeatMode int mRepeatMode;
         boolean mShuffleModeEnabled;
         Bundle mExtras;
@@ -1780,6 +1900,14 @@
         }
 
         @Override
+        public void setCaptioningEnabled(boolean enabled) {
+            if (mCaptioningEnabled != enabled) {
+                mCaptioningEnabled = enabled;
+                sendCaptioningEnabled(enabled);
+            }
+        }
+
+        @Override
         public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
             if (mRepeatMode != repeatMode) {
                 mRepeatMode = repeatMode;
@@ -1892,43 +2020,6 @@
             }
         }
 
-        PlaybackStateCompat getStateWithUpdatedPosition() {
-            PlaybackStateCompat state;
-            long duration = -1;
-            synchronized (mLock) {
-                state = mState;
-                if (mMetadata != null
-                        && mMetadata.containsKey(MediaMetadataCompat.METADATA_KEY_DURATION)) {
-                    duration = mMetadata.getLong(MediaMetadataCompat.METADATA_KEY_DURATION);
-                }
-            }
-
-            PlaybackStateCompat result = null;
-            if (state != null) {
-                if (state.getState() == PlaybackStateCompat.STATE_PLAYING
-                        || state.getState() == PlaybackStateCompat.STATE_FAST_FORWARDING
-                        || state.getState() == PlaybackStateCompat.STATE_REWINDING) {
-                    long updateTime = state.getLastPositionUpdateTime();
-                    long currentTime = SystemClock.elapsedRealtime();
-                    if (updateTime > 0) {
-                        long position = (long) (state.getPlaybackSpeed()
-                                * (currentTime - updateTime)) + state.getPosition();
-                        if (duration >= 0 && position > duration) {
-                            position = duration;
-                        } else if (position < 0) {
-                            position = 0;
-                        }
-                        PlaybackStateCompat.Builder builder = new PlaybackStateCompat.Builder(
-                                state);
-                        builder.setState(state.getState(), position, state.getPlaybackSpeed(),
-                                currentTime);
-                        result = builder.build();
-                    }
-                }
-            }
-            return result == null ? state : result;
-        }
-
         void sendVolumeInfoChanged(ParcelableVolumeInfo info) {
             int size = mControllerCallbacks.beginBroadcast();
             for (int i = size - 1; i >= 0; i--) {
@@ -2014,6 +2105,18 @@
             mControllerCallbacks.finishBroadcast();
         }
 
+        private void sendCaptioningEnabled(boolean enabled) {
+            int size = mControllerCallbacks.beginBroadcast();
+            for (int i = size - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.getBroadcastItem(i);
+                try {
+                    cb.onCaptioningEnabledChanged(enabled);
+                } catch (RemoteException e) {
+                }
+            }
+            mControllerCallbacks.finishBroadcast();
+        }
+
         private void sendRepeatMode(int repeatMode) {
             int size = mControllerCallbacks.beginBroadcast();
             for (int i = size - 1; i >= 0; i--) {
@@ -2234,6 +2337,11 @@
             }
 
             @Override
+            public void setCaptioningEnabled(boolean enabled) throws RemoteException {
+                postToHandler(MessageHandler.MSG_SET_CAPTIONING_ENABLED, enabled);
+            }
+
+            @Override
             public void setRepeatMode(int repeatMode) throws RemoteException {
                 postToHandler(MessageHandler.MSG_SET_REPEAT_MODE, repeatMode);
             }
@@ -2256,7 +2364,13 @@
 
             @Override
             public PlaybackStateCompat getPlaybackState() {
-                return getStateWithUpdatedPosition();
+                PlaybackStateCompat state;
+                MediaMetadataCompat metadata;
+                synchronized (mLock) {
+                    state = mState;
+                    metadata = mMetadata;
+                }
+                return getStateWithUpdatedPosition(state, metadata);
             }
 
             @Override
@@ -2305,6 +2419,11 @@
             }
 
             @Override
+            public boolean isCaptioningEnabled() {
+                return mCaptioningEnabled;
+            }
+
+            @Override
             @PlaybackStateCompat.RepeatMode
             public int getRepeatMode() {
                 return mRepeatMode;
@@ -2363,6 +2482,7 @@
             private static final int MSG_ADD_QUEUE_ITEM_AT = 26;
             private static final int MSG_REMOVE_QUEUE_ITEM = 27;
             private static final int MSG_REMOVE_QUEUE_ITEM_AT = 28;
+            private static final int MSG_SET_CAPTIONING_ENABLED = 29;
 
             // KeyEvent constants only available on API 11+
             private static final int KEYCODE_MEDIA_PAUSE = 127;
@@ -2482,6 +2602,9 @@
                     case MSG_SET_VOLUME:
                         setVolumeTo(msg.arg1, 0);
                         break;
+                    case MSG_SET_CAPTIONING_ENABLED:
+                        cb.onSetCaptioningEnabled((boolean) msg.obj);
+                        break;
                     case MSG_SET_REPEAT_MODE:
                         cb.onSetRepeatMode(msg.arg1);
                         break;
@@ -2558,23 +2681,26 @@
         private final Token mToken;
 
         private boolean mDestroyed = false;
-        private ExtraSession mExtraSessionBinder;
         private final RemoteCallbackList<IMediaControllerCallback> mExtraControllerCallbacks =
                 new RemoteCallbackList<>();
 
         private PlaybackStateCompat mPlaybackState;
+        private MediaMetadataCompat mMetadata;
         @RatingCompat.Style int mRatingType;
+        boolean mCaptioningEnabled;
         @PlaybackStateCompat.RepeatMode int mRepeatMode;
         boolean mShuffleModeEnabled;
 
         public MediaSessionImplApi21(Context context, String tag) {
             mSessionObj = MediaSessionCompatApi21.createSession(context, tag);
-            mToken = new Token(MediaSessionCompatApi21.getSessionToken(mSessionObj));
+            mToken = new Token(MediaSessionCompatApi21.getSessionToken(mSessionObj),
+                    new ExtraSession());
         }
 
         public MediaSessionImplApi21(Object mediaSession) {
             mSessionObj = MediaSessionCompatApi21.verifySession(mediaSession);
-            mToken = new Token(MediaSessionCompatApi21.getSessionToken(mSessionObj));
+            mToken = new Token(MediaSessionCompatApi21.getSessionToken(mSessionObj),
+                    new ExtraSession());
         }
 
         @Override
@@ -2657,6 +2783,7 @@
 
         @Override
         public void setMetadata(MediaMetadataCompat metadata) {
+            mMetadata = metadata;
             MediaSessionCompatApi21.setMetadata(mSessionObj,
                     metadata == null ? null : metadata.getMediaMetadata());
         }
@@ -2698,6 +2825,22 @@
         }
 
         @Override
+        public void setCaptioningEnabled(boolean enabled) {
+            if (mCaptioningEnabled != enabled) {
+                mCaptioningEnabled = enabled;
+                int size = mExtraControllerCallbacks.beginBroadcast();
+                for (int i = size - 1; i >= 0; i--) {
+                    IMediaControllerCallback cb = mExtraControllerCallbacks.getBroadcastItem(i);
+                    try {
+                        cb.onCaptioningEnabledChanged(enabled);
+                    } catch (RemoteException e) {
+                    }
+                }
+                mExtraControllerCallbacks.finishBroadcast();
+            }
+        }
+
+        @Override
         public void setRepeatMode(@PlaybackStateCompat.RepeatMode int repeatMode) {
             if (mRepeatMode != repeatMode) {
                 mRepeatMode = repeatMode;
@@ -2753,13 +2896,6 @@
             }
         }
 
-        ExtraSession getExtraSessionBinder() {
-            if (mExtraSessionBinder == null) {
-                mExtraSessionBinder = new ExtraSession();
-            }
-            return mExtraSessionBinder;
-        }
-
         class ExtraSession extends IMediaSession.Stub {
             @Override
             public void sendCommand(String command, Bundle args, ResultReceiverWrapper cb) {
@@ -2931,6 +3067,12 @@
             }
 
             @Override
+            public void setCaptioningEnabled(boolean enabled) throws RemoteException {
+                // Will not be called.
+                throw new AssertionError();
+            }
+
+            @Override
             public void setRepeatMode(int repeatMode) throws RemoteException {
                 // Will not be called.
                 throw new AssertionError();
@@ -2956,7 +3098,7 @@
 
             @Override
             public PlaybackStateCompat getPlaybackState() {
-                return mPlaybackState;
+                return getStateWithUpdatedPosition(mPlaybackState, mMetadata);
             }
 
             @Override
@@ -3008,6 +3150,11 @@
             }
 
             @Override
+            public boolean isCaptioningEnabled() {
+                return mCaptioningEnabled;
+            }
+
+            @Override
             @PlaybackStateCompat.RepeatMode
             public int getRepeatMode() {
                 return mRepeatMode;
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 7b1ad31..956abb6 100644
--- a/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
+++ b/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
@@ -50,7 +50,7 @@
             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_SET_REPEAT_MODE, ACTION_SET_SHUFFLE_MODE_ENABLED})
+            ACTION_SET_REPEAT_MODE, ACTION_SET_SHUFFLE_MODE_ENABLED, ACTION_SET_CAPTIONING_ENABLED})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Actions {}
 
@@ -204,6 +204,13 @@
     public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 1 << 19;
 
     /**
+     * Indicates this session supports the set captioning enabled command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SET_CAPTIONING_ENABLED = 1 << 20;
+
+    /**
      * @hide
      */
     @RestrictTo(LIBRARY_GROUP)
@@ -625,6 +632,7 @@
      * <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>
+     * <li> {@link PlaybackStateCompat#ACTION_SET_CAPTIONING_ENABLED}</li>
      * </ul>
      */
     @Actions
@@ -1165,6 +1173,7 @@
          * <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>
+         * <li> {@link PlaybackStateCompat#ACTION_SET_CAPTIONING_ENABLED}</li>
          * </ul>
          *
          * @return this
diff --git a/media-compat/tests/AndroidManifest.xml b/media-compat/tests/AndroidManifest.xml
index 93ead1e..eda8df2 100644
--- a/media-compat/tests/AndroidManifest.xml
+++ b/media-compat/tests/AndroidManifest.xml
@@ -36,6 +36,17 @@
                 <action android:name="android.media.browse.MediaBrowserService"/>
             </intent-filter>
         </service>
+        <service android:name="android.support.v4.media.StubRemoteMediaBrowserServiceCompat"
+                 android:process=":remote">
+            <intent-filter>
+                <action android:name="android.media.browse.MediaBrowserService"/>
+            </intent-filter>
+        </service>
+        <service android:name="android.support.v4.media.StubMediaBrowserServiceCompatWithDelayedMediaSession">
+            <intent-filter>
+                <action android:name="android.media.browse.MediaBrowserService"/>
+            </intent-filter>
+        </service>
     </application>
 
     <instrumentation
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 fd87a76..50ff13b 100644
--- a/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/MediaBrowserCompatTest.java
@@ -19,7 +19,9 @@
 import static android.support.test.InstrumentationRegistry.getInstrumentation;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
 
 import static org.junit.Assert.fail;
 
@@ -58,6 +60,10 @@
     private static final ComponentName TEST_BROWSER_SERVICE = new ComponentName(
             "android.support.mediacompat.test",
             "android.support.v4.media.StubMediaBrowserServiceCompat");
+    private static final ComponentName TEST_REMOTE_BROWSER_SERVICE = new ComponentName(
+            "android.support.mediacompat.test",
+            "android.support.v4.media.StubRemoteMediaBrowserServiceCompat");
+
     private static final ComponentName TEST_INVALID_BROWSER_SERVICE = new ComponentName(
             "invalid.package", "invalid.ServiceClassName");
     private final StubConnectionCallback mConnectionCallback = new StubConnectionCallback();
@@ -71,10 +77,10 @@
     public void testMediaBrowser() {
         resetCallbacks();
         createMediaBrowser(TEST_BROWSER_SERVICE);
-        assertEquals(false, mMediaBrowser.isConnected());
+        assertFalse(mMediaBrowser.isConnected());
 
         connectMediaBrowserService();
-        assertEquals(true, mMediaBrowser.isConnected());
+        assertTrue(mMediaBrowser.isConnected());
 
         assertEquals(TEST_BROWSER_SERVICE, mMediaBrowser.getServiceComponent());
         assertEquals(StubMediaBrowserServiceCompat.MEDIA_ID_ROOT, mMediaBrowser.getRoot());
@@ -90,6 +96,33 @@
                 return !mMediaBrowser.isConnected();
             }
         }.run();
+        assertFalse(mMediaBrowser.isConnected());
+    }
+
+    @Test
+    @SmallTest
+    public void testMediaBrowserWithRemoteService() {
+        resetCallbacks();
+        createMediaBrowser(TEST_REMOTE_BROWSER_SERVICE);
+        assertFalse(mMediaBrowser.isConnected());
+
+        connectMediaBrowserService();
+        assertTrue(mMediaBrowser.isConnected());
+
+        assertEquals(TEST_REMOTE_BROWSER_SERVICE, mMediaBrowser.getServiceComponent());
+        assertEquals(StubRemoteMediaBrowserServiceCompat.MEDIA_ID_ROOT, mMediaBrowser.getRoot());
+        assertEquals(StubRemoteMediaBrowserServiceCompat.EXTRAS_VALUE,
+                mMediaBrowser.getExtras().getString(
+                        StubRemoteMediaBrowserServiceCompat.EXTRAS_KEY));
+
+        mMediaBrowser.disconnect();
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return !mMediaBrowser.isConnected();
+            }
+        }.run();
+        assertFalse(mMediaBrowser.isConnected());
     }
 
     @Test
@@ -125,6 +158,46 @@
 
     @Test
     @SmallTest
+    public void testSecondConnection() {
+        resetCallbacks();
+        createMediaBrowser(TEST_BROWSER_SERVICE);
+        connectMediaBrowserService();
+
+        mMediaBrowser.disconnect();
+        // We need to sleep some time here, because the browser may not be ready to connect yet.
+        try {
+            Thread.sleep(SLEEP_MS);
+        } catch (InterruptedException e) {
+            fail("Unexpected InterruptedException occurred.");
+        }
+
+        // Connect to the service again.
+        resetCallbacks();
+        connectMediaBrowserService();
+
+        // Test subscribe.
+        resetCallbacks();
+        mMediaBrowser.subscribe(StubMediaBrowserServiceCompat.MEDIA_ID_ROOT, mSubscriptionCallback);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mSubscriptionCallback.mChildrenLoadedCount > 0;
+            }
+        }.run();
+
+        // Test getItem.
+        resetCallbacks();
+        mMediaBrowser.getItem(StubMediaBrowserServiceCompat.MEDIA_ID_CHILDREN[0], mItemCallback);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mItemCallback.mLastMediaItem != null;
+            }
+        }.run();
+    }
+
+    @Test
+    @SmallTest
     public void testGetServiceComponentBeforeConnection() {
         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 7e436ec..8aa5a10 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 static junit.framework.Assert.assertTrue;
 
 import android.content.ComponentName;
+import android.os.Build;
 import android.os.Bundle;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.SmallTest;
@@ -47,6 +48,19 @@
     private static final ComponentName TEST_BROWSER_SERVICE = new ComponentName(
             "android.support.mediacompat.test",
             "android.support.v4.media.StubMediaBrowserServiceCompat");
+    private static final ComponentName TEST_BROWSER_SERVICE_DELAYED_MEDIA_SESSION =
+            new ComponentName(
+                    "android.support.mediacompat.test",
+                    "android.support.v4.media"
+                            + ".StubMediaBrowserServiceCompatWithDelayedMediaSession");
+    private static final String TEST_KEY_1 = "key_1";
+    private static final String TEST_VALUE_1 = "value_1";
+    private static final String TEST_KEY_2 = "key_2";
+    private static final String TEST_VALUE_2 = "value_2";
+    private static final String TEST_KEY_3 = "key_3";
+    private static final String TEST_VALUE_3 = "value_3";
+    private static final String TEST_KEY_4 = "key_4";
+    private static final String TEST_VALUE_4 = "value_4";
     private final Object mWaitLock = new Object();
 
     private final ConnectionCallback mConnectionCallback = new ConnectionCallback();
@@ -55,6 +69,7 @@
     private final SearchCallback mSearchCallback = new SearchCallback();
 
     private MediaBrowserCompat mMediaBrowser;
+    private MediaBrowserCompat mMediaBrowserForDelayedMediaSession;
     private StubMediaBrowserServiceCompat mMediaBrowserService;
     private Bundle mRootHints;
 
@@ -76,6 +91,8 @@
             mWaitLock.wait(TIME_OUT_MS);
         }
         assertNotNull(mMediaBrowserService);
+        mMediaBrowserService.mCustomActionExtras = null;
+        mMediaBrowserService.mCustomActionResult = null;
     }
 
     @Test
@@ -212,6 +229,142 @@
 
     @Test
     @SmallTest
+    public void testSendCustomAction() throws Exception {
+        synchronized (mWaitLock) {
+            CustomActionCallback callback = new CustomActionCallback();
+            Bundle extras = new Bundle();
+            extras.putString(TEST_KEY_1, TEST_VALUE_1);
+            mMediaBrowser.sendCustomAction(StubMediaBrowserServiceCompat.CUSTOM_ACTION, extras,
+                    callback);
+            new PollingCheck(TIME_OUT_MS) {
+                @Override
+                protected boolean check() {
+                    return mMediaBrowserService.mCustomActionResult != null;
+                }
+            }.run();
+            assertNotNull(mMediaBrowserService.mCustomActionResult);
+            assertNotNull(mMediaBrowserService.mCustomActionExtras);
+            assertEquals(TEST_VALUE_1,
+                    mMediaBrowserService.mCustomActionExtras.getString(TEST_KEY_1));
+
+            callback.reset();
+            Bundle bundle1 = new Bundle();
+            bundle1.putString(TEST_KEY_2, TEST_VALUE_2);
+            mMediaBrowserService.mCustomActionResult.sendProgressUpdate(bundle1);
+            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+            assertTrue(callback.mOnProgressUpdateCalled);
+            assertNotNull(callback.mExtras);
+            assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1));
+            assertNotNull(callback.mData);
+            assertEquals(TEST_VALUE_2, callback.mData.getString(TEST_KEY_2));
+
+            callback.reset();
+            Bundle bundle2 = new Bundle();
+            bundle2.putString(TEST_KEY_3, TEST_VALUE_3);
+            mMediaBrowserService.mCustomActionResult.sendProgressUpdate(bundle2);
+            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+            assertTrue(callback.mOnProgressUpdateCalled);
+            assertNotNull(callback.mExtras);
+            assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1));
+            assertNotNull(callback.mData);
+            assertEquals(TEST_VALUE_3, callback.mData.getString(TEST_KEY_3));
+
+            Bundle bundle3 = new Bundle();
+            bundle3.putString(TEST_KEY_4, TEST_VALUE_4);
+            callback.reset();
+            mMediaBrowserService.mCustomActionResult.sendResult(bundle3);
+            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+            assertTrue(callback.mOnResultCalled);
+            assertNotNull(callback.mExtras);
+            assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1));
+            assertNotNull(callback.mData);
+            assertEquals(TEST_VALUE_4, callback.mData.getString(TEST_KEY_4));
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testSendCustomActionWithDetachedError() throws Exception {
+        synchronized (mWaitLock) {
+            CustomActionCallback callback = new CustomActionCallback();
+            Bundle extras = new Bundle();
+            extras.putString(TEST_KEY_1, TEST_VALUE_1);
+            mMediaBrowser.sendCustomAction(StubMediaBrowserServiceCompat.CUSTOM_ACTION, extras,
+                    callback);
+            new PollingCheck(TIME_OUT_MS) {
+                @Override
+                protected boolean check() {
+                    return mMediaBrowserService.mCustomActionResult != null;
+                }
+            }.run();
+            assertNotNull(mMediaBrowserService.mCustomActionResult);
+            assertNotNull(mMediaBrowserService.mCustomActionExtras);
+            assertEquals(TEST_VALUE_1,
+                    mMediaBrowserService.mCustomActionExtras.getString(TEST_KEY_1));
+
+            callback.reset();
+            Bundle bundle1 = new Bundle();
+            bundle1.putString(TEST_KEY_2, TEST_VALUE_2);
+            mMediaBrowserService.mCustomActionResult.sendProgressUpdate(bundle1);
+            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+            assertTrue(callback.mOnProgressUpdateCalled);
+            assertNotNull(callback.mExtras);
+            assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1));
+            assertNotNull(callback.mData);
+            assertEquals(TEST_VALUE_2, callback.mData.getString(TEST_KEY_2));
+
+            callback.reset();
+            Bundle bundle2 = new Bundle();
+            bundle2.putString(TEST_KEY_3, TEST_VALUE_3);
+            mMediaBrowserService.mCustomActionResult.sendError(bundle2);
+            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+            assertTrue(callback.mOnErrorCalled);
+            assertNotNull(callback.mExtras);
+            assertEquals(TEST_VALUE_1, callback.mExtras.getString(TEST_KEY_1));
+            assertNotNull(callback.mData);
+            assertEquals(TEST_VALUE_3, callback.mData.getString(TEST_KEY_3));
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testSendCustomActionWithNullCallback() throws Exception {
+        Bundle extras = new Bundle();
+        extras.putString(TEST_KEY_1, TEST_VALUE_1);
+        mMediaBrowser.sendCustomAction(StubMediaBrowserServiceCompat.CUSTOM_ACTION, extras, null);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mMediaBrowserService.mCustomActionResult != null;
+            }
+        }.run();
+        assertNotNull(mMediaBrowserService.mCustomActionResult);
+        assertNotNull(mMediaBrowserService.mCustomActionExtras);
+        assertEquals(TEST_VALUE_1, mMediaBrowserService.mCustomActionExtras.getString(TEST_KEY_1));
+    }
+
+    @Test
+    @SmallTest
+    public void testSendCustomActionWithError() throws Exception {
+        synchronized (mWaitLock) {
+            CustomActionCallback callback = new CustomActionCallback();
+            mMediaBrowser.sendCustomAction(StubMediaBrowserServiceCompat.CUSTOM_ACTION_FOR_ERROR,
+                    null, callback);
+            new PollingCheck(TIME_OUT_MS) {
+                @Override
+                protected boolean check() {
+                    return mMediaBrowserService.mCustomActionResult != null;
+                }
+            }.run();
+            assertNotNull(mMediaBrowserService.mCustomActionResult);
+            assertNull(mMediaBrowserService.mCustomActionExtras);
+            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+            assertTrue(callback.mOnErrorCalled);
+        }
+    }
+
+    @Test
+    @SmallTest
     public void testBrowserRoot() {
         final String id = "test-id";
         final String key = "test-key";
@@ -225,6 +378,35 @@
         assertEquals(val, browserRoot.getExtras().getString(key));
     }
 
+    @Test
+    @SmallTest
+    public void testDelayedSetSessionToken() throws Exception {
+        if (Build.VERSION.SDK_INT == 21) {
+            return;
+        }
+        final ConnectionCallbackForDelayedMediaSession callback =
+                new ConnectionCallbackForDelayedMediaSession();
+
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mMediaBrowserForDelayedMediaSession =
+                        new MediaBrowserCompat(getInstrumentation().getTargetContext(),
+                                TEST_BROWSER_SERVICE_DELAYED_MEDIA_SESSION, callback, null);
+            }
+        });
+
+        synchronized (mWaitLock) {
+            mMediaBrowserForDelayedMediaSession.connect();
+            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+            assertEquals(0, callback.mConnectedCount);
+
+            StubMediaBrowserServiceCompatWithDelayedMediaSession.sInstance.callSetSessionToken();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertEquals(1, callback.mConnectedCount);
+        }
+    }
+
     private void assertRootHints(MediaItem item) {
         Bundle rootHints = item.getDescription().getExtras();
         assertNotNull(rootHints);
@@ -330,4 +512,69 @@
             mSearchResults = null;
         }
     }
+
+    private class CustomActionCallback extends MediaBrowserCompat.CustomActionCallback {
+        String mAction;
+        Bundle mExtras;
+        Bundle mData;
+        boolean mOnProgressUpdateCalled;
+        boolean mOnResultCalled;
+        boolean mOnErrorCalled;
+
+        @Override
+        public void onProgressUpdate(String action, Bundle extras, Bundle data) {
+            synchronized (mWaitLock) {
+                mOnProgressUpdateCalled = true;
+                mAction = action;
+                mExtras = extras;
+                mData = data;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onResult(String action, Bundle extras, Bundle resultData) {
+            synchronized (mWaitLock) {
+                mOnResultCalled = true;
+                mAction = action;
+                mExtras = extras;
+                mData = resultData;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
+        public void onError(String action, Bundle extras, Bundle data) {
+            synchronized (mWaitLock) {
+                mOnErrorCalled = true;
+                mAction = action;
+                mExtras = extras;
+                mData = data;
+                mWaitLock.notify();
+            }
+        }
+
+        public void reset() {
+            mOnResultCalled = false;
+            mOnProgressUpdateCalled = false;
+            mOnErrorCalled = false;
+            mAction = null;
+            mExtras = null;
+            mData = null;
+        }
+    }
+
+    private class ConnectionCallbackForDelayedMediaSession extends
+            MediaBrowserCompat.ConnectionCallback {
+        private int mConnectedCount = 0;
+
+        @Override
+        public void onConnected() {
+            synchronized (mWaitLock) {
+                mConnectedCount++;
+                mWaitLock.notify();
+            }
+        }
+    };
+
 }
diff --git a/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompat.java b/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompat.java
index b943594..e7adc79 100644
--- a/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompat.java
+++ b/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompat.java
@@ -33,6 +33,7 @@
     static final String EXTRAS_KEY = "test_extras_key";
     static final String EXTRAS_VALUE = "test_extras_value";
 
+    static final String MEDIA_ID = "test_media_id";
     static final String MEDIA_ID_INVALID = "test_media_id_invalid";
     static final String MEDIA_ID_ROOT = "test_media_id_root";
     static final String MEDIA_ID_CHILDREN_DELAYED = "test_media_id_children_delayed";
@@ -49,6 +50,9 @@
     static final String SEARCH_QUERY_FOR_NO_RESULT = "query no result";
     static final String SEARCH_QUERY_FOR_ERROR = "query for error";
 
+    static final String CUSTOM_ACTION = "CUSTOM_ACTION";
+    static final String CUSTOM_ACTION_FOR_ERROR = "CUSTOM_ACTION_FOR_ERROR";
+
     static StubMediaBrowserServiceCompat sInstance;
 
     /* package private */ static MediaSessionCompat sSession;
@@ -57,6 +61,9 @@
     private Result<MediaItem> mPendingLoadItemResult;
     private Bundle mPendingRootHints;
 
+    /* package private */ Bundle mCustomActionExtras;
+    /* package private */ Result<Bundle> mCustomActionResult;
+
     @Override
     public void onCreate() {
         super.onCreate();
@@ -133,6 +140,18 @@
         }
     }
 
+    @Override
+    public void onCustomAction(String action, Bundle extras,
+            Result<Bundle> result) {
+        mCustomActionResult = result;
+        mCustomActionExtras = extras;
+        if (CUSTOM_ACTION_FOR_ERROR.equals(action)) {
+            result.sendError(null);
+        } else if (CUSTOM_ACTION.equals(action)) {
+            result.detach();
+        }
+    }
+
     public void sendDelayedNotifyChildrenChanged() {
         if (mPendingLoadChildrenResult != null) {
             mPendingLoadChildrenResult.sendResult(Collections.<MediaItem>emptyList());
diff --git a/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompatWithDelayedMediaSession.java b/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompatWithDelayedMediaSession.java
new file mode 100644
index 0000000..e93c940
--- /dev/null
+++ b/media-compat/tests/src/android/support/v4/media/StubMediaBrowserServiceCompatWithDelayedMediaSession.java
@@ -0,0 +1,62 @@
+/*
+ * 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.media;
+
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.media.session.MediaSessionCompat;
+
+import java.util.List;
+
+/**
+ * Stub implementation of {@link MediaBrowserServiceCompat}.
+ * This implementation does not call
+ * {@link MediaBrowserServiceCompat#setSessionToken(MediaSessionCompat.Token)} in its
+ * {@link android.app.Service#onCreate}.
+ */
+public class StubMediaBrowserServiceCompatWithDelayedMediaSession extends
+        MediaBrowserServiceCompat {
+
+    static StubMediaBrowserServiceCompatWithDelayedMediaSession sInstance;
+    private MediaSessionCompat mSession;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        sInstance = this;
+        mSession = new MediaSessionCompat(
+                this, "StubMediaBrowserServiceCompatWithDelayedMediaSession");
+    }
+
+    @Nullable
+    @Override
+    public BrowserRoot onGetRoot(@NonNull String clientPackageName,
+            int clientUid, @Nullable Bundle rootHints) {
+        return new BrowserRoot("StubRootId", null);
+    }
+
+    @Override
+    public void onLoadChildren(@NonNull String parentId,
+            @NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
+        result.detach();
+    }
+
+    void callSetSessionToken() {
+        setSessionToken(mSession.getSessionToken());
+    }
+}
diff --git a/media-compat/tests/src/android/support/v4/media/StubRemoteMediaBrowserServiceCompat.java b/media-compat/tests/src/android/support/v4/media/StubRemoteMediaBrowserServiceCompat.java
new file mode 100644
index 0000000..9d7e73d
--- /dev/null
+++ b/media-compat/tests/src/android/support/v4/media/StubRemoteMediaBrowserServiceCompat.java
@@ -0,0 +1,74 @@
+/*
+ * 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.media;
+
+import android.os.Bundle;
+import android.support.v4.media.MediaBrowserCompat.MediaItem;
+import android.support.v4.media.session.MediaSessionCompat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Stub implementation of {@link android.support.v4.media.MediaBrowserServiceCompat}.
+ */
+public class StubRemoteMediaBrowserServiceCompat extends MediaBrowserServiceCompat {
+    static final String EXTRAS_KEY = "test_extras_key";
+    static final String EXTRAS_VALUE = "test_extras_value";
+
+    static final String MEDIA_ID_ROOT = "test_media_id_root";
+
+    static final String[] MEDIA_ID_CHILDREN = new String[]{
+            "test_media_id_children_0", "test_media_id_children_1",
+            "test_media_id_children_2", "test_media_id_children_3"
+    };
+
+    private static MediaSessionCompat mSession;
+    private Bundle mExtras;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mSession = new MediaSessionCompat(this, "StubRemoteMediaBrowserServiceCompat");
+        setSessionToken(mSession.getSessionToken());
+    }
+
+    @Override
+    public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
+        mExtras = new Bundle();
+        mExtras.putString(EXTRAS_KEY, EXTRAS_VALUE);
+        return new BrowserRoot(MEDIA_ID_ROOT, mExtras);
+    }
+
+    @Override
+    public void onLoadChildren(final String parentMediaId, final Result<List<MediaItem>> result) {
+        List<MediaItem> mediaItems = new ArrayList<>();
+        if (MEDIA_ID_ROOT.equals(parentMediaId)) {
+            Bundle rootHints = getBrowserRootHints();
+            for (String id : MEDIA_ID_CHILDREN) {
+                mediaItems.add(createMediaItem(id));
+            }
+            result.sendResult(mediaItems);
+        }
+    }
+
+    private MediaItem createMediaItem(String id) {
+        return new MediaItem(new MediaDescriptionCompat.Builder()
+                .setMediaId(id).setExtras(getBrowserRootHints()).build(),
+                MediaItem.FLAG_BROWSABLE);
+    }
+}
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
index 2598bef..d72e499 100644
--- a/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java
+++ b/media-compat/tests/src/android/support/v4/media/session/MediaControllerCompatTest.java
@@ -21,18 +21,22 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import android.media.AudioManager;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.PlaybackState;
 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.os.SystemClock;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v4.media.MediaDescriptionCompat;
-import android.support.v4.media.PollingCheck;
 import android.support.v4.media.RatingCompat;
 import android.support.v4.media.VolumeProviderCompat;
 
@@ -52,6 +56,10 @@
     private static final String EXTRAS_KEY = "test-key";
     private static final String EXTRAS_VALUE = "test-val";
     private static final float DELTA = 1e-4f;
+    private static final boolean ENABLED = true;
+    private static final boolean DISABLED = false;
+    private static final long TEST_POSITION = 1000000L;
+    private static final float TEST_PLAYBACK_SPEED = 3.0f;
 
     private final Object mWaitLock = new Object();
     private Handler mHandler = new Handler(Looper.getMainLooper());
@@ -90,15 +98,6 @@
                 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());
     }
 
@@ -162,6 +161,15 @@
             assertTrue(mCallback.mOnRemoveQueueItemCalled);
             assertEquals(mediaId, mCallback.mQueueDescription.getMediaId());
             assertEquals(mediaTitle, mCallback.mQueueDescription.getTitle());
+
+            // Try to modify the queue when the session does not support queue management.
+            mSession.setFlags(0);
+            try {
+                mController.addQueueItem(itemDescription);
+                fail();
+            } catch (UnsupportedOperationException e) {
+                // Expected.
+            }
         }
     }
 
@@ -349,6 +357,12 @@
             assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
 
             mCallback.reset();
+            controls.setCaptioningEnabled(ENABLED);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnSetCaptioningEnabledCalled);
+            assertEquals(ENABLED, mCallback.mCaptioningEnabled);
+
+            mCallback.reset();
             final int repeatMode = PlaybackStateCompat.REPEAT_MODE_ALL;
             controls.setRepeatMode(repeatMode);
             mWaitLock.wait(TIME_OUT_MS);
@@ -356,11 +370,10 @@
             assertEquals(repeatMode, mCallback.mRepeatMode);
 
             mCallback.reset();
-            final boolean shuffleModeEnabled = true;
-            controls.setShuffleModeEnabled(shuffleModeEnabled);
+            controls.setShuffleModeEnabled(ENABLED);
             mWaitLock.wait(TIME_OUT_MS);
             assertTrue(mCallback.mOnSetShuffleModeEnabledCalled);
-            assertEquals(shuffleModeEnabled, mCallback.mShuffleModeEnabled);
+            assertEquals(ENABLED, mCallback.mShuffleModeEnabled);
         }
     }
 
@@ -383,6 +396,40 @@
         assertEquals(currentVolume, info.getCurrentVolume());
     }
 
+    @Test
+    @SmallTest
+    public void testGetPlaybackStateWithPositionUpdate() throws InterruptedException {
+        final long stateSetTime = SystemClock.elapsedRealtime();
+        PlaybackStateCompat stateIn = new PlaybackStateCompat.Builder()
+                .setState(PlaybackStateCompat.STATE_PLAYING, TEST_POSITION, TEST_PLAYBACK_SPEED,
+                        stateSetTime)
+                .build();
+        mSession.setPlaybackState(stateIn);
+
+        final long waitDuration = 100L;
+        Thread.sleep(waitDuration);
+
+        final long expectedUpdateTime = waitDuration + stateSetTime;
+        final long expectedPosition = (long) (TEST_PLAYBACK_SPEED * waitDuration) + TEST_POSITION;
+
+        final double updateTimeTolerance = 30L;
+        final double positionTolerance = updateTimeTolerance * TEST_PLAYBACK_SPEED;
+
+        PlaybackStateCompat stateOut = mSession.getController().getPlaybackState();
+        assertEquals(expectedUpdateTime, stateOut.getLastPositionUpdateTime(), updateTimeTolerance);
+        assertEquals(expectedPosition, stateOut.getPosition(), positionTolerance);
+
+        // Compare the result with MediaController.getPlaybackState().
+        if (Build.VERSION.SDK_INT >= 21) {
+            MediaController controller = new MediaController(
+                    getContext(), (MediaSession.Token) mSession.getSessionToken().getToken());
+            PlaybackState state = controller.getPlaybackState();
+            assertEquals(state.getLastPositionUpdateTime(), stateOut.getLastPositionUpdateTime(),
+                    updateTimeTolerance);
+            assertEquals(state.getPosition(), stateOut.getPosition(), positionTolerance);
+        }
+    }
+
     private class MediaSessionCallback extends MediaSessionCompat.Callback {
         private long mSeekPosition;
         private long mQueueItemId;
@@ -394,6 +441,7 @@
         private String mCommand;
         private Bundle mExtras;
         private ResultReceiver mCommandCallback;
+        private boolean mCaptioningEnabled;
         private int mRepeatMode;
         private boolean mShuffleModeEnabled;
         private int mQueueIndex;
@@ -418,6 +466,7 @@
         private boolean mOnPrepareFromMediaIdCalled;
         private boolean mOnPrepareFromSearchCalled;
         private boolean mOnPrepareFromUriCalled;
+        private boolean mOnSetCaptioningEnabledCalled;
         private boolean mOnSetRepeatModeCalled;
         private boolean mOnSetShuffleModeEnabledCalled;
         private boolean mOnAddQueueItemCalled;
@@ -436,6 +485,7 @@
             mExtras = null;
             mCommand = null;
             mCommandCallback = null;
+            mCaptioningEnabled = false;
             mShuffleModeEnabled = false;
             mRepeatMode = PlaybackStateCompat.REPEAT_MODE_NONE;
             mQueueIndex = -1;
@@ -460,6 +510,7 @@
             mOnPrepareFromMediaIdCalled = false;
             mOnPrepareFromSearchCalled = false;
             mOnPrepareFromUriCalled = false;
+            mOnSetCaptioningEnabledCalled = false;
             mOnSetRepeatModeCalled = false;
             mOnSetShuffleModeEnabledCalled = false;
             mOnAddQueueItemCalled = false;
@@ -678,6 +729,15 @@
         }
 
         @Override
+        public void onSetCaptioningEnabled(boolean enabled) {
+            synchronized (mWaitLock) {
+                mOnSetCaptioningEnabledCalled = true;
+                mCaptioningEnabled = enabled;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
         public void onSetShuffleModeEnabled(boolean enabled) {
             synchronized (mWaitLock) {
                 mOnSetShuffleModeEnabledCalled = true;
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 0e85c1c..fabe72d 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
@@ -38,7 +38,6 @@
 import android.os.Parcel;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.support.v4.media.PollingCheck;
 import android.support.v4.media.MediaDescriptionCompat;
 import android.support.v4.media.MediaMetadataCompat;
 import android.support.v4.media.RatingCompat;
@@ -213,9 +212,6 @@
     @SmallTest
     public void testSetPlaybackState() throws Exception {
         MediaControllerCompat controller = mSession.getController();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            waitUntilExtraBinderReady(controller);
-        }
         controller.registerCallback(mCallback, mHandler);
         synchronized (mWaitLock) {
             mCallback.resetLocked();
@@ -310,15 +306,37 @@
     }
 
     /**
+     * Tests {@link MediaSessionCompat#setCaptioningEnabled}.
+     */
+    @Test
+    @SmallTest
+    public void testSetCaptioningEnabled() throws Exception {
+        MediaControllerCompat controller = mSession.getController();
+        controller.registerCallback(mCallback, mHandler);
+        synchronized (mWaitLock) {
+            mCallback.resetLocked();
+            mSession.setCaptioningEnabled(true);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnCaptioningEnabledChangedCalled);
+            assertEquals(true, mCallback.mCaptioningEnabled);
+            assertEquals(true, controller.isCaptioningEnabled());
+
+            mCallback.resetLocked();
+            mSession.setCaptioningEnabled(false);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnCaptioningEnabledChangedCalled);
+            assertEquals(false, mCallback.mCaptioningEnabled);
+            assertEquals(false, controller.isCaptioningEnabled());
+        }
+    }
+
+    /**
      * Tests {@link MediaSessionCompat#setRepeatMode}.
      */
     @Test
     @SmallTest
     public void testSetRepeatMode() throws Exception {
         MediaControllerCompat controller = mSession.getController();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            waitUntilExtraBinderReady(controller);
-        }
         controller.registerCallback(mCallback, mHandler);
         synchronized (mWaitLock) {
             mCallback.resetLocked();
@@ -339,13 +357,9 @@
     public void testSetShuffleModeEnabled() throws Exception {
         final boolean shuffleModeEnabled = true;
         MediaControllerCompat controller = mSession.getController();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            waitUntilExtraBinderReady(controller);
-        }
         controller.registerCallback(mCallback, mHandler);
         synchronized (mWaitLock) {
             mCallback.resetLocked();
-            final int repeatMode = PlaybackStateCompat.REPEAT_MODE_ALL;
             mSession.setShuffleModeEnabled(shuffleModeEnabled);
             mWaitLock.wait(TIME_OUT_MS);
             assertTrue(mCallback.mOnShuffleModeChangedCalled);
@@ -361,10 +375,6 @@
     @SmallTest
     public void testSendSessionEvent() throws Exception {
         MediaControllerCompat controller = mSession.getController();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
-                Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
-            waitUntilExtraBinderReady(controller);
-        }
         controller.registerCallback(mCallback, mHandler);
         synchronized (mWaitLock) {
             mCallback.resetLocked();
@@ -620,15 +630,6 @@
         controller.dispatchMediaButtonEvent(new KeyEvent(KeyEvent.ACTION_UP, keyCode));
     }
 
-    private void waitUntilExtraBinderReady(final MediaControllerCompat controller) {
-        new PollingCheck(TIME_OUT_MS) {
-            @Override
-            protected boolean check() {
-                return controller.isExtraBinderReady();
-            }
-        }.run();
-    }
-
     private class MediaControllerCallback extends MediaControllerCompat.Callback {
         private volatile boolean mOnPlaybackStateChangedCalled;
         private volatile boolean mOnMetadataChangedCalled;
@@ -638,6 +639,7 @@
         private volatile boolean mOnAudioInfoChangedCalled;
         private volatile boolean mOnSessionDestroyedCalled;
         private volatile boolean mOnSessionEventCalled;
+        private volatile boolean mOnCaptioningEnabledChangedCalled;
         private volatile boolean mOnRepeatModeChangedCalled;
         private volatile boolean mOnShuffleModeChangedCalled;
 
@@ -648,6 +650,7 @@
         private volatile String mEvent;
         private volatile Bundle mExtras;
         private volatile MediaControllerCompat.PlaybackInfo mPlaybackInfo;
+        private volatile boolean mCaptioningEnabled;
         private volatile int mRepeatMode;
         private volatile boolean mShuffleModeEnabled;
 
@@ -669,6 +672,7 @@
             mTitle = null;
             mExtras = null;
             mPlaybackInfo = null;
+            mCaptioningEnabled = false;
             mRepeatMode = PlaybackStateCompat.REPEAT_MODE_NONE;
             mShuffleModeEnabled = false;
         }
@@ -746,6 +750,15 @@
         }
 
         @Override
+        public void onCaptioningEnabledChanged(boolean enabled) {
+            synchronized (mWaitLock) {
+                mOnCaptioningEnabledChangedCalled = true;
+                mCaptioningEnabled = enabled;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
         public void onRepeatModeChanged(int repeatMode) {
             synchronized (mWaitLock) {
                 mOnRepeatModeChangedCalled = true;
diff --git a/percent/AndroidManifest.xml b/percent/AndroidManifest.xml
index 0d55165..46ccce8 100644
--- a/percent/AndroidManifest.xml
+++ b/percent/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.percent">
     <uses-sdk android:minSdkVersion="9"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/recommendation/AndroidManifest.xml b/recommendation/AndroidManifest.xml
index e36c822..09017e0 100644
--- a/recommendation/AndroidManifest.xml
+++ b/recommendation/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.recommendation">
     <uses-sdk android:minSdkVersion="21"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/recommendation/build.gradle b/recommendation/build.gradle
index dadad58..56633de 100644
--- a/recommendation/build.gradle
+++ b/recommendation/build.gradle
@@ -47,3 +47,37 @@
 
     artifacts.add('archives', sourcesJarTask);
 }
+
+uploadArchives {
+    repositories {
+        mavenDeployer {
+            repository(url: uri(rootProject.ext.supportRepoOut)) {
+            }
+
+            pom.project {
+                name 'Android Support Recommendation'
+                description "Android Support Recommendation"
+                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'
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/samples/Support7Demos/AndroidManifest.xml b/samples/Support7Demos/AndroidManifest.xml
index 0ba2e6a..8200390 100644
--- a/samples/Support7Demos/AndroidManifest.xml
+++ b/samples/Support7Demos/AndroidManifest.xml
@@ -537,6 +537,16 @@
                 <category android:name="com.example.android.supportv7.SAMPLE_CODE"/>
             </intent-filter>
         </activity>
+
+        <!-- ListView styling activity -->
+        <activity android:name=".widget.ListViewActivity"
+                  android:label="@string/list_view_activity"
+                  android:theme="@style/Theme.AppCompat.Light">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="com.example.android.supportv7.SAMPLE_CODE"/>
+            </intent-filter>
+        </activity>
     </application>
 
 
diff --git a/samples/Support7Demos/res/layout/list_view_activity.xml b/samples/Support7Demos/res/layout/list_view_activity.xml
new file mode 100644
index 0000000..aed3ea6
--- /dev/null
+++ b/samples/Support7Demos/res/layout/list_view_activity.xml
@@ -0,0 +1,23 @@
+<?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.
+  -->
+
+<ListView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/list_view"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
+
diff --git a/samples/Support7Demos/res/layout/list_view_item.xml b/samples/Support7Demos/res/layout/list_view_item.xml
new file mode 100644
index 0000000..4a97d34
--- /dev/null
+++ b/samples/Support7Demos/res/layout/list_view_item.xml
@@ -0,0 +1,37 @@
+<?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.
+  -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:padding="12dp"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/title"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?attr/textAppearanceListItem" />
+
+    <TextView
+        android:id="@+id/subtitle"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:textAppearance="?attr/textAppearanceListItemSecondary" />
+
+</LinearLayout>
diff --git a/samples/Support7Demos/res/layout/popup_menu_activity.xml b/samples/Support7Demos/res/layout/popup_menu_activity.xml
index c3ed4f5..552a996 100644
--- a/samples/Support7Demos/res/layout/popup_menu_activity.xml
+++ b/samples/Support7Demos/res/layout/popup_menu_activity.xml
@@ -27,6 +27,16 @@
         android:layout_centerHorizontal="true"
         android:text="@string/popup_menu_button" />
 
+    <android.support.v7.widget.SwitchCompat
+        android:id="@+id/elevation_toggle"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/test_button"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        android:checked="true"
+        android:text="@string/popup_default_elevation" />
+
     <TextView
         android:id="@+id/log"
         android:layout_width="match_parent"
diff --git a/samples/Support7Demos/res/values-v21/styles.xml b/samples/Support7Demos/res/values-v21/styles.xml
new file mode 100644
index 0000000..00d54c9
--- /dev/null
+++ b/samples/Support7Demos/res/values-v21/styles.xml
@@ -0,0 +1,21 @@
+<?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="CustomPopupNoElevation" parent="@style/Widget.AppCompat.Light.PopupMenu">
+        <item name="android:popupElevation">2dp</item>
+    </style>
+</resources>
diff --git a/samples/Support7Demos/res/values/strings.xml b/samples/Support7Demos/res/values/strings.xml
index 6794eae..b5b6a51 100644
--- a/samples/Support7Demos/res/values/strings.xml
+++ b/samples/Support7Demos/res/values/strings.xml
@@ -213,6 +213,7 @@
     <string name="popup_menu_activity">AppCompat/Popup menu</string>
     <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_default_elevation">Use default elevation on popup</string>
     <string name="popup_menu_highlight">Highlight</string>
     <string name="popup_menu_edit">Edit</string>
     <string name="popup_menu_delete">Delete</string>
@@ -222,6 +223,8 @@
     <string name="popup_menu_share_circles">To my circles</string>
     <string name="popup_menu_print">Print</string>
 
+    <string name="list_view_activity">AppCompat/ListView styling</string>
+
     <string name="appcompat_vector_disabled">AnimatedVectorDrawableCompat does not work on devices running API v10 or below</string>
     <string name="appcompat_vector_title">AppCompat/Integrations/AnimatedVectorDrawable</string>
 
diff --git a/samples/Support7Demos/res/values/styles.xml b/samples/Support7Demos/res/values/styles.xml
index a1ec841..ca2eb9f 100644
--- a/samples/Support7Demos/res/values/styles.xml
+++ b/samples/Support7Demos/res/values/styles.xml
@@ -56,4 +56,6 @@
         <item name="windowActionModeOverlay">true</item>
         <item name="android:windowContentOverlay">@null</item>
     </style>
+
+    <style name="CustomPopupNoElevation" parent="@style/Widget.AppCompat.Light.PopupMenu" />
 </resources>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/ListViewActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/ListViewActivity.java
new file mode 100644
index 0000000..cb0c2e2
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/ListViewActivity.java
@@ -0,0 +1,71 @@
+/*
+ * 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 com.example.android.supportv7.widget;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.example.android.supportv7.R;
+
+/**
+ * Sample activity for the demo of list item styles.
+ */
+public class ListViewActivity extends AppCompatActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.list_view_activity);
+        ListView listView = (ListView) findViewById(R.id.list_view);
+        listView.setAdapter(new BaseAdapter() {
+            @Override
+            public int getCount() {
+                return 100;
+            }
+
+            @Override
+            public Object getItem(int i) {
+                return null;
+            }
+
+            @Override
+            public long getItemId(int i) {
+                return i;
+            }
+
+            @Override
+            public View getView(int i, View view, ViewGroup viewGroup) {
+                // this is just a demo, so not using view holders
+                if (view == null) {
+                    view = LayoutInflater.from(viewGroup.getContext()).inflate(
+                            R.layout.list_view_item, viewGroup, false);
+                }
+                TextView title = (TextView) view.findViewById(R.id.title);
+                TextView subtitle = (TextView) view.findViewById(R.id.subtitle);
+                title.setText("Title for #" + i);
+                subtitle.setText("Subtitle for #" + i);
+                return view;
+            }
+        });
+    }
+}
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..080fb5a 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/widget/PopupMenuActivity.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/PopupMenuActivity.java
@@ -19,26 +19,23 @@
 import android.os.Bundle;
 import android.support.v7.app.AppCompatActivity;
 import android.support.v7.widget.PopupMenu;
+import android.support.v7.widget.SwitchCompat;
+import android.view.Gravity;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.TextView;
+
 import com.example.android.supportv7.R;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
 
 public class PopupMenuActivity extends AppCompatActivity {
-    private ViewGroup mContainer;
-
     private TextView mLog;
 
-    private Button mButton;
-
-    private PopupMenu mPopupMenu;
-
     private SimpleDateFormat mDateFormat;
 
     @Override
@@ -49,20 +46,31 @@
 
         mDateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
 
-        mContainer = (ViewGroup) findViewById(R.id.container);
-        mLog = (TextView) mContainer.findViewById(R.id.log);
-        mButton = (Button) mContainer.findViewById(R.id.test_button);
+        final ViewGroup container = (ViewGroup) findViewById(R.id.container);
+        mLog = (TextView) container.findViewById(R.id.log);
 
-        mButton.setOnClickListener(new View.OnClickListener() {
+        final SwitchCompat elevationToggle = (SwitchCompat) container.findViewById(
+                R.id.elevation_toggle);
+        final Button button = (Button) container.findViewById(R.id.test_button);
+        button.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                mPopupMenu = new PopupMenu(mContainer.getContext(), mButton);
-                final MenuInflater menuInflater = mPopupMenu.getMenuInflater();
-                menuInflater.inflate(R.menu.popup_menu, mPopupMenu.getMenu());
+                // Do we need to use a custom style that removes elevation?
+                boolean useDefaultElevation = elevationToggle.isChecked();
+
+                PopupMenu popupMenu = null;
+                if (useDefaultElevation) {
+                    popupMenu = new PopupMenu(container.getContext(), button);
+                } else {
+                    popupMenu = new PopupMenu(container.getContext(), button, Gravity.NO_GRAVITY,
+                            0, R.style.CustomPopupNoElevation);
+                }
+                final MenuInflater menuInflater = popupMenu.getMenuInflater();
+                menuInflater.inflate(R.menu.popup_menu, popupMenu.getMenu());
 
                 // Register a listener to be notified when a menu item in our popup menu has
                 // been clicked.
-                mPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                     @Override
                     public boolean onMenuItemClick(MenuItem item) {
                         addToLog("Item '"+ item.getTitle() + "' clicked");
@@ -71,7 +79,7 @@
                 });
 
                 // Register a listener to be notified when our popup menu is dismissed.
-                mPopupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
+                popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
                     @Override
                     public void onDismiss(PopupMenu menu) {
                         addToLog("Popup menu dismissed");
@@ -79,7 +87,7 @@
                 });
 
                 // Show the popup menu
-                mPopupMenu.show();
+                popupMenu.show();
             }
         });
     }
diff --git a/samples/SupportAnimationDemos/Android.mk b/samples/SupportAnimationDemos/Android.mk
new file mode 100644
index 0000000..bbc786a
--- /dev/null
+++ b/samples/SupportAnimationDemos/Android.mk
@@ -0,0 +1,31 @@
+# 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.
+
+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 := SupportAnimationDemos
+LOCAL_MODULE_TAGS := samples
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 16
+LOCAL_DEX_PREOPT := false
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+        android-support-dynamic-animation
+LOCAL_AAPT_FLAGS := --no-version-vectors
+include $(BUILD_PACKAGE)
diff --git a/samples/SupportAnimationDemos/AndroidManifest.xml b/samples/SupportAnimationDemos/AndroidManifest.xml
new file mode 100644
index 0000000..25e5ec8
--- /dev/null
+++ b/samples/SupportAnimationDemos/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?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"
+    package="com.example.android.support.animation">
+
+    <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="25" />
+
+    <application android:label="@string/activity_sample_code"
+            android:supportsRtl="true"
+            android:icon="@drawable/app_sample_code"
+            android:theme="@style/android:Theme.Holo.Light">
+        <activity android:name=".MainActivity"
+                  android:label="ChainedSpringDemo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".BrowseActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".SpringActivity"
+                  android:label="SpringDemo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/samples/SupportAnimationDemos/build.gradle b/samples/SupportAnimationDemos/build.gradle
new file mode 100644
index 0000000..dd3e350
--- /dev/null
+++ b/samples/SupportAnimationDemos/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.application'
+
+dependencies {
+    compile project(':support-dynamic-animation')
+}
+
+android {
+    compileSdkVersion project.ext.currentSdk
+
+    defaultConfig {
+        minSdkVersion 16
+    }
+
+    sourceSets {
+        main.manifest.srcFile 'AndroidManifest.xml'
+        main.java.srcDirs = ['src']
+        main.aidl.srcDirs = ['src']
+        main.res.srcDirs = ['res']
+    }
+
+    lintOptions {
+        abortOnError true
+    }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_7
+        targetCompatibility JavaVersion.VERSION_1_7
+    }
+}
+
diff --git a/samples/SupportVectorDrawable/static/res/drawable/app_sample_code.png b/samples/SupportAnimationDemos/res/drawable-hdpi/app_sample_code.png
similarity index 100%
copy from samples/SupportVectorDrawable/static/res/drawable/app_sample_code.png
copy to samples/SupportAnimationDemos/res/drawable-hdpi/app_sample_code.png
Binary files differ
diff --git a/samples/SupportAnimationDemos/res/drawable-mdpi/app_sample_code.png b/samples/SupportAnimationDemos/res/drawable-mdpi/app_sample_code.png
new file mode 100644
index 0000000..5ae7701
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/drawable-mdpi/app_sample_code.png
Binary files differ
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/samples/SupportAnimationDemos/res/drawable/circle.xml
similarity index 68%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to samples/SupportAnimationDemos/res/drawable/circle.xml
index 36c297f..a343f54 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/samples/SupportAnimationDemos/res/drawable/circle.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- 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.
@@ -14,9 +14,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <size
+        android:width="40dp"
+        android:height="40dp"/>
+    <solid
+        android:color="#2E7D32"/>
+</shape>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/samples/SupportAnimationDemos/res/drawable/green_circle.xml
similarity index 68%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to samples/SupportAnimationDemos/res/drawable/green_circle.xml
index 36c297f..833fc9e 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/samples/SupportAnimationDemos/res/drawable/green_circle.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- 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.
@@ -14,9 +14,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <size
+        android:width="40dp"
+        android:height="40dp"/>
+    <solid
+        android:color="#4CAF50"/>
+</shape>
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/samples/SupportAnimationDemos/res/drawable/light_green_circle.xml
similarity index 68%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to samples/SupportAnimationDemos/res/drawable/light_green_circle.xml
index 36c297f..c181576 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/samples/SupportAnimationDemos/res/drawable/light_green_circle.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- 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.
@@ -14,9 +14,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <size
+        android:width="40dp"
+        android:height="40dp"/>
+    <solid
+        android:color="#A5D6A7"/>
+</shape>
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/samples/SupportAnimationDemos/res/drawable/spring_demo_circle.xml
similarity index 66%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to samples/SupportAnimationDemos/res/drawable/spring_demo_circle.xml
index 36c297f..d370267 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/samples/SupportAnimationDemos/res/drawable/spring_demo_circle.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- 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.
@@ -14,9 +14,11 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="oval">
+    <size
+        android:width="40dp"
+        android:height="40dp"/>
+    <solid
+        android:color="@android:color/holo_green_light"></solid>
+</shape>
\ No newline at end of file
diff --git a/samples/SupportAnimationDemos/res/layout/activity_chained_springs.xml b/samples/SupportAnimationDemos/res/layout/activity_chained_springs.xml
new file mode 100644
index 0000000..ff8a7f7
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/layout/activity_chained_springs.xml
@@ -0,0 +1,100 @@
+<?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.
+-->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:layout_width="match_parent" android:layout_height="match_parent">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_gravity="bottom"
+        android:layout_marginBottom="50dp"
+        android:orientation="horizontal">
+        <LinearLayout
+            android:layout_width="100dp"
+            android:layout_height="match_parent"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Damping Ratio:"/>
+            <TextView
+                android:id="@+id/damping_ratio_txt"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"/>
+        </LinearLayout>
+        <SeekBar
+            android:id="@+id/damping_ratio"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"/>
+    </LinearLayout>
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="50dp"
+        android:layout_gravity="bottom"
+        android:orientation="horizontal">
+        <LinearLayout
+            android:layout_width="100dp"
+            android:layout_height="match_parent"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Stiffness:"/>
+            <TextView
+                android:id="@+id/stiffness_txt"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"/>
+        </LinearLayout>
+        <SeekBar
+            android:id="@+id/stiffness"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"/>
+    </LinearLayout>
+    <LinearLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center_horizontal"
+        android:orientation="vertical">
+        <TextView
+            android:id="@+id/lead"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            android:layout_margin="20dp"
+            android:background="@drawable/circle"
+            android:gravity="center"
+            android:text="Drag\n Me"
+            android:textColor="#FFFFAD"/>
+        <ImageView
+            android:id="@+id/follow1"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            android:layout_margin="20dp"
+            android:src="@drawable/green_circle"/>
+        <ImageView
+            android:id="@+id/follow2"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            android:layout_margin="20dp"
+            android:src="@drawable/light_green_circle"/>
+    </LinearLayout>
+</FrameLayout>
\ No newline at end of file
diff --git a/samples/SupportAnimationDemos/res/layout/activity_main.xml b/samples/SupportAnimationDemos/res/layout/activity_main.xml
new file mode 100644
index 0000000..4e8d9b4
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/layout/activity_main.xml
@@ -0,0 +1,104 @@
+<?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.
+-->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/activity_main"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context="com.example.android.support.animation.SpringActivity">
+
+    <FrameLayout
+        android:id="@+id/container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <com.example.android.support.animation.SpringView
+            android:id="@+id/actual_spring"
+            android:layout_width="100dp"
+            android:layout_height="match_parent"
+            android:layout_gravity="center_horizontal"/>
+        <ImageView
+            android:id="@+id/imageView"
+            android:layout_width="100dp"
+            android:layout_height="100dp"
+            android:layout_centerHorizontal="true"
+            android:layout_centerVertical="true"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginTop="50dp"
+            android:src="@drawable/spring_demo_circle"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_gravity="bottom"
+            android:layout_marginBottom="50dp"
+            android:orientation="horizontal">
+            <LinearLayout
+                android:layout_width="100dp"
+                android:layout_height="match_parent"
+                android:gravity="center_horizontal"
+                android:orientation="vertical">
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="Damping Ratio:"/>
+                <TextView
+                    android:id="@+id/damping_ratio_txt"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"/>
+            </LinearLayout>
+            <SeekBar
+                android:id="@+id/damping_ratio"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"/>
+        </LinearLayout>
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="50dp"
+            android:layout_gravity="bottom"
+            android:orientation="horizontal">
+            <LinearLayout
+                android:layout_width="100dp"
+                android:layout_height="match_parent"
+                android:gravity="center_horizontal"
+                android:orientation="vertical">
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="Stiffness:"/>
+                <TextView
+                    android:id="@+id/stiffness_txt"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"/>
+            </LinearLayout>
+            <SeekBar
+                android:id="@+id/stiffness"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"/>
+        </LinearLayout>
+
+    </FrameLayout>
+</RelativeLayout>
diff --git a/samples/SupportAnimationDemos/res/values-w820dp/dimens.xml b/samples/SupportAnimationDemos/res/values-w820dp/dimens.xml
new file mode 100644
index 0000000..3ef1782
--- /dev/null
+++ b/samples/SupportAnimationDemos/res/values-w820dp/dimens.xml
@@ -0,0 +1,22 @@
+<?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>
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/samples/SupportAnimationDemos/res/values/colors.xml
similarity index 70%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to samples/SupportAnimationDemos/res/values/colors.xml
index 36c297f..7141433 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/samples/SupportAnimationDemos/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) 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,6 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<resources>
+    <color name="springColor">#ff0099cc</color>
+</resources>
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/samples/SupportAnimationDemos/res/values/dimens.xml
similarity index 69%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to samples/SupportAnimationDemos/res/values/dimens.xml
index 36c297f..f5b011c 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/samples/SupportAnimationDemos/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) 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,8 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/samples/SupportAnimationDemos/res/values/strings.xml
similarity index 70%
copy from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
copy to samples/SupportAnimationDemos/res/values/strings.xml
index 36c297f..3412861 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/samples/SupportAnimationDemos/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) 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,6 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+<resources>
+    <string name="activity_sample_code">Support Animation Demos</string>
+</resources>
diff --git a/samples/SupportAnimationDemos/src/com/example/android/support/animation/BrowseActivity.java b/samples/SupportAnimationDemos/src/com/example/android/support/animation/BrowseActivity.java
new file mode 100644
index 0000000..e330302
--- /dev/null
+++ b/samples/SupportAnimationDemos/src/com/example/android/support/animation/BrowseActivity.java
@@ -0,0 +1,154 @@
+/*
+ * 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 com.example.android.support.animation;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This activity lists all the activities in this application.
+ */
+public class BrowseActivity extends ListActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Intent intent = getIntent();
+        String path = intent.getStringExtra("com.example.android.support.animation");
+
+        if (path == null) {
+            path = "";
+        }
+
+        setListAdapter(new SimpleAdapter(this, getData(path),
+                android.R.layout.simple_list_item_1, new String[] { "title" },
+                new int[] { android.R.id.text1 }));
+        getListView().setTextFilterEnabled(true);
+    }
+
+    protected List<Map<String, Object>> getData(String prefix) {
+        List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
+
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
+
+        PackageManager pm = getPackageManager();
+        List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
+
+        if (null == list) {
+            return myData;
+        }
+
+        String[] prefixPath;
+        String prefixWithSlash = prefix;
+
+        if (prefix.equals("")) {
+            prefixPath = null;
+        } else {
+            prefixPath = prefix.split("/");
+            prefixWithSlash = prefix + "/";
+        }
+
+        int len = list.size();
+
+        Map<String, Boolean> entries = new HashMap<String, Boolean>();
+
+        for (int i = 0; i < len; i++) {
+            ResolveInfo info = list.get(i);
+            CharSequence labelSeq = info.loadLabel(pm);
+            String label = labelSeq != null ? labelSeq.toString() : info.activityInfo.name;
+
+            if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
+
+                String[] labelPath = label.split("/");
+
+                String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
+
+                if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
+                    addItem(myData, nextLabel, activityIntent(
+                            info.activityInfo.applicationInfo.packageName,
+                            info.activityInfo.name));
+                } else {
+                    if (entries.get(nextLabel) == null) {
+                        addItem(myData, nextLabel, browseIntent(prefix.equals("")
+                                ? nextLabel : prefix + "/" + nextLabel));
+                        entries.put(nextLabel, true);
+                    }
+                }
+            }
+        }
+
+        Collections.sort(myData, sDisplayNameComparator);
+        return myData;
+    }
+
+    private static final Comparator<Map<String, Object>> sDisplayNameComparator =
+            new Comparator<Map<String, Object>>() {
+                public final Collator collator = Collator.getInstance();
+
+                public int compare(Map<String, Object> map1, Map<String, Object> map2) {
+                    return collator.compare(map1.get("title"), map2.get("title"));
+                }
+            };
+
+    protected Intent activityIntent(String pkg, String componentName) {
+        Intent result = new Intent();
+        result.setClassName(pkg, componentName);
+        return result;
+    }
+
+    protected Intent browseIntent(String path) {
+        Intent result = new Intent();
+        result.setClass(this, BrowseActivity.class);
+        result.putExtra("com.example.android.support.animation", path);
+        return result;
+    }
+
+    protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
+        Map<String, Object> temp = new HashMap<String, Object>();
+        temp.put("title", name);
+        temp.put("intent", intent);
+        data.add(temp);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        Map<String, Object> map = (Map<String, Object>) l.getItemAtPosition(position);
+
+        Intent intent = new Intent((Intent) map.get("intent"));
+        intent.addCategory(Intent.CATEGORY_SAMPLE_CODE);
+        startActivity(intent);
+    }
+}
+
+
diff --git a/samples/SupportAnimationDemos/src/com/example/android/support/animation/MainActivity.java b/samples/SupportAnimationDemos/src/com/example/android/support/animation/MainActivity.java
new file mode 100644
index 0000000..1ded677
--- /dev/null
+++ b/samples/SupportAnimationDemos/src/com/example/android/support/animation/MainActivity.java
@@ -0,0 +1,170 @@
+/*
+ * 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 com.example.android.support.animation;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.animation.DynamicAnimation;
+import android.support.animation.SpringAnimation;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+/**
+ * Activity for chained spring animations.
+ */
+public class MainActivity extends Activity {
+    private float mDampingRatio = 1.0f;
+    private float mStiffness = 50.0f;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_chained_springs);
+        final View lead = findViewById(R.id.lead);
+        final View follow1 = findViewById(R.id.follow1);
+        final View follow2 = findViewById(R.id.follow2);
+
+        final SpringAnimation anim1X = new SpringAnimation(follow1, DynamicAnimation.TRANSLATION_X,
+                lead.getTranslationX());
+        final SpringAnimation anim1Y = new SpringAnimation(follow1, DynamicAnimation.TRANSLATION_Y,
+                lead.getTranslationY());
+        final SpringAnimation anim2X = new SpringAnimation(follow2, DynamicAnimation.TRANSLATION_X,
+                follow1.getTranslationX());
+        final SpringAnimation anim2Y = new SpringAnimation(follow2, DynamicAnimation.TRANSLATION_Y,
+                follow1.getTranslationY());
+
+        anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
+            @Override
+            public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
+                                          float velocity) {
+                anim2X.animateToFinalPosition(value);
+            }
+        });
+
+        anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
+            @Override
+            public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value,
+                                          float velocity) {
+                anim2Y.animateToFinalPosition(value);
+            }
+        });
+
+        ((View) lead.getParent()).setOnTouchListener(new View.OnTouchListener() {
+            public float firstDownX = 0;
+            public float firstDownY = 0;
+            public VelocityTracker tracker;
+            @Override
+            public boolean onTouch(View view, MotionEvent motionEvent) {
+                if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
+
+                    if (motionEvent.getX() < lead.getX()
+                            || motionEvent.getX() > lead.getX() + lead.getWidth()
+                            || motionEvent.getY() < lead.getY()
+                            || motionEvent.getY() > lead.getY() + lead.getHeight()) {
+                        return false;
+                    }
+
+                    // Update the stiffness and damping ratio that are configured by user from the
+                    // seekbar UI as needed.
+                    anim1X.getSpring().setStiffness(mStiffness).setDampingRatio(mDampingRatio);
+                    anim1Y.getSpring().setStiffness(mStiffness).setDampingRatio(mDampingRatio);
+                    anim2X.getSpring().setStiffness(mStiffness).setDampingRatio(mDampingRatio);
+                    anim2Y.getSpring().setStiffness(mStiffness).setDampingRatio(mDampingRatio);
+
+                    firstDownX = motionEvent.getX() - lead.getTranslationX();
+                    firstDownY = motionEvent.getY() - lead.getTranslationY();
+                    tracker = VelocityTracker.obtain();
+                    tracker.clear();
+                    tracker.addMovement(motionEvent);
+                } else if (motionEvent.getActionMasked() == MotionEvent.ACTION_MOVE) {
+                    float deltaX = motionEvent.getX() - firstDownX;
+                    float deltaY = motionEvent.getY() - firstDownY;
+
+                    // Directly manipulate the lead view.
+                    lead.setTranslationX(deltaX);
+                    lead.setTranslationY(deltaY);
+
+                    // Animate the follow views to the new final position
+                    anim1X.animateToFinalPosition(deltaX);
+                    anim1Y.animateToFinalPosition(deltaY);
+
+                    tracker.addMovement(motionEvent);
+                }
+                return true;
+            }
+        });
+        setupSeekBars();
+    }
+
+    // Setup seek bars so damping ratio and stiffness for the spring can be modified through the UI.
+    void setupSeekBars() {
+        SeekBar dr = (SeekBar) findViewById(R.id.damping_ratio);
+        dr.setMax(130);
+        final TextView drTxt = (TextView) findViewById(R.id.damping_ratio_txt);
+        dr.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+                if (i < 80) {
+                    mDampingRatio = i / 80.0f;
+                } else if (i > 90) {
+                    mDampingRatio = (float) Math.exp((i - 90) / 10.0);
+                } else {
+                    mDampingRatio = 1;
+                }
+                drTxt.setText(String.format("%.4f", (float) mDampingRatio));
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+
+            }
+        });
+
+        SeekBar stiff = (SeekBar) findViewById(R.id.stiffness);
+        stiff.setMax(110);
+        final TextView nfTxt = (TextView) findViewById(R.id.stiffness_txt);
+        stiff.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+                float stiffness = (float) Math.exp(i / 10d);
+                mStiffness = stiffness;
+                nfTxt.setText(String.format("%.3f", (float) stiffness));
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+
+            }
+        });
+        dr.setProgress(80);
+        stiff.setProgress(60);
+
+    }
+}
diff --git a/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringActivity.java b/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringActivity.java
new file mode 100644
index 0000000..e9f2d62
--- /dev/null
+++ b/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringActivity.java
@@ -0,0 +1,154 @@
+/*
+ * 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 com.example.android.support.animation;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.animation.DynamicAnimation;
+import android.support.animation.SpringAnimation;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+/**
+ * This is a single spring animation. It provides a UI to interact with the spring, and two seek
+ * bars to tune the spring constants.
+ */
+public class SpringActivity extends Activity {
+    private float mDampingRatio;
+    private float mStiffness;
+    private SpringView mSpringView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        final View v = findViewById(R.id.container);
+        mSpringView = (SpringView) findViewById(R.id.actual_spring);
+
+        final View img = findViewById(R.id.imageView);
+        setupSeekBars();
+        final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y,
+                0 /* final position */);
+        anim.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() {
+            @Override
+            public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float v, float v1) {
+                // Update the drawing of the spring.
+                mSpringView.setMassHeight(img.getY());
+            }
+        });
+
+        ((View) img.getParent()).setOnTouchListener(new View.OnTouchListener() {
+            public float touchOffset;
+            public VelocityTracker vt;
+            @Override
+            public boolean onTouch(View v, MotionEvent motionEvent) {
+                if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
+                    // check whether the touch happens inside of the img view.
+                    boolean inside = motionEvent.getX() >= img.getX()
+                            && motionEvent.getX() <= img.getX() + img.getWidth()
+                            && motionEvent.getY() >= img.getY()
+                            && motionEvent.getY() <= img.getY() + img.getHeight();
+
+                    anim.cancel();
+
+                    if (!inside) {
+                        return false;
+                    }
+                    // Apply this offset to all the subsequent events
+                    touchOffset = img.getTranslationY() - motionEvent.getY();
+                    vt = VelocityTracker.obtain();
+                    vt.clear();
+                }
+
+                vt.addMovement(motionEvent);
+
+                if (motionEvent.getActionMasked() == MotionEvent.ACTION_MOVE) {
+                    img.setTranslationY(motionEvent.getY() + touchOffset);
+                    // Updates the drawing of the spring.
+                    mSpringView.setMassHeight(img.getY());
+                } else if (motionEvent.getActionMasked() == MotionEvent.ACTION_CANCEL
+                        || motionEvent.getActionMasked() == MotionEvent.ACTION_UP) {
+                    // Compute the velocity in unit: pixel/second
+                    vt.computeCurrentVelocity(1000);
+                    float velocity = vt.getYVelocity();
+                    anim.getSpring().setDampingRatio(mDampingRatio).setStiffness(mStiffness);
+                    anim.setStartVelocity(velocity).start();
+                    vt.recycle();
+                }
+                return true;
+            }
+        });
+    }
+
+    // Setup seek bars so damping ratio and stiffness for the spring can be modified through the UI.
+    void setupSeekBars() {
+        SeekBar dr = (SeekBar) findViewById(R.id.damping_ratio);
+        dr.setMax(130);
+        final TextView drTxt = (TextView) findViewById(R.id.damping_ratio_txt);
+        dr.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+                if (i < 80) {
+                    mDampingRatio = i / 80.0f;
+                } else if (i > 90) {
+                    mDampingRatio = (float) Math.exp((i - 90) / 10.0);
+                } else {
+                    mDampingRatio = 1;
+                }
+                drTxt.setText(String.format("%.4f", (float) mDampingRatio));
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+
+            }
+        });
+
+        SeekBar stiff = (SeekBar) findViewById(R.id.stiffness);
+        stiff.setMax(110);
+        final TextView nfTxt = (TextView) findViewById(R.id.stiffness_txt);
+        stiff.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+                float stiffness = (float) Math.exp(i / 10d);
+                mStiffness = stiffness;
+                nfTxt.setText(String.format("%.3f", (float) stiffness));
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+
+            }
+
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+
+            }
+        });
+        dr.setProgress(40);
+        stiff.setProgress(60);
+    }
+}
diff --git a/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringView.java b/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringView.java
new file mode 100644
index 0000000..14a0fd0
--- /dev/null
+++ b/samples/SupportAnimationDemos/src/com/example/android/support/animation/SpringView.java
@@ -0,0 +1,70 @@
+/*
+ * 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 com.example.android.support.animation;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * The view that draws the spring as it reacts (i.e. expands/compresses) to the user touch.
+ */
+public class SpringView extends View {
+    final Paint mPaint = new Paint();
+    private float mLastHeight = 175;
+
+    public SpringView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setWillNotDraw(false);
+        mPaint.setColor(context.getResources().getColor(R.color.springColor));
+        mPaint.setStrokeWidth(10);
+    }
+
+    /**
+     * Sets the other end of the spring.
+     *
+     * @param height height of the mass, which is used to derive how to draw the spring
+     */
+    public void setMassHeight(float height) {
+        mLastHeight = height;
+        invalidate();
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        // Draws the spring
+        // 30px long, 15 sections
+        int num = 20;
+        float sectionLen = 150; // px
+        final float x = canvas.getWidth() / 2;
+        float y = 0;
+        float sectionHeight = mLastHeight / num;
+        float sectionWidth = (float) Math.sqrt(sectionLen * sectionLen
+                - sectionHeight * sectionHeight);
+        canvas.drawLine(x, 0, x + sectionWidth / 2, sectionHeight / 2, mPaint);
+        float lastX = x + sectionWidth / 2;
+        float lastY = sectionHeight / 2;
+        for (int i = 1; i < num; i++) {
+            canvas.drawLine(lastX, lastY, 2 * x - lastX, lastY + sectionHeight, mPaint);
+            lastX = 2 * x - lastX;
+            lastY = lastY + sectionHeight;
+        }
+        canvas.drawLine(lastX, lastY, x, mLastHeight, mPaint);
+    }
+}
diff --git a/samples/SupportDesignDemos/res/values/styles.xml b/samples/SupportDesignDemos/res/values/styles.xml
index ddbed52f..121ffa6 100644
--- a/samples/SupportDesignDemos/res/values/styles.xml
+++ b/samples/SupportDesignDemos/res/values/styles.xml
@@ -47,6 +47,9 @@
     <style name="Theme.DesignDemos.Navigation" parent="Theme.DesignDemos.Navigation.Base"/>
 
     <style name="Theme.DesignDemos.BottomSheetModal" parent="Theme.Design">
+        <item name="colorPrimary">#607D8B</item>
+        <item name="colorPrimaryDark">#455A64</item>
+        <item name="colorAccent">#FFAB40</item>
         <item name="bottomSheetDialogTheme">@style/Theme.DesignDemos.BottomSheetModal.BottomSheetDialog</item>
     </style>
 
diff --git a/samples/SupportLeanbackDemos/res/values/themes.xml b/samples/SupportLeanbackDemos/res/values/themes.xml
index 58ae373..e2292b5 100644
--- a/samples/SupportLeanbackDemos/res/values/themes.xml
+++ b/samples/SupportLeanbackDemos/res/values/themes.xml
@@ -14,7 +14,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools" >
     <style name="Theme.Example.Leanback" parent="Theme.Leanback">
     </style>
     <style name="Theme.Example.Leanback.Browse" parent="Theme.Leanback.Browse">
@@ -45,8 +45,8 @@
         <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowBackground">@android:color/transparent</item>
         <item name="android:backgroundDimEnabled">true</item>
-        <item name="android:colorPrimary">@color/settings_background</item>
-        <item name="android:colorAccent">?attr/defaultBrandColor</item>
+        <item name="android:colorPrimary" tools:targetApi="21" >@color/settings_background</item>
+        <item name="android:colorAccent" tools:targetApi="21">?attr/defaultBrandColor</item>
     </style>
     <style name="Theme.Example.Leanback.Onboarding" parent="Theme.Leanback.Onboarding">
         <item name="onboardingLogoStyle">@style/Widget.Example.Leanback.OnboardingLogoStyle</item>
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java
index 01bd583..4f8546e 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/DetailsPresenterSelectionActivity.java
@@ -76,7 +76,7 @@
             String title = getString(R.string.guidedstep_second_title);
             String breadcrumb = getString(R.string.guidedstep_second_breadcrumb);
             String description = getString(R.string.guidedstep_second_description);
-            Drawable icon = getActivity().getDrawable(R.drawable.ic_main_icon);
+            Drawable icon = getActivity().getResources().getDrawable(R.drawable.ic_main_icon);
             return new Guidance(title, description, breadcrumb, icon);
         }
 
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java
index 94f7d6c..a311338 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepActivity.java
@@ -403,8 +403,8 @@
 
         @Override
         public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
-            addEditableAction(getContext(), actions, FIRST_NAME, "Pat", "Your first name");
-            addEditableAction(getContext(), actions, LAST_NAME, "Smith", "Your last name");
+            addEditableAction(getActivity(), actions, FIRST_NAME, "Pat", "Your first name");
+            addEditableAction(getActivity(), actions, LAST_NAME, "Smith", "Your last name");
             List<GuidedAction> subActions = new ArrayList<GuidedAction>();
             updatePaymentAction(addAction(actions, PAYMENT, "Select Payment", "", subActions));
             addEditableDescriptionAction(actions, PASSWORD, "Password", "", "",
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java
index bb9aa1ec..0cd6edd 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/GuidedStepSupportActivity.java
@@ -406,8 +406,8 @@
 
         @Override
         public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
-            addEditableAction(getContext(), actions, FIRST_NAME, "Pat", "Your first name");
-            addEditableAction(getContext(), actions, LAST_NAME, "Smith", "Your last name");
+            addEditableAction(getActivity(), actions, FIRST_NAME, "Pat", "Your first name");
+            addEditableAction(getActivity(), actions, LAST_NAME, "Smith", "Your last name");
             List<GuidedAction> subActions = new ArrayList<GuidedAction>();
             updatePaymentAction(addAction(actions, PAYMENT, "Select Payment", "", subActions));
             addEditableDescriptionAction(actions, PASSWORD, "Password", "", "",
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
index 9b48371..9b801dc 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsFragment.java
@@ -16,6 +16,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.v17.leanback.app.DetailsFragmentBackgroundController;
@@ -76,8 +77,8 @@
             new DetailsFragmentBackgroundController(this);
 
     private void initializeTest() {
-        TEST_SHARED_ELEMENT_TRANSITION = null != getActivity().getWindow()
-                .getSharedElementEnterTransition();
+        TEST_SHARED_ELEMENT_TRANSITION = Build.VERSION.SDK_INT >= 21
+                && null != getActivity().getWindow().getSharedElementEnterTransition();
         TEST_OVERVIEW_ROW_ON_SECOND = !TEST_SHARED_ELEMENT_TRANSITION;
         TEST_ENTRANCE_TRANSITION = false;
     }
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
index ef41be0..77ce368 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/NewDetailsSupportFragment.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.v17.leanback.app.DetailsSupportFragmentBackgroundController;
@@ -79,8 +80,8 @@
             new DetailsSupportFragmentBackgroundController(this);
 
     private void initializeTest() {
-        TEST_SHARED_ELEMENT_TRANSITION = null != getActivity().getWindow()
-                .getSharedElementEnterTransition();
+        TEST_SHARED_ELEMENT_TRANSITION = Build.VERSION.SDK_INT >= 21
+                && null != getActivity().getWindow().getSharedElementEnterTransition();
         TEST_OVERVIEW_ROW_ON_SECOND = !TEST_SHARED_ELEMENT_TRANSITION;
         TEST_ENTRANCE_TRANSITION = false;
     }
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
index a29a995..c72519d 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackFragment.java
@@ -17,16 +17,15 @@
 package com.example.android.leanback;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.support.v17.leanback.app.PlaybackFragmentGlueHost;
 import android.support.v17.leanback.widget.Action;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
 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.PlaybackControlsRow;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
 import android.util.Log;
 
@@ -56,7 +55,6 @@
     private static final int ROW_CONTROLS = 0;
 
     private PlaybackControlGlue mGlue;
-    private ListRowPresenter mListRowPresenter;
 
     public SparseArrayObjectAdapter getAdapter() {
         return (SparseArrayObjectAdapter) super.getAdapter();
@@ -86,7 +84,9 @@
             @Override
             public void onActionClicked(Action action) {
                 if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    getActivity().enterPictureInPictureMode();
+                    if (Build.VERSION.SDK_INT >= 24) {
+                        getActivity().enterPictureInPictureMode();
+                    }
                     return;
                 }
                 super.onActionClicked(action);
@@ -100,22 +100,10 @@
         };
 
         mGlue.setHost(new PlaybackFragmentGlueHost(this));
-        mListRowPresenter = new ListRowPresenter();
+        ClassPresenterSelector classPresenterSelector = new ClassPresenterSelector();
+        classPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter());
 
-        setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
-            @Override
-            public Presenter getPresenter(Object object) {
-                if (object instanceof PlaybackControlsRow) {
-                    return mGlue.getControlsRowPresenter();
-                } else if (object instanceof ListRow) {
-                    return mListRowPresenter;
-                }
-                throw new IllegalArgumentException("Unhandled object: " + object);
-            }
-        }));
-
-        // Add the controls row
-        getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+        setAdapter(new SparseArrayObjectAdapter(classPresenterSelector));
 
         // Add related content rows
         for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
index bca057f..248e4ab 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlayFragment.java
@@ -14,10 +14,12 @@
 package com.example.android.leanback;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.v17.leanback.widget.Action;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
 import android.support.v17.leanback.widget.HeaderItem;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.ListRowPresenter;
@@ -26,7 +28,6 @@
 import android.support.v17.leanback.widget.PlaybackControlsRow;
 import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
 import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.Row;
 import android.support.v17.leanback.widget.RowPresenter;
 import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
@@ -55,8 +56,6 @@
     private static final int ROW_CONTROLS = 0;
 
     private PlaybackControlHelper mGlue;
-    private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
-    private ListRowPresenter mListRowPresenter;
     final Handler mHandler = new Handler();
 
     // Artificial delay to simulate a media being prepared. The onRowChanged callback should be
@@ -123,7 +122,9 @@
             @Override
             public void onActionClicked(Action action) {
                 if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    getActivity().enterPictureInPictureMode();
+                    if (Build.VERSION.SDK_INT >= 24) {
+                        getActivity().enterPictureInPictureMode();
+                    }
                     return;
                 }
                 super.onActionClicked(action);
@@ -139,21 +140,14 @@
         }, MEDIA_PREPARATION_DELAY);
         mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
 
-        mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
-        mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
-        mListRowPresenter = new ListRowPresenter();
+        PlaybackControlsRowPresenter playbackControlsRowPresenter =
+                mGlue.createControlsRowAndPresenter();
+        playbackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
+        ClassPresenterSelector selector = new ClassPresenterSelector();
+        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
+        selector.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter);
 
-        setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
-            @Override
-            public Presenter getPresenter(Object object) {
-                if (object instanceof PlaybackControlsRow) {
-                    return mPlaybackControlsRowPresenter;
-                } else if (object instanceof ListRow) {
-                    return mListRowPresenter;
-                }
-                throw new IllegalArgumentException("Unhandled object: " + object);
-            }
-        }));
+        setAdapter(new SparseArrayObjectAdapter(selector));
 
         // Add the controls row
         getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
index b806a9a..205037e 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackOverlaySupportFragment.java
@@ -17,10 +17,12 @@
 package com.example.android.leanback;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.support.v17.leanback.widget.Action;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
 import android.support.v17.leanback.widget.HeaderItem;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.ListRowPresenter;
@@ -29,7 +31,6 @@
 import android.support.v17.leanback.widget.PlaybackControlsRow;
 import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
 import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.Row;
 import android.support.v17.leanback.widget.RowPresenter;
 import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
@@ -58,8 +59,6 @@
     private static final int ROW_CONTROLS = 0;
 
     private PlaybackControlSupportHelper mGlue;
-    private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
-    private ListRowPresenter mListRowPresenter;
     final Handler mHandler = new Handler();
 
     // Artificial delay to simulate a media being prepared. The onRowChanged callback should be
@@ -126,7 +125,9 @@
             @Override
             public void onActionClicked(Action action) {
                 if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    getActivity().enterPictureInPictureMode();
+                    if (Build.VERSION.SDK_INT >= 24) {
+                        getActivity().enterPictureInPictureMode();
+                    }
                     return;
                 }
                 super.onActionClicked(action);
@@ -142,21 +143,14 @@
         }, MEDIA_PREPARATION_DELAY);
         mGlue.setOnItemViewClickedListener(mOnItemViewClickedListener);
 
-        mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
-        mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
-        mListRowPresenter = new ListRowPresenter();
+        PlaybackControlsRowPresenter playbackControlsRowPresenter =
+                mGlue.createControlsRowAndPresenter();
+        playbackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
+        ClassPresenterSelector selector = new ClassPresenterSelector();
+        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
+        selector.addClassPresenter(PlaybackControlsRow.class, playbackControlsRowPresenter);
 
-        setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
-            @Override
-            public Presenter getPresenter(Object object) {
-                if (object instanceof PlaybackControlsRow) {
-                    return mPlaybackControlsRowPresenter;
-                } else if (object instanceof ListRow) {
-                    return mListRowPresenter;
-                }
-                throw new IllegalArgumentException("Unhandled object: " + object);
-            }
-        }));
+        setAdapter(new SparseArrayObjectAdapter(selector));
 
         // Add the controls row
         getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
diff --git a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
index 6d2fa51..8a5da83 100644
--- a/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
+++ b/samples/SupportLeanbackDemos/src/com/example/android/leanback/PlaybackSupportFragment.java
@@ -20,16 +20,15 @@
 package com.example.android.leanback;
 
 import android.content.Context;
+import android.os.Build;
 import android.os.Bundle;
 import android.support.v17.leanback.app.PlaybackSupportFragmentGlueHost;
 import android.support.v17.leanback.widget.Action;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
 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.PlaybackControlsRow;
-import android.support.v17.leanback.widget.Presenter;
-import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
 import android.util.Log;
 
@@ -59,7 +58,6 @@
     private static final int ROW_CONTROLS = 0;
 
     private PlaybackControlGlue mGlue;
-    private ListRowPresenter mListRowPresenter;
 
     public SparseArrayObjectAdapter getAdapter() {
         return (SparseArrayObjectAdapter) super.getAdapter();
@@ -89,7 +87,9 @@
             @Override
             public void onActionClicked(Action action) {
                 if (action.getId() == R.id.lb_control_picture_in_picture) {
-                    getActivity().enterPictureInPictureMode();
+                    if (Build.VERSION.SDK_INT >= 24) {
+                        getActivity().enterPictureInPictureMode();
+                    }
                     return;
                 }
                 super.onActionClicked(action);
@@ -103,22 +103,10 @@
         };
 
         mGlue.setHost(new PlaybackSupportFragmentGlueHost(this));
-        mListRowPresenter = new ListRowPresenter();
+        ClassPresenterSelector classPresenterSelector = new ClassPresenterSelector();
+        classPresenterSelector.addClassPresenter(ListRow.class, new ListRowPresenter());
 
-        setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
-            @Override
-            public Presenter getPresenter(Object object) {
-                if (object instanceof PlaybackControlsRow) {
-                    return mGlue.getControlsRowPresenter();
-                } else if (object instanceof ListRow) {
-                    return mListRowPresenter;
-                }
-                throw new IllegalArgumentException("Unhandled object: " + object);
-            }
-        }));
-
-        // Add the controls row
-        getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+        setAdapter(new SparseArrayObjectAdapter(classPresenterSelector));
 
         // Add related content rows
         for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
diff --git a/samples/SupportVectorDrawable/animated/AndroidManifest.xml b/samples/SupportVectorDrawable/animated/AndroidManifest.xml
deleted file mode 100644
index 55d6bc6..0000000
--- a/samples/SupportVectorDrawable/animated/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="com.example.android.support.vectordrawable" >
-
-    <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
-
-    <application android:icon="@drawable/app_sample_code" android:label="AnimatedVectorDrawableCompatTest" >
-        <activity android:name="com.example.android.support.vectordrawable.app.AnimatedButtonBackground" />
-        <intent-filter>
-            <action android:name="android.intent.action.MAIN" />
-
-            <category android:name="android.intent.category.LAUNCHER" />
-        </intent-filter>
-    </application>
-
-</manifest>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawable/animated/res/drawable/app_sample_code.png b/samples/SupportVectorDrawable/animated/res/drawable/app_sample_code.png
deleted file mode 100755
index 66a1984..0000000
--- a/samples/SupportVectorDrawable/animated/res/drawable/app_sample_code.png
+++ /dev/null
Binary files differ
diff --git a/samples/SupportVectorDrawable/animated/res/values/strings.xml b/samples/SupportVectorDrawable/animated/res/values/strings.xml
deleted file mode 100644
index c5451c88..0000000
--- a/samples/SupportVectorDrawable/animated/res/values/strings.xml
+++ /dev/null
@@ -1,28 +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.
--->
-
-<resources>
-
-    <string name="twoLinePathData">"M 0,0 v 100 M 0,0 h 100"</string>
-    <string name="triangle"> "M300,70 l 0,-70 70,70 0,0   -70,70z"</string>
-    <string name="rectangle">"M300,70 l 0,-70 70,0  0,140 -70,0 z"</string>
-    <string name="rectangle2">"M300,70 l 0,-70 70,0  0,70z M300,70  l 70,0 0,70 -70,0z"</string>
-    <string name="equal2">    "M300,35 l 0,-35 70,0  0,35z M300,105 l 70,0 0,35 -70,0z"</string>
-    <string name="round_box">"m2.10001,-6c-1.9551,0 -0.5,0.02499 -2.10001,0.02499c-1.575,0 0.0031,-0.02499 -1.95,-0.02499c-2.543,0 -4,2.2816 -4,4.85001c0,3.52929 0.25,6.25 5.95,6.25c5.7,0 6,-2.72071 6,-6.25c0,-2.56841 -1.35699,-4.85001 -3.89999,-4.85001"</string>
-    <string name="heart">    "m4.5,-7c-1.95509,0 -3.83009,1.26759 -4.5,3c-0.66991,-1.73241 -2.54691,-3 -4.5,-3c-2.543,0 -4.5,1.93159 -4.5,4.5c0,3.5293 3.793,6.2578 9,11.5c5.207,-5.2422 9,-7.9707 9,-11.5c0,-2.56841 -1.957,-4.5 -4.5,-4.5"</string>
-    <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
-</resources>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawable/animated/rundemo.sh b/samples/SupportVectorDrawable/animated/rundemo.sh
deleted file mode 100755
index e5972f7..0000000
--- a/samples/SupportVectorDrawable/animated/rundemo.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-. $ANDROID_BUILD_TOP/build/envsetup.sh && \
-mmm -j20 . && \
-adb install -r $OUT/data/app/SupportAnimatedVectorDrawable/SupportAnimatedVectorDrawable.apk && \
-adb shell am start -n com.example.android.support.vectordrawable/com.example.android.support.vectordrawable.app.AnimatedButtonBackground
-
-
diff --git a/samples/SupportVectorDrawable/static/Android.mk b/samples/SupportVectorDrawable/static/Android.mk
deleted file mode 100644
index bdc102a..0000000
--- a/samples/SupportVectorDrawable/static/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_USE_AAPT2 := true
-
-LOCAL_MODULE_TAGS := samples tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := SupportVectorDrawable
-
-LOCAL_STATIC_ANDROID_LIBRARIES := android-support-vectordrawable android-support-v4
-
-LOCAL_SDK_VERSION := current
-
-LOCAL_MIN_SDK_VERSION := 7
-
-LOCAL_AAPT_FLAGS += --no-version-vectors
-
-include $(BUILD_PACKAGE)
-
-LOCAL_PROGUARD_FLAG_FILES := proguard.flags
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/SupportVectorDrawable/static/AndroidManifest.xml b/samples/SupportVectorDrawable/static/AndroidManifest.xml
deleted file mode 100644
index 53fc9c2..0000000
--- a/samples/SupportVectorDrawable/static/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +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="com.example.android.support.vectordrawable" >
-
-    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="23"/>
-
-    <application android:icon="@drawable/app_sample_code" android:label="VectorDrawableCompatTest" >
-        <activity android:name=".app.SimpleButtonBackground" />
-
-        <intent-filter>
-            <action android:name="android.intent.action.MAIN" />
-
-            <category android:name="android.intent.category.LAUNCHER" />
-        </intent-filter>
-    </application>
-
-</manifest>
diff --git a/samples/SupportVectorDrawable/static/rundemo.sh b/samples/SupportVectorDrawable/static/rundemo.sh
deleted file mode 100755
index 2695b53..0000000
--- a/samples/SupportVectorDrawable/static/rundemo.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-. $ANDROID_BUILD_TOP/build/envsetup.sh && \
-mmm -j20 . && \
-adb install -r $OUT/data/app/SupportVectorDrawable/SupportVectorDrawable.apk && \
-adb shell am start -n com.example.android.support.vectordrawable/com.example.android.support.vectordrawable.app.SimpleButtonBackground
-
-
diff --git a/samples/SupportVectorDrawable/animated/Android.mk b/samples/SupportVectorDrawableDemos/Android.mk
similarity index 88%
rename from samples/SupportVectorDrawable/animated/Android.mk
rename to samples/SupportVectorDrawableDemos/Android.mk
index ae01691..376f841 100644
--- a/samples/SupportVectorDrawable/animated/Android.mk
+++ b/samples/SupportVectorDrawableDemos/Android.mk
@@ -18,17 +18,18 @@
 
 LOCAL_USE_AAPT2 := true
 
-LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_TAGS := samples tests
 
 LOCAL_SDK_VERSION := current
 
-LOCAL_MIN_SDK_VERSION := 11
+LOCAL_MIN_SDK_VERSION := 14
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := SupportAnimatedVectorDrawable
+LOCAL_PACKAGE_NAME := SupportVectorDrawableDemos
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
+        android-support-v7-appcompat \
         android-support-animatedvectordrawable \
         android-support-vectordrawable \
         android-support-v4
diff --git a/samples/SupportVectorDrawableDemos/AndroidManifest.xml b/samples/SupportVectorDrawableDemos/AndroidManifest.xml
new file mode 100644
index 0000000..1de3a5f
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/AndroidManifest.xml
@@ -0,0 +1,57 @@
+<?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="com.example.android.support.vectordrawable" >
+
+    <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23"/>
+
+    <application android:icon="@drawable/app_sample_code" android:label="SupportVectorDrawableDemos" >
+        <activity android:name="com.example.android.support.vectordrawable.app.SupportVectorDrawableDemos">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="com.example.android.support.vectordrawable.app.SimpleAnimatedVectorDrawable"
+                  android:label="SimpleAnimatedVectorDrawable">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="com.example.android.support.vectordrawable.app.SimpleStaticVectorDrawable"
+                  android:label="SimpleVectorDrawable">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name="com.example.android.support.vectordrawable.app.AVDCListenerDemo"
+                  android:label="AnimatedVectorDrawableCompatListener"
+                  android:theme="@style/Theme.AppCompat.Light">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawableDemos/build.gradle b/samples/SupportVectorDrawableDemos/build.gradle
new file mode 100644
index 0000000..8557c6b
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/build.gradle
@@ -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.
+ */
+
+apply plugin: 'com.android.application'
+
+dependencies {
+    compile project(':support-vector-drawable')
+    compile project(':support-animated-vector-drawable')
+    compile project(':support-appcompat-v7')
+}
+
+android {
+    compileSdkVersion project.ext.currentSdk
+
+    defaultConfig {
+        minSdkVersion 14
+        vectorDrawables.useSupportLibrary = true
+    }
+
+    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/SupportVectorDrawable/animated/res/anim/alpha_animation_progress_bar.xml b/samples/SupportVectorDrawableDemos/res/anim/alpha_animation_progress_bar.xml
similarity index 100%
rename from samples/SupportVectorDrawable/animated/res/anim/alpha_animation_progress_bar.xml
rename to samples/SupportVectorDrawableDemos/res/anim/alpha_animation_progress_bar.xml
diff --git a/samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_control_points_interpolator.xml b/samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_control_points_interpolator.xml
new file mode 100644
index 0000000..c4f0389
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_control_points_interpolator.xml
@@ -0,0 +1,23 @@
+<?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.
+  -->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+                android:duration="3300"
+                android:interpolator="@interpolator/control_points_interpolator"
+                android:propertyName="rotation"
+                android:valueFrom="0"
+                android:valueTo="450"/>
diff --git a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml b/samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_path_interpolator.xml
similarity index 75%
rename from samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
rename to samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_path_interpolator.xml
index 36c297f..699d370 100644
--- a/samples/SupportVectorDrawable/animated/res/anim/animation_grouping_1_01.xml
+++ b/samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_path_interpolator.xml
@@ -16,7 +16,8 @@
 -->
 
 <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:duration="3300"
-    android:propertyName="rotation"
-    android:valueFrom="0"
-    android:valueTo="450" />
+                android:duration="3300"
+                android:interpolator="@interpolator/path_interpolator"
+                android:propertyName="rotation"
+                android:valueFrom="0"
+                android:valueTo="450"/>
diff --git a/samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_single_control_point_interpolator.xml b/samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_single_control_point_interpolator.xml
new file mode 100644
index 0000000..a0a67e6
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/animation_grouping_1_single_control_point_interpolator.xml
@@ -0,0 +1,23 @@
+<?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.
+  -->
+
+<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
+                android:duration="3300"
+                android:interpolator="@interpolator/single_control_point_interpolator"
+                android:propertyName="rotation"
+                android:valueFrom="0"
+                android:valueTo="450"/>
diff --git a/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_fill_outlines.xml b/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_fill_outlines.xml
new file mode 100644
index 0000000..d647da7
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_fill_outlines.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="333"
+        android:propertyName="rotation"
+        android:valueFrom="0"
+        android:valueTo="180"
+        android:interpolator="@android:interpolator/accelerate_decelerate" />
+</set>
diff --git a/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_hourglass_frame.xml b/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_hourglass_frame.xml
new file mode 100644
index 0000000..d647da7
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_hourglass_frame.xml
@@ -0,0 +1,23 @@
+<!--
+  ~ 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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <objectAnimator
+        android:duration="333"
+        android:propertyName="rotation"
+        android:valueFrom="0"
+        android:valueTo="180"
+        android:interpolator="@android:interpolator/accelerate_decelerate" />
+</set>
diff --git a/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_mask_1.xml b/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_mask_1.xml
new file mode 100644
index 0000000..0ea8939
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/ic_hourglass_animation_mask_1.xml
@@ -0,0 +1,34 @@
+<!--
+  ~ 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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="333"
+            android:propertyName="pathData"
+            android:valueFrom="M 24 13.3999938965 c 0 0.0 -24 0.0 -24 0.0 c 0 0.0 0 10.6000061035 0 10.6000061035 c 0 0 24 0 24 0 c 0 0 0 -10.6000061035 0 -10.6000061035 Z"
+            android:valueTo="M 24 13.3999938965 c 0 0.0 -24 0.0 -24 0.0 c 0 0.0 0 10.6000061035 0 10.6000061035 c 0 0 24 0 24 0 c 0 0 0 -10.6000061035 0 -10.6000061035 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/accelerate_decelerate" />
+        <objectAnimator
+            android:duration="1000"
+            android:propertyName="pathData"
+            android:valueFrom="M 24 13.3999938965 c 0 0.0 -24 0.0 -24 0.0 c 0 0.0 0 10.6000061035 0 10.6000061035 c 0 0 24 0 24 0 c 0 0 0 -10.6000061035 0 -10.6000061035 Z"
+            android:valueTo="M 24 0.00173950195312 c 0 0.0 -24 0.0 -24 0.0 c 0 0.0 0 10.6982574463 0 10.6982574463 c 0 0.0 24 0.0 24 0.0 c 0 0.0 0 -10.6982574463 0 -10.6982574463 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/accelerate_decelerate" />
+    </set>
+</set>
diff --git a/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_cross_1.xml b/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_cross_1.xml
new file mode 100644
index 0000000..993493b
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_cross_1.xml
@@ -0,0 +1,31 @@
+<!-- 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.
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="0"
+            android:valueTo="0"
+            android:interpolator="@android:interpolator/linear" />
+        <objectAnimator
+            android:duration="17"
+            android:propertyName="alpha"
+            android:valueFrom="0"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/linear" />
+    </set>
+</set>
diff --git a/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_ic_signal_airplane.xml b/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_ic_signal_airplane.xml
new file mode 100644
index 0000000..a9db7cc
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_ic_signal_airplane.xml
@@ -0,0 +1,32 @@
+<!--
+  ~ 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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="1"
+            android:interpolator="@android:interpolator/accelerate_decelerate" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="alpha"
+            android:valueFrom="1"
+            android:valueTo="0.5"
+            android:interpolator="@android:interpolator/accelerate_decelerate" />
+    </set>
+</set>
diff --git a/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_mask_2.xml b/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_mask_2.xml
new file mode 100644
index 0000000..e809b47
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_mask_2.xml
@@ -0,0 +1,34 @@
+<!--
+  ~ 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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 31.5523681641 -35.8077850342 31.5523681641 c 0.0 0.0 9.55097961426 9.55285644531 9.55097961426 9.55285644531 c 0.0 0.0 -2.61698913574 2.09387207031 -2.61698913574 2.09387207031 c 0.0 0.0 -9.75096130371 -9.56428527832 -9.75096130371 -9.56428527832 c 0.0 0.0 -34.6200408936 25.4699249268 -34.6200408936 25.4699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z"
+            android:valueTo="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 31.5523681641 -35.8077850342 31.5523681641 c 0.0 0.0 9.55097961426 9.55285644531 9.55097961426 9.55285644531 c 0.0 0.0 -2.61698913574 2.09387207031 -2.61698913574 2.09387207031 c 0.0 0.0 -9.75096130371 -9.56428527832 -9.75096130371 -9.56428527832 c 0.0 0.0 -34.6200408936 25.4699249268 -34.6200408936 25.4699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/accelerate_decelerate" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 31.5523681641 -35.8077850342 31.5523681641 c 0.0 0.0 9.55097961426 9.55285644531 9.55097961426 9.55285644531 c 0.0 0.0 -2.61698913574 2.09387207031 -2.61698913574 2.09387207031 c 0.0 0.0 -9.75096130371 -9.56428527832 -9.75096130371 -9.56428527832 c 0.0 0.0 -34.6200408936 25.4699249268 -34.6200408936 25.4699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z"
+            android:valueTo="M 37.8337860107 -40.3974914551 c 0.0 0.0 -35.8077850342 31.5523681641 -35.8077850342 31.5523681641 c 0.0 0.0 40.9884796143 40.9278411865 40.9884796143 40.9278411865 c 0.0 0.0 -2.61700439453 2.0938873291 -2.61700439453 2.0938873291 c 0.0 0.0 -41.1884460449 -40.9392852783 -41.1884460449 -40.9392852783 c 0.0 0.0 -34.6200408936 25.4699249268 -34.6200408936 25.4699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z"
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/accelerate_decelerate" />
+    </set>
+</set>
diff --git a/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_path_1_1.xml b/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_path_1_1.xml
new file mode 100644
index 0000000..30db79d
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/anim/ic_signal_airplane_v2_animation_path_1_1.xml
@@ -0,0 +1,34 @@
+<!--
+  ~ 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.
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android" >
+    <set
+        android:ordering="sequentially" >
+        <objectAnimator
+            android:duration="200"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617 3.9430847168 c 0.0 0.0 0.324981689453 0.399978637695 0.324981689453 0.399978637695 "
+            android:valueTo="M 7.54049682617 3.9430847168 c 0.0 0.0 0.324981689453 0.399978637695 0.324981689453 0.399978637695 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/accelerate_decelerate" />
+        <objectAnimator
+            android:duration="350"
+            android:propertyName="pathData"
+            android:valueFrom="M 7.54049682617 3.9430847168 c 0.0 0.0 0.324981689453 0.399978637695 0.324981689453 0.399978637695 "
+            android:valueTo="M 7.54049682617 3.9430847168 c 0.0 0.0 31.5749816895 31.4499664307 31.5749816895 31.4499664307 "
+            android:valueType="pathType"
+            android:interpolator="@android:interpolator/accelerate_decelerate" />
+    </set>
+</set>
diff --git a/samples/SupportVectorDrawable/animated/res/anim/trim_path_animation_progress_bar.xml b/samples/SupportVectorDrawableDemos/res/anim/trim_path_animation_progress_bar.xml
similarity index 100%
rename from samples/SupportVectorDrawable/animated/res/anim/trim_path_animation_progress_bar.xml
rename to samples/SupportVectorDrawableDemos/res/anim/trim_path_animation_progress_bar.xml
diff --git a/samples/SupportVectorDrawable/animated/res/drawable/animation_vector_drawable_grouping_1.xml b/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_1.xml
similarity index 84%
rename from samples/SupportVectorDrawable/animated/res/drawable/animation_vector_drawable_grouping_1.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_1.xml
index dac981b..6c09a5d 100644
--- a/samples/SupportVectorDrawable/animated/res/drawable/animation_vector_drawable_grouping_1.xml
+++ b/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_1.xml
@@ -18,9 +18,9 @@
 
     <target
         android:name="sun"
-        android:animation="@anim/animation_grouping_1_01" />
+        android:animation="@anim/animation_grouping_1_path_interpolator" />
     <target
         android:name="earth"
-        android:animation="@anim/animation_grouping_1_01" />
+        android:animation="@anim/animation_grouping_1_path_interpolator" />
 
 </animated-vector>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_accelerate.xml b/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_accelerate.xml
new file mode 100644
index 0000000..5b35e44
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_accelerate.xml
@@ -0,0 +1,27 @@
+<!--
+  ~ 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.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/vector_drawable_grouping_1" >
+
+    <target
+        android:name="sun"
+        android:animation="@anim/animation_grouping_1_single_control_point_interpolator" />
+    <target
+        android:name="earth"
+        android:animation="@anim/animation_grouping_1_single_control_point_interpolator" />
+
+</animated-vector>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_decelerate.xml b/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_decelerate.xml
new file mode 100644
index 0000000..e7fa1a7
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_drawable_grouping_decelerate.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ 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.
+  -->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/vector_drawable_grouping_1" >
+
+    <target
+        android:name="sun"
+        android:animation="@anim/animation_grouping_1_control_points_interpolator" />
+    <target
+        android:name="earth"
+        android:animation="@anim/animation_grouping_1_control_points_interpolator" />
+
+</animated-vector>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawable/animated/res/drawable/animation_vector_progress_bar.xml b/samples/SupportVectorDrawableDemos/res/drawable/animation_vector_progress_bar.xml
similarity index 100%
rename from samples/SupportVectorDrawable/animated/res/drawable/animation_vector_progress_bar.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/animation_vector_progress_bar.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/app_sample_code.png b/samples/SupportVectorDrawableDemos/res/drawable/app_sample_code.png
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/app_sample_code.png
rename to samples/SupportVectorDrawableDemos/res/drawable/app_sample_code.png
Binary files differ
diff --git a/samples/SupportVectorDrawable/animated/res/drawable/btn_radio_on_to_off_bundle.xml b/samples/SupportVectorDrawableDemos/res/drawable/btn_radio_on_to_off_bundle.xml
similarity index 100%
rename from samples/SupportVectorDrawable/animated/res/drawable/btn_radio_on_to_off_bundle.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/btn_radio_on_to_off_bundle.xml
diff --git a/samples/SupportVectorDrawableDemos/res/drawable/ic_hourglass.xml b/samples/SupportVectorDrawableDemos/res/drawable/ic_hourglass.xml
new file mode 100644
index 0000000..5b40922
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/drawable/ic_hourglass.xml
@@ -0,0 +1,74 @@
+<!-- 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="24dp"
+    android:width="24dp"
+    android:viewportHeight="24"
+    android:viewportWidth="24" >
+    <group
+        android:name="hourglass_frame"
+        android:translateX="12"
+        android:translateY="12"
+        android:scaleX="0.75"
+        android:scaleY="0.75" >
+        <group
+            android:name="hourglass_frame_pivot"
+            android:translateX="-12"
+            android:translateY="-12" >
+            <group
+                android:name="group_2_2"
+                android:translateX="12"
+                android:translateY="6.5" >
+                <path
+                    android:name="path_2_2"
+                    android:pathData="M 6.52099609375 -3.89300537109 c 0.0 0.0 -6.52099609375 6.87901306152 -6.52099609375 6.87901306152 c 0 0.0 -6.52099609375 -6.87901306152 -6.52099609375 -6.87901306152 c 0.0 0.0 13.0419921875 0.0 13.0419921875 0.0 Z M 9.99800109863 -6.5 c 0.0 0.0 -19.9960021973 0.0 -19.9960021973 0.0 c -0.890991210938 0.0 -1.33700561523 1.07699584961 -0.707000732422 1.70700073242 c 0.0 0.0 10.7050018311 11.2929992676 10.7050018311 11.2929992676 c 0 0.0 10.7050018311 -11.2929992676 10.7050018311 -11.2929992676 c 0.630004882812 -0.630004882812 0.183990478516 -1.70700073242 -0.707000732422 -1.70700073242 Z"
+                    android:fillColor="#FF777777" />
+            </group>
+            <group
+                android:name="group_1_2"
+                android:translateX="12"
+                android:translateY="17.5" >
+                <path
+                    android:name="path_2_1"
+                    android:pathData="M 0 -2.98600769043 c 0 0.0 6.52099609375 6.87901306152 6.52099609375 6.87901306152 c 0.0 0.0 -13.0419921875 0.0 -13.0419921875 0.0 c 0.0 0.0 6.52099609375 -6.87901306152 6.52099609375 -6.87901306152 Z M 0 -6.5 c 0 0.0 -10.7050018311 11.2929992676 -10.7050018311 11.2929992676 c -0.630004882812 0.630004882812 -0.184005737305 1.70700073242 0.707000732422 1.70700073242 c 0.0 0.0 19.9960021973 0.0 19.9960021973 0.0 c 0.890991210938 0.0 1.33699035645 -1.07699584961 0.707000732422 -1.70700073242 c 0.0 0.0 -10.7050018311 -11.2929992676 -10.7050018311 -11.2929992676 Z"
+                    android:fillColor="#FF777777" />
+            </group>
+        </group>
+    </group>
+    <group
+        android:name="fill_outlines"
+        android:translateX="12"
+        android:translateY="12"
+        android:scaleX="0.75"
+        android:scaleY="0.75" >
+        <group
+            android:name="fill_outlines_pivot"
+            android:translateX="-12"
+            android:translateY="-12" >
+            <clip-path
+                android:name="mask_1"
+                android:pathData="M 24 13.3999938965 c 0 0.0 -24 0.0 -24 0.0 c 0 0.0 0 10.6000061035 0 10.6000061035 c 0 0 24 0 24 0 c 0 0 0 -10.6000061035 0 -10.6000061035 Z" />
+            <group
+                android:name="group_1_3"
+                android:translateX="12"
+                android:translateY="12" >
+                <path
+                    android:name="path_1_6"
+                    android:pathData="M 10.7100067139 10.2900085449 c 0.629989624023 0.629989624023 0.179992675781 1.70999145508 -0.710006713867 1.70999145508 c 0 0 -20 0 -20 0 c -0.889999389648 0 -1.33999633789 -1.08000183105 -0.710006713867 -1.70999145508 c 0.0 0.0 9.76000976562 -10.2900085449 9.76000976563 -10.2900085449 c 0.0 0 -9.76000976562 -10.2899932861 -9.76000976563 -10.2899932861 c -0.629989624023 -0.630004882812 -0.179992675781 -1.71000671387 0.710006713867 -1.71000671387 c 0 0 20 0 20 0 c 0.889999389648 0 1.33999633789 1.08000183105 0.710006713867 1.71000671387 c 0.0 0.0 -9.76000976562 10.2899932861 -9.76000976563 10.2899932861 c 0.0 0 9.76000976562 10.2900085449 9.76000976563 10.2900085449 Z"
+                    android:fillColor="#FF777777" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/samples/SupportVectorDrawable/animated/res/drawable/animation_vector_drawable_grouping_1.xml b/samples/SupportVectorDrawableDemos/res/drawable/ic_hourglass_animation.xml
similarity index 60%
copy from samples/SupportVectorDrawable/animated/res/drawable/animation_vector_drawable_grouping_1.xml
copy to samples/SupportVectorDrawableDemos/res/drawable/ic_hourglass_animation.xml
index dac981b..3d87376 100644
--- a/samples/SupportVectorDrawable/animated/res/drawable/animation_vector_drawable_grouping_1.xml
+++ b/samples/SupportVectorDrawableDemos/res/drawable/ic_hourglass_animation.xml
@@ -1,5 +1,4 @@
-<!--
- Copyright (C) 2015 The Android Open Source Project
+<!-- 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.
@@ -14,13 +13,14 @@
      limitations under the License.
 -->
 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:drawable="@drawable/vector_drawable_grouping_1" >
-
+    android:drawable="@drawable/ic_hourglass" >
     <target
-        android:name="sun"
-        android:animation="@anim/animation_grouping_1_01" />
+        android:name="hourglass_frame"
+        android:animation="@anim/ic_hourglass_animation_hourglass_frame" />
     <target
-        android:name="earth"
-        android:animation="@anim/animation_grouping_1_01" />
-
-</animated-vector>
\ No newline at end of file
+        android:name="fill_outlines"
+        android:animation="@anim/ic_hourglass_animation_fill_outlines" />
+    <target
+        android:name="mask_1"
+        android:animation="@anim/ic_hourglass_animation_mask_1" />
+</animated-vector>
diff --git a/samples/SupportVectorDrawableDemos/res/drawable/ic_signal_airplane_v2.xml b/samples/SupportVectorDrawableDemos/res/drawable/ic_signal_airplane_v2.xml
new file mode 100644
index 0000000..8b2a1a8
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/drawable/ic_signal_airplane_v2.xml
@@ -0,0 +1,52 @@
+<!-- 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="48dp"
+    android:width="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48" >
+    <group
+        android:name="ic_signal_airplane"
+        android:translateX="21.9995"
+        android:translateY="25.73401" >
+        <group
+            android:name="ic_signal_airplane_pivot"
+            android:translateX="-23.21545"
+            android:translateY="-18.86649" >
+            <clip-path
+                android:name="mask_2"
+                android:pathData="M 37.8337860107 -40.4599914551 c 0.0 0.0 -35.8077850342 31.5523681641 -35.8077850342 31.5523681641 c 0.0 0.0 9.55097961426 9.55285644531 9.55097961426 9.55285644531 c 0.0 0.0 -2.61698913574 2.09387207031 -2.61698913574 2.09387207031 c 0.0 0.0 -9.75096130371 -9.56428527832 -9.75096130371 -9.56428527832 c 0.0 0.0 -34.6200408936 25.4699249268 -34.6200408936 25.4699249268 c 0.0 0.0 55.9664764404 69.742401123 55.9664764404 69.742401123 c 0.0 0.0 73.2448120117 -59.1047973633 73.2448120117 -59.1047973633 c 0.0 0.0 -55.9664916992 -69.7423400879 -55.9664916992 -69.7423400879 Z" />
+            <group
+                android:name="cross_1"
+                android:alpha="0" >
+                <path
+                    android:name="path_1_1"
+                    android:pathData="M 7.54049682617 3.9430847168 c 0.0 0.0 0.324981689453 0.399978637695 0.324981689453 0.399978637695 "
+                    android:strokeColor="#FF777777"
+                    android:strokeWidth="3.5"
+                    android:fillColor="#00000000" />
+            </group>
+            <group
+                android:name="plane"
+                android:translateX="23.481"
+                android:translateY="18.71151" >
+                <path
+                    android:name="path_3_2"
+                    android:pathData="M 18.9439849854 7.98849487305 c 0.0 0.0 0.0 -4.0 0.0 -4.0 c 0.0 0.0 -16.0 -10.0 -16.0 -10.0 c 0.0 0.0 0.0 -11.0 0.0 -11.0 c 0.0 -1.70001220703 -1.30000305176 -3.0 -3.0 -3.0 c -1.69999694824 0.0 -3.0 1.29998779297 -3.0 3.0 c 0.0 0.0 0.0 11.0 0.0 11.0 c 0.0 0.0 -16.0 10.0 -16.0 10.0 c 0.0 0.0 0.0 4.0 0.0 4.0 c 0.0 0.0 16.0 -5.0 16.0 -5.0 c 0.0 0.0 0.0 11.0 0.0 11.0 c 0.0 0.0 -4.0 3.0 -4.0 3.0 c 0.0 0.0 0.0 3.0 0.0 3.0 c 0.0 0.0 7.0 -2.0 7.0 -2.0 c 0.0 0.0 7.0 2.0 7.0 2.0 c 0.0 0.0 0.0 -3.0 0.0 -3.0 c 0.0 0.0 -4.0 -3.0 -4.0 -3.0 c 0.0 0.0 0.0 -11.0 0.0 -11.0 c 0.0 0.0 16.0 5.0 16.0 5.0 Z"
+                    android:fillColor="#FF777777" />
+            </group>
+        </group>
+    </group>
+</vector>
diff --git a/samples/SupportVectorDrawableDemos/res/drawable/ic_signal_airplane_v2_animation.xml b/samples/SupportVectorDrawableDemos/res/drawable/ic_signal_airplane_v2_animation.xml
new file mode 100644
index 0000000..bde2b38
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/drawable/ic_signal_airplane_v2_animation.xml
@@ -0,0 +1,29 @@
+<!-- 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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/ic_signal_airplane_v2" >
+    <target
+        android:name="ic_signal_airplane"
+        android:animation="@anim/ic_signal_airplane_v2_animation_ic_signal_airplane" />
+    <target
+        android:name="mask_2"
+        android:animation="@anim/ic_signal_airplane_v2_animation_mask_2" />
+    <target
+        android:name="cross_1"
+        android:animation="@anim/ic_signal_airplane_v2_animation_cross_1" />
+    <target
+        android:name="path_1_1"
+        android:animation="@anim/ic_signal_airplane_v2_animation_path_1_1" />
+</animated-vector>
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable01.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable01.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable01.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable01.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable02.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable02.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable02.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable02.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable03.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable03.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable03.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable03.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable04.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable04.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable04.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable04.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable05.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable05.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable05.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable05.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable06.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable06.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable06.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable06.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable07.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable07.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable07.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable07.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable08.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable08.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable08.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable08.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable09.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable09.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable09.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable09.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable10.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable10.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable10.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable10.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable11.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable11.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable11.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable11.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable12.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable12.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable12.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable12.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable13.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable13.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable13.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable13.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable14.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable14.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable14.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable14.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable15.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable15.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable15.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable15.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable16.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable16.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable16.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable16.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable17.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable17.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable17.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable17.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable18.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable18.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable18.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable18.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable19.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable19.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable19.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable19.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable20.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable20.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable20.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable20.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable21.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable21.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable21.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable21.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable22.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable22.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable22.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable22.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable23.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable23.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable23.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable23.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable24.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable24.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable24.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable24.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable25.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable25.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable25.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable25.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable26.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable26.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable26.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable26.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable27.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable27.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable27.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable27.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable28.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable28.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable28.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable28.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable29.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable29.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable29.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable29.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable30.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable30.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable30.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable30.xml
diff --git a/samples/SupportVectorDrawable/animated/res/drawable/vector_drawable_grouping_1.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_grouping_1.xml
similarity index 100%
rename from samples/SupportVectorDrawable/animated/res/drawable/vector_drawable_grouping_1.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_grouping_1.xml
diff --git a/samples/SupportVectorDrawable/animated/res/drawable/vector_drawable_progress_bar.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_progress_bar.xml
similarity index 100%
rename from samples/SupportVectorDrawable/animated/res/drawable/vector_drawable_progress_bar.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_progress_bar.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable_scale0.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_scale0.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable_scale0.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_scale0.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable_scale1.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_scale1.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable_scale1.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_scale1.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable_scale2.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_scale2.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable_scale2.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_scale2.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_drawable_scale3.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_scale3.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_drawable_scale3.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_drawable_scale3.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_test01.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_test01.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_test01.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_test01.xml
diff --git a/samples/SupportVectorDrawable/static/res/drawable/vector_test02.xml b/samples/SupportVectorDrawableDemos/res/drawable/vector_test02.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/drawable/vector_test02.xml
rename to samples/SupportVectorDrawableDemos/res/drawable/vector_test02.xml
diff --git a/samples/SupportVectorDrawableDemos/res/interpolator/control_points_interpolator.xml b/samples/SupportVectorDrawableDemos/res/interpolator/control_points_interpolator.xml
new file mode 100644
index 0000000..510f202
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/interpolator/control_points_interpolator.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:controlX1="0"
+                  android:controlY1="0"
+                  android:controlX2="0"
+                  android:controlY2="1"/>
diff --git a/samples/SupportVectorDrawableDemos/res/interpolator/path_interpolator.xml b/samples/SupportVectorDrawableDemos/res/interpolator/path_interpolator.xml
new file mode 100644
index 0000000..98c7ee9
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/interpolator/path_interpolator.xml
@@ -0,0 +1,18 @@
+<?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.
+  -->
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:pathData="M 0.0,0.0 c 0.08,0.0 0.04,1.0 0.2,0.8 l 0.6,0.1 L 1.0,1.0"/>
diff --git a/samples/SupportVectorDrawableDemos/res/interpolator/single_control_point_interpolator.xml b/samples/SupportVectorDrawableDemos/res/interpolator/single_control_point_interpolator.xml
new file mode 100644
index 0000000..81ff055
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/interpolator/single_control_point_interpolator.xml
@@ -0,0 +1,21 @@
+<?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.
+  -->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:controlX1="1"
+                  android:controlY1="0"/>
diff --git a/samples/SupportVectorDrawableDemos/res/layout/avdc_listener.xml b/samples/SupportVectorDrawableDemos/res/layout/avdc_listener.xml
new file mode 100644
index 0000000..827bc25
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/res/layout/avdc_listener.xml
@@ -0,0 +1,48 @@
+<?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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              xmlns:app="http://schemas.android.com/apk/res-auto"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" android:weightSum="1">
+
+    <android.support.v7.widget.AppCompatImageView
+        app:srcCompat="@drawable/ic_signal_airplane_v2_animation"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" android:id="@+id/imageView"/>
+    <TextView
+        android:text="TextView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" android:id="@+id/textView"/>
+    <TextView
+        android:text="TextView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" android:id="@+id/textView2"/>
+    <android.support.v7.widget.AppCompatImageView
+        app:srcCompat="@drawable/ic_hourglass_animation"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" android:id="@+id/imageView2"/>
+    <TextView
+        android:text="TextView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" android:id="@+id/textView3"/>
+    <TextView
+        android:text="TextView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" android:id="@+id/textView4"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawable/static/res/raw/vector_drawable01.xml b/samples/SupportVectorDrawableDemos/res/raw/vector_drawable01.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/raw/vector_drawable01.xml
rename to samples/SupportVectorDrawableDemos/res/raw/vector_drawable01.xml
diff --git a/samples/SupportVectorDrawable/static/res/values/colors.xml b/samples/SupportVectorDrawableDemos/res/values/colors.xml
similarity index 100%
rename from samples/SupportVectorDrawable/static/res/values/colors.xml
rename to samples/SupportVectorDrawableDemos/res/values/colors.xml
diff --git a/samples/SupportVectorDrawable/static/res/values/strings.xml b/samples/SupportVectorDrawableDemos/res/values/strings.xml
similarity index 99%
rename from samples/SupportVectorDrawable/static/res/values/strings.xml
rename to samples/SupportVectorDrawableDemos/res/values/strings.xml
index 065e7d9..a59ad14 100644
--- a/samples/SupportVectorDrawable/static/res/values/strings.xml
+++ b/samples/SupportVectorDrawableDemos/res/values/strings.xml
@@ -16,7 +16,6 @@
 -->
 
 <resources>
-
     <string name="twoLinePathData">"M 0,0 v 100 M 0,0 h 100"</string>
     <string name="triangle"> "M300,70 l 0,-70 70,70 0,0   -70,70z"</string>
     <string name="rectangle">"M300,70 l 0,-70 70,0  0,140 -70,0 z"</string>
@@ -26,4 +25,4 @@
     <string name="heart">    "m4.5,-7c-1.95509,0 -3.83009,1.26759 -4.5,3c-0.66991,-1.73241 -2.54691,-3 -4.5,-3c-2.543,0 -4.5,1.93159 -4.5,4.5c0,3.5293 3.793,6.2578 9,11.5c5.207,-5.2422 9,-7.9707 9,-11.5c0,-2.56841 -1.957,-4.5 -4.5,-4.5"</string>
     <string name="rectangle200">"M 0,0 l 200,0 l 0, 200 l -200, 0 z"</string>
     <string name="triangle100">"M 100, 0 l 0, 100, -100, 0 z"</string>
-</resources>
+</resources>
\ No newline at end of file
diff --git a/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/AVDCListenerDemo.java b/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/AVDCListenerDemo.java
new file mode 100644
index 0000000..f228a43
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/AVDCListenerDemo.java
@@ -0,0 +1,135 @@
+/*
+ * 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 com.example.android.support.vectordrawable.app;
+
+import android.graphics.drawable.Animatable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.support.graphics.drawable.Animatable2Compat;
+import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.AppCompatImageView;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.TextView;
+
+import com.example.android.support.vectordrawable.R;
+
+/**
+ * A demo for AnimatedVectorDrawableCompat's listener support.
+ */
+public class AVDCListenerDemo extends AppCompatActivity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.avdc_listener);
+        final AppCompatImageView imageView1 = (AppCompatImageView) findViewById(R.id.imageView);
+        final AppCompatImageView imageView2 = (AppCompatImageView) findViewById(R.id.imageView2);
+
+        final TextView textView1 = (TextView) findViewById(R.id.textView);
+        textView1.setText("Should show start / end for first AVD");
+        final TextView textView2 = (TextView) findViewById(R.id.textView2);
+        textView2.setText("Not affected by AVD, b/c removed after register");
+        final TextView textView3 = (TextView) findViewById(R.id.textView3);
+        textView3.setText("Should show start / end for second AVD");
+        final TextView textView4 = (TextView) findViewById(R.id.textView4);
+        textView4.setText("Not affected by AVD, b/c unregistered after register");
+
+        final Drawable drawable1 = imageView1.getDrawable();
+        final Drawable drawable2 = imageView2.getDrawable();
+
+        Animatable2Compat.AnimationCallback textView1Callback = new
+                Animatable2Compat.AnimationCallback() {
+                    @Override
+                    public void onAnimationStart(Drawable drawable) {
+                        textView1.setText("AVD 1 started");
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Drawable drawable) {
+                        textView1.setText("AVD 1 Ended");
+                    }
+                };
+        Animatable2Compat.AnimationCallback textView2Callback = new
+                Animatable2Compat.AnimationCallback() {
+                    @Override
+                    public void onAnimationStart(Drawable drawable) {
+                        textView2.setText("AVD 1 started");
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Drawable drawable) {
+                        textView2.setText("AVD 1 Ended");
+                    }
+                };
+        AnimatedVectorDrawableCompat.registerAnimationCallback(drawable1, textView1Callback);
+        AnimatedVectorDrawableCompat.registerAnimationCallback(drawable1, textView2Callback);
+        AnimatedVectorDrawableCompat.clearAnimationCallbacks(drawable1);
+        AnimatedVectorDrawableCompat.registerAnimationCallback(drawable1, textView1Callback);
+
+        AnimatedVectorDrawableCompat.registerAnimationCallback(drawable2,
+                new Animatable2Compat.AnimationCallback() {
+                    @Override
+                    public void onAnimationStart(Drawable drawable) {
+                        textView3.setText("AVD 2 started");
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Drawable drawable) {
+                        textView3.setText("AVD 2 Ended");
+                    }
+                });
+
+        Animatable2Compat.AnimationCallback textView4Callback = new
+                Animatable2Compat.AnimationCallback() {
+                    @Override
+                    public void onAnimationStart(Drawable drawable) {
+                        textView4.setText("AVD 2 started");
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Drawable drawable) {
+                        textView4.setText("AVD 2 Ended");
+                    }
+                };
+
+        AnimatedVectorDrawableCompat.registerAnimationCallback(drawable2, textView4Callback);
+        AnimatedVectorDrawableCompat.unregisterAnimationCallback(drawable2, textView4Callback);
+
+        // Touch the imageView will run the AVD.
+        imageView1.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if (!((Animatable) drawable1).isRunning()) {
+                    ((Animatable) drawable1).start();
+                }
+                return true;
+            }
+        });
+
+        imageView2.setOnTouchListener(new View.OnTouchListener() {
+            @Override
+            public boolean onTouch(View v, MotionEvent event) {
+                if (!((Animatable) drawable2).isRunning()) {
+                    ((Animatable) drawable2).start();
+                }
+                return true;
+            }
+        });
+    }
+}
diff --git a/samples/SupportVectorDrawable/animated/src/com/example/android/support/vectordrawable/app/AnimatedButtonBackground.java b/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SimpleAnimatedVectorDrawable.java
similarity index 75%
rename from samples/SupportVectorDrawable/animated/src/com/example/android/support/vectordrawable/app/AnimatedButtonBackground.java
rename to samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SimpleAnimatedVectorDrawable.java
index d8381d1..feb9d3c 100644
--- a/samples/SupportVectorDrawable/animated/src/com/example/android/support/vectordrawable/app/AnimatedButtonBackground.java
+++ b/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SimpleAnimatedVectorDrawable.java
@@ -16,7 +16,6 @@
 
 package com.example.android.support.vectordrawable.app;
 
-import android.animation.ObjectAnimator;
 import android.app.Activity;
 import android.content.res.Resources;
 import android.os.Bundle;
@@ -26,24 +25,30 @@
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
 import android.widget.TextView;
+
 import com.example.android.support.vectordrawable.R;
 
 import java.text.DecimalFormat;
 
-public class AnimatedButtonBackground extends Activity implements View.OnClickListener{
+/**
+ * Simple demo for AnimatedVectorDrawableCompat.
+ */
+public class SimpleAnimatedVectorDrawable extends Activity implements View.OnClickListener {
     private static final String LOG_TAG = "TestActivity";
 
     private static final String LOGCAT = "VectorDrawable1";
-    protected int[] icon = {
-        R.drawable.animation_vector_drawable_grouping_1,
-        R.drawable.animation_vector_progress_bar,
-        R.drawable.btn_radio_on_to_off_bundle,
+    protected int[] mIcons = {
+            R.drawable.animation_vector_drawable_grouping_1,
+            R.drawable.animation_vector_drawable_grouping_decelerate,
+            R.drawable.animation_vector_drawable_grouping_accelerate,
+            R.drawable.ic_hourglass_animation,
+            R.drawable.ic_signal_airplane_v2_animation,
+            R.drawable.animation_vector_progress_bar,
+            R.drawable.btn_radio_on_to_off_bundle,
     };
 
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        ObjectAnimator oa = new ObjectAnimator();
         super.onCreate(savedInstanceState);
         ScrollView scrollView = new ScrollView(this);
         LinearLayout container = new LinearLayout(this);
@@ -51,15 +56,15 @@
         container.setOrientation(LinearLayout.VERTICAL);
         Resources res = this.getResources();
         container.setBackgroundColor(0xFF888888);
-        AnimatedVectorDrawableCompat []d = new AnimatedVectorDrawableCompat[icon.length];
-        long time =  android.os.SystemClock.currentThreadTimeMillis();
-        for (int i = 0; i < icon.length; i++) {
-             d[i] = AnimatedVectorDrawableCompat.create(this, icon[i]);
+        AnimatedVectorDrawableCompat[] d = new AnimatedVectorDrawableCompat[mIcons.length];
+        long time = android.os.SystemClock.currentThreadTimeMillis();
+        for (int i = 0; i < mIcons.length; i++) {
+            d[i] = AnimatedVectorDrawableCompat.create(this, mIcons[i]);
         }
-        time =  android.os.SystemClock.currentThreadTimeMillis()-time;
+        time = android.os.SystemClock.currentThreadTimeMillis() - time;
         TextView t = new TextView(this);
         DecimalFormat df = new DecimalFormat("#.##");
-        t.setText("avgL=" + df.format(time / (icon.length)) + " ms");
+        t.setText("avgL=" + df.format(time / (mIcons.length)) + " ms");
         container.addView(t);
 
         addDrawableButtons(container, d);
diff --git a/samples/SupportVectorDrawable/static/src/com/example/android/support/vectordrawable/app/SimpleButtonBackground.java b/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SimpleStaticVectorDrawable.java
similarity index 86%
rename from samples/SupportVectorDrawable/static/src/com/example/android/support/vectordrawable/app/SimpleButtonBackground.java
rename to samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SimpleStaticVectorDrawable.java
index 79a51ac..deee6c6 100644
--- a/samples/SupportVectorDrawable/static/src/com/example/android/support/vectordrawable/app/SimpleButtonBackground.java
+++ b/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SimpleStaticVectorDrawable.java
@@ -26,15 +26,18 @@
 import android.widget.LinearLayout;
 import android.widget.ScrollView;
 import android.widget.TextView;
+
 import com.example.android.support.vectordrawable.R;
 
 import java.text.DecimalFormat;
 
-public class SimpleButtonBackground extends Activity {
-    private static final String LOG_TAG = "SimpleButtonBackground";
+/**
+ * Simple demo for VectorDrawableCompat.
+ */
+public class SimpleStaticVectorDrawable extends Activity {
+    private static final String LOG_TAG = "SimpleStaticVectorDrawable";
 
-    private static final String LOGCAT = "VectorDrawable1";
-    protected int[] icon = {
+    protected int[] mIcons = {
             R.drawable.vector_drawable_scale0,
             R.drawable.vector_drawable_scale1,
             R.drawable.vector_drawable_scale2,
@@ -84,12 +87,12 @@
         container.setOrientation(LinearLayout.VERTICAL);
         Resources res = this.getResources();
         container.setBackgroundColor(0xFF888888);
-        VectorDrawableCompat []d = new VectorDrawableCompat[icon.length];
-        long time =  android.os.SystemClock.currentThreadTimeMillis();
-        for (int i = 0; i < icon.length; i++) {
-             d[i] = VectorDrawableCompat.create(res, icon[i], getTheme());
+        VectorDrawableCompat[] d = new VectorDrawableCompat[mIcons.length];
+        long time = android.os.SystemClock.currentThreadTimeMillis();
+        for (int i = 0; i < mIcons.length; i++) {
+            d[i] = VectorDrawableCompat.create(res, mIcons[i], getTheme());
         }
-        time =  android.os.SystemClock.currentThreadTimeMillis()-time;
+        time = android.os.SystemClock.currentThreadTimeMillis() - time;
 
         // Testing Tint on one particular case.
         if (d.length > 3) {
@@ -99,7 +102,7 @@
 
         // Testing Constant State like operation by creating the first 2 icons
         // from the 3rd one's constant state.
-        VectorDrawableCompat []extras = new VectorDrawableCompat[EXTRA_TESTS];
+        VectorDrawableCompat[] extras = new VectorDrawableCompat[EXTRA_TESTS];
         ConstantState state = d[0].getConstantState();
         extras[0] = (VectorDrawableCompat) state.newDrawable();
         extras[1] = (VectorDrawableCompat) state.newDrawable();
@@ -113,7 +116,7 @@
         // Just show the average create time as the first view.
         TextView t = new TextView(this);
         DecimalFormat df = new DecimalFormat("#.##");
-        t.setText("avgL=" + df.format(time / (icon.length)) + " ms");
+        t.setText("avgL=" + df.format(time / (mIcons.length)) + " ms");
         container.addView(t);
 
         addDrawableButtons(container, extras);
diff --git a/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SupportVectorDrawableDemos.java b/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SupportVectorDrawableDemos.java
new file mode 100644
index 0000000..1bb3377
--- /dev/null
+++ b/samples/SupportVectorDrawableDemos/src/com/example/android/support/vectordrawable/app/SupportVectorDrawableDemos.java
@@ -0,0 +1,155 @@
+/*
+ * 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 com.example.android.support.vectordrawable.app;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+import java.text.Collator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The root level activity for this demo. Showing a list of sub demos.
+ */
+public class SupportVectorDrawableDemos extends ListActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Intent intent = getIntent();
+        String path = intent.getStringExtra("com.example.android.apis.Path");
+
+        if (path == null) {
+            path = "";
+        }
+
+        setListAdapter(new SimpleAdapter(this, getData(path),
+                android.R.layout.simple_list_item_1, new String[]{"title"},
+                new int[]{android.R.id.text1}));
+        getListView().setTextFilterEnabled(true);
+    }
+
+    protected List<Map<String, Object>> getData(String prefix) {
+        List<Map<String, Object>> myData = new ArrayList<Map<String, Object>>();
+
+        Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+        mainIntent.addCategory("android.intent.category.SAMPLE_CODE");
+
+        PackageManager pm = getPackageManager();
+        List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
+
+        if (null == list) {
+            return myData;
+        }
+
+        String[] prefixPath;
+        String prefixWithSlash = prefix;
+
+        if (prefix.equals("")) {
+            prefixPath = null;
+        } else {
+            prefixPath = prefix.split("/");
+            prefixWithSlash = prefix + "/";
+        }
+
+        int len = list.size();
+
+        Map<String, Boolean> entries = new HashMap<String, Boolean>();
+
+        for (int i = 0; i < len; i++) {
+            ResolveInfo info = list.get(i);
+            CharSequence labelSeq = info.loadLabel(pm);
+            String label = labelSeq != null
+                    ? labelSeq.toString()
+                    : info.activityInfo.name;
+
+            if (prefixWithSlash.length() == 0 || label.startsWith(prefixWithSlash)) {
+
+                String[] labelPath = label.split("/");
+
+                String nextLabel = prefixPath == null ? labelPath[0] : labelPath[prefixPath.length];
+
+                if ((prefixPath != null ? prefixPath.length : 0) == labelPath.length - 1) {
+                    addItem(myData, nextLabel, activityIntent(
+                            info.activityInfo.applicationInfo.packageName,
+                            info.activityInfo.name));
+                } else {
+                    if (entries.get(nextLabel) == null) {
+                        addItem(myData, nextLabel, browseIntent(
+                                prefix.equals("") ? nextLabel : prefix + "/" + nextLabel));
+                        entries.put(nextLabel, true);
+                    }
+                }
+            }
+        }
+
+        Collections.sort(myData, sDisplayNameComparator);
+
+        return myData;
+    }
+
+    private static final Comparator<Map<String, Object>> sDisplayNameComparator =
+            new Comparator<Map<String, Object>>() {
+                private final Collator mCollator = Collator.getInstance();
+
+                @Override
+                public int compare(Map<String, Object> map1, Map<String, Object> map2) {
+                    return mCollator.compare(map1.get("title"), map2.get("title"));
+                }
+            };
+
+    protected Intent activityIntent(String pkg, String componentName) {
+        Intent result = new Intent();
+        result.setClassName(pkg, componentName);
+        return result;
+    }
+
+    protected Intent browseIntent(String path) {
+        Intent result = new Intent();
+        result.setClass(this, SupportVectorDrawableDemos.class);
+        result.putExtra("com.example.android.apis.Path", path);
+        return result;
+    }
+
+    protected void addItem(List<Map<String, Object>> data, String name, Intent intent) {
+        Map<String, Object> temp = new HashMap<String, Object>();
+        temp.put("title", name);
+        temp.put("intent", intent);
+        data.add(temp);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        Map<String, Object> map = (Map<String, Object>) l.getItemAtPosition(position);
+
+        Intent intent = (Intent) map.get("intent");
+        startActivity(intent);
+    }
+}
diff --git a/settings.gradle b/settings.gradle
index e4e79a8..af43ef2 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -82,6 +82,9 @@
 include ':support-transition'
 project(':support-transition').projectDir = new File(rootDir, 'transition')
 
+include ':support-dynamic-animation'
+project(':support-dynamic-animation').projectDir = new File(rootDir, 'dynamic-animation')
+
 include ':support-exifinterface'
 project(':support-exifinterface').projectDir = new File(rootDir, 'exifinterface')
 
@@ -118,6 +121,12 @@
 include ':support-v13-demos'
 project(':support-v13-demos').projectDir = new File(samplesRoot, 'Support13Demos')
 
+include ':support-vector-drawable-demos'
+project(':support-vector-drawable-demos').projectDir = new File(samplesRoot, 'SupportVectorDrawableDemos')
+
+include ':support-animation-demos'
+project(':support-animation-demos').projectDir = new File(samplesRoot, 'SupportAnimationDemos')
+
 /////////////////////////////
 //
 // External
diff --git a/transition/AndroidManifest.xml b/transition/AndroidManifest.xml
index 1059f63..309b695 100644
--- a/transition/AndroidManifest.xml
+++ b/transition/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.transition">
     <uses-sdk android:minSdkVersion="14"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v13/AndroidManifest.xml b/v13/AndroidManifest.xml
index 7449688..3520ab3 100644
--- a/v13/AndroidManifest.xml
+++ b/v13/AndroidManifest.xml
@@ -17,6 +17,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.v13">
     <uses-sdk android:minSdkVersion="13" tools:overrideLibrary="android.support.v13"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}"/>
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v14/preference/AndroidManifest.xml b/v14/preference/AndroidManifest.xml
index 74cff2e..95bab75 100644
--- a/v14/preference/AndroidManifest.xml
+++ b/v14/preference/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.support.v14.preference">
     <uses-sdk android:minSdkVersion="14" />
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v17/leanback/AndroidManifest.xml b/v17/leanback/AndroidManifest.xml
index ded4ce8..9176231 100644
--- a/v17/leanback/AndroidManifest.xml
+++ b/v17/leanback/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v17.leanback">
     <uses-sdk android:minSdkVersion="17"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
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..2d0ab62 100644
--- a/v17/leanback/api21/android/support/v17/leanback/transition/TransitionHelperApi21.java
+++ b/v17/leanback/api21/android/support/v17/leanback/transition/TransitionHelperApi21.java
@@ -55,10 +55,18 @@
         return window.getSharedElementEnterTransition();
     }
 
+    public static void setSharedElementEnterTransition(Window window, Object transition) {
+        window.setSharedElementEnterTransition((Transition) transition);
+    }
+
     public static Object getSharedElementReturnTransition(Window window) {
         return window.getSharedElementReturnTransition();
     }
 
+    public static void setSharedElementReturnTransition(Window window, Object transition) {
+        window.setSharedElementReturnTransition((Transition) transition);
+    }
+
     public static Object getSharedElementExitTransition(Window window) {
         return window.getSharedElementExitTransition();
     }
@@ -71,10 +79,18 @@
         return window.getEnterTransition();
     }
 
+    public static void setEnterTransition(Window window, Object transition) {
+        window.setEnterTransition((Transition) transition);
+    }
+
     public static Object getReturnTransition(Window window) {
         return window.getReturnTransition();
     }
 
+    public static void setReturnTransition(Window window, Object transition) {
+        window.setReturnTransition((Transition) transition);
+    }
+
     public static Object getExitTransition(Window window) {
         return window.getExitTransition();
     }
diff --git a/v17/leanback/generatev4.py b/v17/leanback/generatev4.py
index ae695e50..4bd9550 100755
--- a/v17/leanback/generatev4.py
+++ b/v17/leanback/generatev4.py
@@ -100,6 +100,7 @@
     line = re.sub(r'FragmentUtil.getContext\(mFragment\)', 'mFragment.getContext()', line);
     line = line.replace('VideoFragment', 'VideoSupportFragment')
     line = line.replace('DetailsFragment', 'DetailsSupportFragment')
+    line = line.replace('RowsFragment', 'RowsSupportFragment')
     line = line.replace('VideoSupportFragmentGlueHost'.format(w), 'VideoSupportFragmentGlueHost'.format(w))
     line = line.replace('android.app.Fragment', 'android.support.v4.app.Fragment')
     outfile.write(line)
diff --git a/v17/leanback/res/layout/lb_playback_controls.xml b/v17/leanback/res/layout/lb_playback_controls.xml
index dda7e06..df2be51 100644
--- a/v17/leanback/res/layout/lb_playback_controls.xml
+++ b/v17/leanback/res/layout/lb_playback_controls.xml
@@ -30,55 +30,43 @@
         android:layoutDirection="ltr"
         android:progressDrawable="@drawable/lb_playback_progress_bar" />
 
-    <android.support.v17.leanback.widget.PersistentFocusWrapper
-        android:id="@+id/controls_container_focus_wrapper"
+    <FrameLayout
+        android:id="@+id/controls_container"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" >
 
+        <android.support.v17.leanback.widget.ControlBar
+            android:id="@+id/control_bar"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layoutDirection="ltr"
+            android:layout_gravity="center_horizontal"
+            android:orientation="horizontal" />
+
         <FrameLayout
-            android:id="@+id/controls_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content" >
+            android:id="@+id/more_actions_dock"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="end" />
 
-            <android.support.v17.leanback.widget.PersistentFocusWrapper
-                android:id="@+id/control_bar_focus_wrapper"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="center_horizontal">
+        <TextView
+            android:id="@+id/current_time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|left"
+            android:layout_marginStart="@dimen/lb_playback_current_time_margin_start"
+            android:paddingTop="@dimen/lb_playback_time_padding_top"
+            style="?attr/playbackControlsTimeStyle" />
 
-                <android.support.v17.leanback.widget.ControlBar
-                    android:id="@+id/control_bar"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layoutDirection="ltr"
-                    android:orientation="horizontal" />
-                </android.support.v17.leanback.widget.PersistentFocusWrapper>
+        <TextView
+            android:id="@+id/total_time"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="top|right"
+            android:layout_marginEnd="@dimen/lb_playback_total_time_margin_end"
+            android:paddingTop="@dimen/lb_playback_time_padding_top"
+            style="?attr/playbackControlsTimeStyle" />
 
-            <FrameLayout
-                android:id="@+id/more_actions_dock"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="end" />
-
-            <TextView
-                android:id="@+id/current_time"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="top|left"
-                android:layout_marginStart="@dimen/lb_playback_current_time_margin_start"
-                android:paddingTop="@dimen/lb_playback_time_padding_top"
-                style="?attr/playbackControlsTimeStyle" />
-
-            <TextView
-                android:id="@+id/total_time"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_gravity="top|right"
-                android:layout_marginEnd="@dimen/lb_playback_total_time_margin_end"
-                android:paddingTop="@dimen/lb_playback_time_padding_top"
-                style="?attr/playbackControlsTimeStyle" />
-
-        </FrameLayout>
-    </android.support.v17.leanback.widget.PersistentFocusWrapper>
+    </FrameLayout>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/v17/leanback/res/layout/lb_playback_controls_row.xml b/v17/leanback/res/layout/lb_playback_controls_row.xml
index e3893b3..b449fa9 100644
--- a/v17/leanback/res/layout/lb_playback_controls_row.xml
+++ b/v17/leanback/res/layout/lb_playback_controls_row.xml
@@ -46,6 +46,7 @@
 
         <LinearLayout
             android:id="@+id/controls_card_right_panel"
+            android:layout_gravity="bottom"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:clipChildren="false"
diff --git a/v17/leanback/res/values/dimens.xml b/v17/leanback/res/values/dimens.xml
index 8d174be..4bf237d 100644
--- a/v17/leanback/res/values/dimens.xml
+++ b/v17/leanback/res/values/dimens.xml
@@ -124,9 +124,11 @@
     <dimen name="lb_action_text_size">16sp</dimen>
     <dimen name="lb_action_button_corner_radius">2dp</dimen>
 
-    <dimen name="lb_playback_controls_align_bottom">58dp</dimen>
-    <dimen name="lb_playback_controls_padding_top">216dp</dimen>
+    <!-- distance of bottom of playback row to bottom edge, used for overscan protection and
+    peeking related rows-->
     <dimen name="lb_playback_controls_padding_bottom">28dp</dimen>
+    <!-- distance of other rows' center to bottom edge, half of screen by default -->
+    <dimen name="lb_playback_other_rows_center_to_bottom">270dp</dimen>
     <dimen name="lb_playback_major_fade_translate_y">200dp</dimen>
     <dimen name="lb_playback_minor_fade_translate_y">16dp</dimen>
     <dimen name="lb_playback_controls_card_height">176dp</dimen>
diff --git a/v17/leanback/res/values/strings.xml b/v17/leanback/res/values/strings.xml
index 1ca09dd..cbf4904 100644
--- a/v17/leanback/res/values/strings.xml
+++ b/v17/leanback/res/values/strings.xml
@@ -81,6 +81,10 @@
     <!-- Talkback label for the control button to enter picture in picture mode -->
     <string name="lb_playback_controls_picture_in_picture">Enter Picture In Picture Mode</string>
 
+
+    <string name="lb_playback_controls_shown">Media controls shown</string>
+    <string name="lb_playback_controls_hidden">Media controls hidden, press d-pad to show</string>
+
     <!-- Title of standard Finish action for GuidedStepFragment -->
     <string name="lb_guidedaction_finish_title">Finish</string>
     <!-- Title of standard Continue action for GuidedStepFragment -->
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
index 8ab731f..b123b9c 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
@@ -13,12 +13,12 @@
  */
 package android.support.v17.leanback.app;
 
-import static android.support.v17.leanback.util.StateMachine.STATUS_EXECUTED;
-
 import android.os.Bundle;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.transition.TransitionListener;
 import android.support.v17.leanback.util.StateMachine;
+import android.support.v17.leanback.util.StateMachine.Condition;
+import android.support.v17.leanback.util.StateMachine.Event;
 import android.support.v17.leanback.util.StateMachine.State;
 import android.view.View;
 import android.view.ViewTreeObserver;
@@ -26,18 +26,24 @@
 /**
  * @hide
  */
+@SuppressWarnings("FragmentNotInstantiable")
 class BaseFragment extends BrandedFragment {
 
     /**
-     * Condition: {@link TransitionHelper#systemSupportsEntranceTransitions()} is true
-     * Action: none
+     * The start state for all
      */
-    private final State STATE_ALLOWED = new State() {
-        @Override
-        public boolean canRun() {
-            return TransitionHelper.systemSupportsEntranceTransitions();
-        }
+    final State STATE_START = new State("START", true, false);
 
+    /**
+     * Initial State for ENTRNACE transition.
+     */
+    final State STATE_ENTRANCE_INIT = new State("ENTRANCE_INIT");
+
+    /**
+     * prepareEntranceTransition is just called, but view not ready yet. We can enable the
+     * busy spinner.
+     */
+    final State STATE_ENTRANCE_ON_PREPARED = new State("ENTRANCE_ON_PREPARED", true, false) {
         @Override
         public void run() {
             mProgressBarManager.show();
@@ -45,15 +51,13 @@
     };
 
     /**
-     * Condition: {@link #isReadyForPrepareEntranceTransition()} is true
-     * Action: {@link #onEntranceTransitionPrepare()} }
+     * prepareEntranceTransition is called and main content view to slide in was created, so we can
+     * call {@link #onEntranceTransitionPrepare}. Note that we dont set initial content to invisible
+     * in this State, the process is very different in subclass, e.g. BrowseFragment hide header
+     * views and hide main fragment view in two steps.
      */
-    private final State STATE_PREPARE = new State() {
-        @Override
-        public boolean canRun() {
-            return isReadyForPrepareEntranceTransition();
-        }
-
+    final State STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW = new State(
+            "ENTRANCE_ON_PREPARED_ON_CREATEVIEW") {
         @Override
         public void run() {
             onEntranceTransitionPrepare();
@@ -61,15 +65,9 @@
     };
 
     /**
-     * Condition: {@link #isReadyForStartEntranceTransition()} is true
-     * Action: {@link #onExecuteEntranceTransition()} }
+     * execute the entrance transition.
      */
-    private final State STATE_START = new State() {
-        @Override
-        public boolean canRun() {
-            return isReadyForStartEntranceTransition();
-        }
-
+    final State STATE_ENTRANCE_PERFORM = new State("STATE_ENTRANCE_PERFORM") {
         @Override
         public void run() {
             mProgressBarManager.hide();
@@ -77,26 +75,109 @@
         }
     };
 
-    final StateMachine mEnterTransitionStates;
+    /**
+     * execute onEntranceTransitionEnd.
+     */
+    final State STATE_ENTRANCE_ON_ENDED = new State("ENTRANCE_ON_ENDED") {
+        @Override
+        public void run() {
+            onEntranceTransitionEnd();
+        }
+    };
+
+    /**
+     * either entrance transition completed or skipped
+     */
+    final State STATE_ENTRANCE_COMPLETE = new State("ENTRANCE_COMPLETE", true, false);
+
+    /**
+     * Event fragment.onCreate()
+     */
+    final Event EVT_ON_CREATE = new Event("onCreate");
+
+    /**
+     * Event fragment.onViewCreated()
+     */
+    final Event EVT_ON_CREATEVIEW = new Event("onCreateView");
+
+    /**
+     * Event for {@link #prepareEntranceTransition()} is called.
+     */
+    final Event EVT_PREPARE_ENTRANCE = new Event("prepareEntranceTransition");
+
+    /**
+     * Event for {@link #startEntranceTransition()} is called.
+     */
+    final Event EVT_START_ENTRANCE = new Event("startEntranceTransition");
+
+    /**
+     * Event for entrance transition is ended through Transition listener.
+     */
+    final Event EVT_ENTRANCE_END = new Event("onEntranceTransitionEnd");
+
+    /**
+     * Event for skipping entrance transition if not supported.
+     */
+    final Condition COND_TRANSITION_NOT_SUPPORTED = new Condition("EntranceTransitionNotSupport") {
+        @Override
+        public boolean canProceed() {
+            return !TransitionHelper.systemSupportsEntranceTransitions();
+        }
+    };
+
+    final StateMachine mStateMachine = new StateMachine();
 
     Object mEntranceTransition;
     final ProgressBarManager mProgressBarManager = new ProgressBarManager();
 
     BaseFragment() {
-        mEnterTransitionStates = new StateMachine();
-        mEnterTransitionStates.addState(STATE_ALLOWED);
-        mEnterTransitionStates.addState(STATE_PREPARE);
-        mEnterTransitionStates.addState(STATE_START);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        createStateMachineStates();
+        createStateMachineTransitions();
+        mStateMachine.start();
+        super.onCreate(savedInstanceState);
+        mStateMachine.fireEvent(EVT_ON_CREATE);
+    }
+
+    void createStateMachineStates() {
+        mStateMachine.addState(STATE_START);
+        mStateMachine.addState(STATE_ENTRANCE_INIT);
+        mStateMachine.addState(STATE_ENTRANCE_ON_PREPARED);
+        mStateMachine.addState(STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW);
+        mStateMachine.addState(STATE_ENTRANCE_PERFORM);
+        mStateMachine.addState(STATE_ENTRANCE_ON_ENDED);
+        mStateMachine.addState(STATE_ENTRANCE_COMPLETE);
+    }
+
+    void createStateMachineTransitions() {
+        mStateMachine.addTransition(STATE_START, STATE_ENTRANCE_INIT, EVT_ON_CREATE);
+        mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_COMPLETE,
+                COND_TRANSITION_NOT_SUPPORTED);
+        mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_COMPLETE,
+                EVT_ON_CREATEVIEW);
+        mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_ON_PREPARED,
+                EVT_PREPARE_ENTRANCE);
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW,
+                EVT_ON_CREATEVIEW);
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_ENTRANCE_PERFORM,
+                EVT_START_ENTRANCE);
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW,
+                STATE_ENTRANCE_PERFORM);
+        mStateMachine.addTransition(STATE_ENTRANCE_PERFORM,
+                STATE_ENTRANCE_ON_ENDED,
+                EVT_ENTRANCE_END);
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_ENDED, STATE_ENTRANCE_COMPLETE);
     }
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        performPendingStates();
-    }
-
-    final void performPendingStates() {
-        mEnterTransitionStates.runPendingStates();
+        mStateMachine.fireEvent(EVT_ON_CREATEVIEW);
     }
 
     /**
@@ -126,18 +207,7 @@
      * override the default transition that browse and details provides.
      */
     public void prepareEntranceTransition() {
-        mEnterTransitionStates.runState(STATE_ALLOWED);
-        mEnterTransitionStates.runState(STATE_PREPARE);
-    }
-
-    /**
-     * Return true if entrance transition is enabled and not started yet.
-     * Entrance transition can only be executed once and isEntranceTransitionEnabled()
-     * is reset to false after entrance transition is started.
-     */
-    boolean isEntranceTransitionEnabled() {
-        // Enabled when passed STATE_ALLOWED in prepareEntranceTransition call.
-        return STATE_ALLOWED.getStatus() == STATUS_EXECUTED;
+        mStateMachine.fireEvent(EVT_PREPARE_ENTRANCE);
     }
 
     /**
@@ -178,26 +248,6 @@
     }
 
     /**
-     * Returns true if it is ready to perform {@link #prepareEntranceTransition()}, false otherwise.
-     * Subclass may override and add additional conditions.
-     * @return True if it is ready to perform {@link #prepareEntranceTransition()}, false otherwise.
-     * Subclass may override and add additional conditions.
-     */
-    boolean isReadyForPrepareEntranceTransition() {
-        return getView() != null;
-    }
-
-    /**
-     * Returns true if it is ready to perform {@link #startEntranceTransition()}, false otherwise.
-     * Subclass may override and add additional conditions.
-     * @return True if it is ready to perform {@link #startEntranceTransition()}, false otherwise.
-     * Subclass may override and add additional conditions.
-     */
-    boolean isReadyForStartEntranceTransition() {
-        return getView() != null;
-    }
-
-    /**
      * When fragment finishes loading data, it should call startEntranceTransition()
      * to execute the entrance transition.
      * startEntranceTransition() will start transition only if both two conditions
@@ -209,7 +259,7 @@
      * and executed when view is created.
      */
     public void startEntranceTransition() {
-        mEnterTransitionStates.runState(STATE_START);
+        mStateMachine.fireEvent(EVT_START_ENTRANCE);
     }
 
     void onExecuteEntranceTransition() {
@@ -224,9 +274,11 @@
                     return true;
                 }
                 internalCreateEntranceTransition();
+                onEntranceTransitionStart();
                 if (mEntranceTransition != null) {
-                    onEntranceTransitionStart();
                     runEntranceTransition(mEntranceTransition);
+                } else {
+                    mStateMachine.fireEvent(EVT_ENTRANCE_END);
                 }
                 return false;
             }
@@ -243,8 +295,7 @@
             @Override
             public void onTransitionEnd(Object transition) {
                 mEntranceTransition = null;
-                onEntranceTransitionEnd();
-                mEnterTransitionStates.resetStatus();
+                mStateMachine.fireEvent(EVT_ENTRANCE_END);
             }
         });
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
index 7d08738..0db81b3 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
@@ -16,12 +16,12 @@
  */
 package android.support.v17.leanback.app;
 
-import static android.support.v17.leanback.util.StateMachine.STATUS_EXECUTED;
-
 import android.os.Bundle;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.transition.TransitionListener;
 import android.support.v17.leanback.util.StateMachine;
+import android.support.v17.leanback.util.StateMachine.Condition;
+import android.support.v17.leanback.util.StateMachine.Event;
 import android.support.v17.leanback.util.StateMachine.State;
 import android.view.View;
 import android.view.ViewTreeObserver;
@@ -29,18 +29,24 @@
 /**
  * @hide
  */
+@SuppressWarnings("FragmentNotInstantiable")
 class BaseSupportFragment extends BrandedSupportFragment {
 
     /**
-     * Condition: {@link TransitionHelper#systemSupportsEntranceTransitions()} is true
-     * Action: none
+     * The start state for all
      */
-    private final State STATE_ALLOWED = new State() {
-        @Override
-        public boolean canRun() {
-            return TransitionHelper.systemSupportsEntranceTransitions();
-        }
+    final State STATE_START = new State("START", true, false);
 
+    /**
+     * Initial State for ENTRNACE transition.
+     */
+    final State STATE_ENTRANCE_INIT = new State("ENTRANCE_INIT");
+
+    /**
+     * prepareEntranceTransition is just called, but view not ready yet. We can enable the
+     * busy spinner.
+     */
+    final State STATE_ENTRANCE_ON_PREPARED = new State("ENTRANCE_ON_PREPARED", true, false) {
         @Override
         public void run() {
             mProgressBarManager.show();
@@ -48,15 +54,13 @@
     };
 
     /**
-     * Condition: {@link #isReadyForPrepareEntranceTransition()} is true
-     * Action: {@link #onEntranceTransitionPrepare()} }
+     * prepareEntranceTransition is called and main content view to slide in was created, so we can
+     * call {@link #onEntranceTransitionPrepare}. Note that we dont set initial content to invisible
+     * in this State, the process is very different in subclass, e.g. BrowseSupportFragment hide header
+     * views and hide main fragment view in two steps.
      */
-    private final State STATE_PREPARE = new State() {
-        @Override
-        public boolean canRun() {
-            return isReadyForPrepareEntranceTransition();
-        }
-
+    final State STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW = new State(
+            "ENTRANCE_ON_PREPARED_ON_CREATEVIEW") {
         @Override
         public void run() {
             onEntranceTransitionPrepare();
@@ -64,15 +68,9 @@
     };
 
     /**
-     * Condition: {@link #isReadyForStartEntranceTransition()} is true
-     * Action: {@link #onExecuteEntranceTransition()} }
+     * execute the entrance transition.
      */
-    private final State STATE_START = new State() {
-        @Override
-        public boolean canRun() {
-            return isReadyForStartEntranceTransition();
-        }
-
+    final State STATE_ENTRANCE_PERFORM = new State("STATE_ENTRANCE_PERFORM") {
         @Override
         public void run() {
             mProgressBarManager.hide();
@@ -80,26 +78,109 @@
         }
     };
 
-    final StateMachine mEnterTransitionStates;
+    /**
+     * execute onEntranceTransitionEnd.
+     */
+    final State STATE_ENTRANCE_ON_ENDED = new State("ENTRANCE_ON_ENDED") {
+        @Override
+        public void run() {
+            onEntranceTransitionEnd();
+        }
+    };
+
+    /**
+     * either entrance transition completed or skipped
+     */
+    final State STATE_ENTRANCE_COMPLETE = new State("ENTRANCE_COMPLETE", true, false);
+
+    /**
+     * Event fragment.onCreate()
+     */
+    final Event EVT_ON_CREATE = new Event("onCreate");
+
+    /**
+     * Event fragment.onViewCreated()
+     */
+    final Event EVT_ON_CREATEVIEW = new Event("onCreateView");
+
+    /**
+     * Event for {@link #prepareEntranceTransition()} is called.
+     */
+    final Event EVT_PREPARE_ENTRANCE = new Event("prepareEntranceTransition");
+
+    /**
+     * Event for {@link #startEntranceTransition()} is called.
+     */
+    final Event EVT_START_ENTRANCE = new Event("startEntranceTransition");
+
+    /**
+     * Event for entrance transition is ended through Transition listener.
+     */
+    final Event EVT_ENTRANCE_END = new Event("onEntranceTransitionEnd");
+
+    /**
+     * Event for skipping entrance transition if not supported.
+     */
+    final Condition COND_TRANSITION_NOT_SUPPORTED = new Condition("EntranceTransitionNotSupport") {
+        @Override
+        public boolean canProceed() {
+            return !TransitionHelper.systemSupportsEntranceTransitions();
+        }
+    };
+
+    final StateMachine mStateMachine = new StateMachine();
 
     Object mEntranceTransition;
     final ProgressBarManager mProgressBarManager = new ProgressBarManager();
 
     BaseSupportFragment() {
-        mEnterTransitionStates = new StateMachine();
-        mEnterTransitionStates.addState(STATE_ALLOWED);
-        mEnterTransitionStates.addState(STATE_PREPARE);
-        mEnterTransitionStates.addState(STATE_START);
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        createStateMachineStates();
+        createStateMachineTransitions();
+        mStateMachine.start();
+        super.onCreate(savedInstanceState);
+        mStateMachine.fireEvent(EVT_ON_CREATE);
+    }
+
+    void createStateMachineStates() {
+        mStateMachine.addState(STATE_START);
+        mStateMachine.addState(STATE_ENTRANCE_INIT);
+        mStateMachine.addState(STATE_ENTRANCE_ON_PREPARED);
+        mStateMachine.addState(STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW);
+        mStateMachine.addState(STATE_ENTRANCE_PERFORM);
+        mStateMachine.addState(STATE_ENTRANCE_ON_ENDED);
+        mStateMachine.addState(STATE_ENTRANCE_COMPLETE);
+    }
+
+    void createStateMachineTransitions() {
+        mStateMachine.addTransition(STATE_START, STATE_ENTRANCE_INIT, EVT_ON_CREATE);
+        mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_COMPLETE,
+                COND_TRANSITION_NOT_SUPPORTED);
+        mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_COMPLETE,
+                EVT_ON_CREATEVIEW);
+        mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_ENTRANCE_ON_PREPARED,
+                EVT_PREPARE_ENTRANCE);
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW,
+                EVT_ON_CREATEVIEW);
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_ENTRANCE_PERFORM,
+                EVT_START_ENTRANCE);
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW,
+                STATE_ENTRANCE_PERFORM);
+        mStateMachine.addTransition(STATE_ENTRANCE_PERFORM,
+                STATE_ENTRANCE_ON_ENDED,
+                EVT_ENTRANCE_END);
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_ENDED, STATE_ENTRANCE_COMPLETE);
     }
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
-        performPendingStates();
-    }
-
-    final void performPendingStates() {
-        mEnterTransitionStates.runPendingStates();
+        mStateMachine.fireEvent(EVT_ON_CREATEVIEW);
     }
 
     /**
@@ -129,18 +210,7 @@
      * override the default transition that browse and details provides.
      */
     public void prepareEntranceTransition() {
-        mEnterTransitionStates.runState(STATE_ALLOWED);
-        mEnterTransitionStates.runState(STATE_PREPARE);
-    }
-
-    /**
-     * Return true if entrance transition is enabled and not started yet.
-     * Entrance transition can only be executed once and isEntranceTransitionEnabled()
-     * is reset to false after entrance transition is started.
-     */
-    boolean isEntranceTransitionEnabled() {
-        // Enabled when passed STATE_ALLOWED in prepareEntranceTransition call.
-        return STATE_ALLOWED.getStatus() == STATUS_EXECUTED;
+        mStateMachine.fireEvent(EVT_PREPARE_ENTRANCE);
     }
 
     /**
@@ -181,26 +251,6 @@
     }
 
     /**
-     * Returns true if it is ready to perform {@link #prepareEntranceTransition()}, false otherwise.
-     * Subclass may override and add additional conditions.
-     * @return True if it is ready to perform {@link #prepareEntranceTransition()}, false otherwise.
-     * Subclass may override and add additional conditions.
-     */
-    boolean isReadyForPrepareEntranceTransition() {
-        return getView() != null;
-    }
-
-    /**
-     * Returns true if it is ready to perform {@link #startEntranceTransition()}, false otherwise.
-     * Subclass may override and add additional conditions.
-     * @return True if it is ready to perform {@link #startEntranceTransition()}, false otherwise.
-     * Subclass may override and add additional conditions.
-     */
-    boolean isReadyForStartEntranceTransition() {
-        return getView() != null;
-    }
-
-    /**
      * When fragment finishes loading data, it should call startEntranceTransition()
      * to execute the entrance transition.
      * startEntranceTransition() will start transition only if both two conditions
@@ -212,7 +262,7 @@
      * and executed when view is created.
      */
     public void startEntranceTransition() {
-        mEnterTransitionStates.runState(STATE_START);
+        mStateMachine.fireEvent(EVT_START_ENTRANCE);
     }
 
     void onExecuteEntranceTransition() {
@@ -227,9 +277,11 @@
                     return true;
                 }
                 internalCreateEntranceTransition();
+                onEntranceTransitionStart();
                 if (mEntranceTransition != null) {
-                    onEntranceTransitionStart();
                     runEntranceTransition(mEntranceTransition);
+                } else {
+                    mStateMachine.fireEvent(EVT_ENTRANCE_END);
                 }
                 return false;
             }
@@ -246,8 +298,7 @@
             @Override
             public void onTransitionEnd(Object transition) {
                 mEntranceTransition = null;
-                onEntranceTransitionEnd();
-                mEnterTransitionStates.resetStatus();
+                mStateMachine.fireEvent(EVT_ENTRANCE_END);
             }
         });
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrandedFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrandedFragment.java
index f16d569..35350e4 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrandedFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrandedFragment.java
@@ -150,6 +150,7 @@
         }
         if (mTitleView != null && view instanceof ViewGroup) {
             mTitleHelper = new TitleHelper((ViewGroup) view, mTitleView);
+            mTitleHelper.showTitle(mShowingTitle);
         }
     }
 
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrandedSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrandedSupportFragment.java
index 1a0d81f..9c42780 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrandedSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrandedSupportFragment.java
@@ -153,6 +153,7 @@
         }
         if (mTitleView != null && view instanceof ViewGroup) {
             mTitleHelper = new TitleHelper((ViewGroup) view, mTitleView);
+            mTitleHelper.showTitle(mShowingTitle);
         }
     }
 
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
index 1c9e5ca..dc40239 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
@@ -28,6 +28,8 @@
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.transition.TransitionListener;
+import android.support.v17.leanback.util.StateMachine.Event;
+import android.support.v17.leanback.util.StateMachine.State;
 import android.support.v17.leanback.widget.BrowseFrameLayout;
 import android.support.v17.leanback.widget.InvisibleRowPresenter;
 import android.support.v17.leanback.widget.ListRow;
@@ -86,6 +88,56 @@
     private static final String IS_PAGE_ROW = "isPageRow";
     private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition";
 
+    /**
+     * State to hide headers fragment.
+     */
+    final State STATE_SET_ENTRANCE_START_STATE = new State("SET_ENTRANCE_START_STATE") {
+        @Override
+        public void run() {
+            setEntranceTransitionStartState();
+        }
+    };
+
+    /**
+     * Event for Header fragment view is created, we could perform
+     * {@link #setEntranceTransitionStartState()} to hide headers fragment initially.
+     */
+    final Event EVT_HEADER_VIEW_CREATED = new Event("headerFragmentViewCreated");
+
+    /**
+     * Event for {@link #getMainFragment()} view is created, it's additional requirement to execute
+     * {@link #onEntranceTransitionPrepare()}.
+     */
+    final Event EVT_MAIN_FRAGMENT_VIEW_CREATED = new Event("mainFragmentViewCreated");
+
+    /**
+     * Event that data for the screen is ready, this is additional requirement to launch entrance
+     * transition.
+     */
+    final Event EVT_SCREEN_DATA_READY = new Event("screenDataReady");
+
+    @Override
+    void createStateMachineStates() {
+        super.createStateMachineStates();
+        mStateMachine.addState(STATE_SET_ENTRANCE_START_STATE);
+    }
+
+    @Override
+    void createStateMachineTransitions() {
+        super.createStateMachineTransitions();
+        // when headers fragment view is created we could setEntranceTransitionStartState()
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED, STATE_SET_ENTRANCE_START_STATE,
+                EVT_HEADER_VIEW_CREATED);
+
+        // add additional requirement for onEntranceTransitionPrepare()
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW,
+                EVT_MAIN_FRAGMENT_VIEW_CREATED);
+        // add additional requirement to launch entrance transition.
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,  STATE_ENTRANCE_PERFORM,
+                EVT_SCREEN_DATA_READY);
+    }
+
     final class BackStackListener implements FragmentManager.OnBackStackChangedListener {
         int mLastEntryCount;
         int mIndexOfHeadersBackStack;
@@ -252,20 +304,21 @@
      */
     private final class FragmentHostImpl implements FragmentHost {
         boolean mShowTitleView = true;
-        boolean mDataReady = false;
 
         FragmentHostImpl() {
         }
 
         @Override
         public void notifyViewCreated(MainFragmentAdapter fragmentAdapter) {
-            performPendingStates();
+            mStateMachine.fireEvent(EVT_MAIN_FRAGMENT_VIEW_CREATED);
+            if (!mIsPageRow) {
+                // If it's not a PageRow: it's a ListRow, so we already have data ready.
+                mStateMachine.fireEvent(EVT_SCREEN_DATA_READY);
+            }
         }
 
         @Override
         public void notifyDataReady(MainFragmentAdapter fragmentAdapter) {
-            mDataReady = true;
-
             // If fragment host is not the currently active fragment (in BrowseFragment), then
             // ignore the request.
             if (mMainFragmentAdapter == null || mMainFragmentAdapter.getFragmentHost() != this) {
@@ -277,7 +330,7 @@
                 return;
             }
 
-            performPendingStates();
+            mStateMachine.fireEvent(EVT_SCREEN_DATA_READY);
         }
 
         @Override
@@ -1224,17 +1277,6 @@
         }
     }
 
-    @Override
-    boolean isReadyForPrepareEntranceTransition() {
-        return mMainFragment != null && mMainFragment.getView() != null;
-    }
-
-    @Override
-    boolean isReadyForStartEntranceTransition() {
-        return mMainFragment != null && mMainFragment.getView() != null
-                && (!mIsPageRow || mMainFragmentAdapter.mFragmentHost.mDataReady);
-    }
-
     void createHeadersTransition() {
         mHeadersTransition = TransitionHelper.loadTransition(FragmentUtil.getContext(this),
                 mShowingHeaders
@@ -1455,7 +1497,6 @@
             swapToMainFragment();
             expandMainFragment(!(mCanShowHeaders && mShowingHeaders));
             setupMainFragment();
-            performPendingStates();
         }
     }
 
@@ -1468,6 +1509,7 @@
             getChildFragmentManager().beginTransaction()
                     .replace(R.id.scale_frame, new Fragment()).commit();
             gridView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+                @SuppressWarnings("ReferenceEquality")
                 @Override
                 public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                     if (newState == RecyclerView.SCROLL_STATE_IDLE) {
@@ -1564,9 +1606,7 @@
             showHeaders(mShowingHeaders);
         }
 
-        if (isEntranceTransitionEnabled()) {
-            setEntranceTransitionStartState();
-        }
+        mStateMachine.fireEvent(EVT_HEADER_VIEW_CREATED);
     }
 
     private void onExpandTransitionStart(boolean expand, final Runnable callback) {
@@ -1682,8 +1722,6 @@
     @Override
     protected void onEntranceTransitionPrepare() {
         mHeadersFragment.onTransitionPrepare();
-        // setEntranceTransitionStartState() might be called when mMainFragment is null,
-        // make sure it is called.
         mMainFragmentAdapter.setEntranceTransitionState(false);
         mMainFragmentAdapter.onTransitionPrepare();
     }
@@ -1717,7 +1755,9 @@
     void setEntranceTransitionStartState() {
         setHeadersOnScreen(false);
         setSearchOrbViewOnScreen(false);
-        mMainFragmentAdapter.setEntranceTransitionState(false);
+        // NOTE that mMainFragmentAdapter.setEntranceTransitionState(false) will be called
+        // in onEntranceTransitionPrepare() because mMainFragmentAdapter is still the dummy
+        // one when setEntranceTransitionStartState() is called.
     }
 
     void setEntranceTransitionEndState() {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
index c7d8de4..21ce544 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
@@ -31,6 +31,8 @@
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.transition.TransitionListener;
+import android.support.v17.leanback.util.StateMachine.Event;
+import android.support.v17.leanback.util.StateMachine.State;
 import android.support.v17.leanback.widget.BrowseFrameLayout;
 import android.support.v17.leanback.widget.InvisibleRowPresenter;
 import android.support.v17.leanback.widget.ListRow;
@@ -89,6 +91,56 @@
     private static final String IS_PAGE_ROW = "isPageRow";
     private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition";
 
+    /**
+     * State to hide headers fragment.
+     */
+    final State STATE_SET_ENTRANCE_START_STATE = new State("SET_ENTRANCE_START_STATE") {
+        @Override
+        public void run() {
+            setEntranceTransitionStartState();
+        }
+    };
+
+    /**
+     * Event for Header fragment view is created, we could perform
+     * {@link #setEntranceTransitionStartState()} to hide headers fragment initially.
+     */
+    final Event EVT_HEADER_VIEW_CREATED = new Event("headerFragmentViewCreated");
+
+    /**
+     * Event for {@link #getMainFragment()} view is created, it's additional requirement to execute
+     * {@link #onEntranceTransitionPrepare()}.
+     */
+    final Event EVT_MAIN_FRAGMENT_VIEW_CREATED = new Event("mainFragmentViewCreated");
+
+    /**
+     * Event that data for the screen is ready, this is additional requirement to launch entrance
+     * transition.
+     */
+    final Event EVT_SCREEN_DATA_READY = new Event("screenDataReady");
+
+    @Override
+    void createStateMachineStates() {
+        super.createStateMachineStates();
+        mStateMachine.addState(STATE_SET_ENTRANCE_START_STATE);
+    }
+
+    @Override
+    void createStateMachineTransitions() {
+        super.createStateMachineTransitions();
+        // when headers fragment view is created we could setEntranceTransitionStartState()
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED, STATE_SET_ENTRANCE_START_STATE,
+                EVT_HEADER_VIEW_CREATED);
+
+        // add additional requirement for onEntranceTransitionPrepare()
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_ENTRANCE_ON_PREPARED_ON_CREATEVIEW,
+                EVT_MAIN_FRAGMENT_VIEW_CREATED);
+        // add additional requirement to launch entrance transition.
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,  STATE_ENTRANCE_PERFORM,
+                EVT_SCREEN_DATA_READY);
+    }
+
     final class BackStackListener implements FragmentManager.OnBackStackChangedListener {
         int mLastEntryCount;
         int mIndexOfHeadersBackStack;
@@ -255,20 +307,21 @@
      */
     private final class FragmentHostImpl implements FragmentHost {
         boolean mShowTitleView = true;
-        boolean mDataReady = false;
 
         FragmentHostImpl() {
         }
 
         @Override
         public void notifyViewCreated(MainFragmentAdapter fragmentAdapter) {
-            performPendingStates();
+            mStateMachine.fireEvent(EVT_MAIN_FRAGMENT_VIEW_CREATED);
+            if (!mIsPageRow) {
+                // If it's not a PageRow: it's a ListRow, so we already have data ready.
+                mStateMachine.fireEvent(EVT_SCREEN_DATA_READY);
+            }
         }
 
         @Override
         public void notifyDataReady(MainFragmentAdapter fragmentAdapter) {
-            mDataReady = true;
-
             // If fragment host is not the currently active fragment (in BrowseSupportFragment), then
             // ignore the request.
             if (mMainFragmentAdapter == null || mMainFragmentAdapter.getFragmentHost() != this) {
@@ -280,7 +333,7 @@
                 return;
             }
 
-            performPendingStates();
+            mStateMachine.fireEvent(EVT_SCREEN_DATA_READY);
         }
 
         @Override
@@ -1227,17 +1280,6 @@
         }
     }
 
-    @Override
-    boolean isReadyForPrepareEntranceTransition() {
-        return mMainFragment != null && mMainFragment.getView() != null;
-    }
-
-    @Override
-    boolean isReadyForStartEntranceTransition() {
-        return mMainFragment != null && mMainFragment.getView() != null
-                && (!mIsPageRow || mMainFragmentAdapter.mFragmentHost.mDataReady);
-    }
-
     void createHeadersTransition() {
         mHeadersTransition = TransitionHelper.loadTransition(getContext(),
                 mShowingHeaders
@@ -1458,7 +1500,6 @@
             swapToMainFragment();
             expandMainFragment(!(mCanShowHeaders && mShowingHeaders));
             setupMainFragment();
-            performPendingStates();
         }
     }
 
@@ -1471,6 +1512,7 @@
             getChildFragmentManager().beginTransaction()
                     .replace(R.id.scale_frame, new Fragment()).commit();
             gridView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+                @SuppressWarnings("ReferenceEquality")
                 @Override
                 public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                     if (newState == RecyclerView.SCROLL_STATE_IDLE) {
@@ -1567,9 +1609,7 @@
             showHeaders(mShowingHeaders);
         }
 
-        if (isEntranceTransitionEnabled()) {
-            setEntranceTransitionStartState();
-        }
+        mStateMachine.fireEvent(EVT_HEADER_VIEW_CREATED);
     }
 
     private void onExpandTransitionStart(boolean expand, final Runnable callback) {
@@ -1685,8 +1725,6 @@
     @Override
     protected void onEntranceTransitionPrepare() {
         mHeadersSupportFragment.onTransitionPrepare();
-        // setEntranceTransitionStartState() might be called when mMainFragment is null,
-        // make sure it is called.
         mMainFragmentAdapter.setEntranceTransitionState(false);
         mMainFragmentAdapter.onTransitionPrepare();
     }
@@ -1720,7 +1758,9 @@
     void setEntranceTransitionStartState() {
         setHeadersOnScreen(false);
         setSearchOrbViewOnScreen(false);
-        mMainFragmentAdapter.setEntranceTransitionState(false);
+        // NOTE that mMainFragmentAdapter.setEntranceTransitionState(false) will be called
+        // in onEntranceTransitionPrepare() because mMainFragmentAdapter is still the dummy
+        // one when setEntranceTransitionStartState() is called.
     }
 
     void setEntranceTransitionEndState() {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsBackgroundVideoHelper.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsBackgroundVideoHelper.java
index 37a6bfc..5bae3d0 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsBackgroundVideoHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsBackgroundVideoHelper.java
@@ -56,6 +56,7 @@
     private ValueAnimator mBackgroundAnimator;
     private Drawable mBackgroundDrawable;
     private PlaybackGlue mPlaybackGlue;
+    private boolean mBackgroundDrawableVisible;
 
     /**
      * Constructor to setup a Helper for controlling video playback in DetailsFragment.
@@ -75,6 +76,8 @@
         this.mPlaybackGlue = playbackGlue;
         this.mDetailsParallax = detailsParallax;
         this.mBackgroundDrawable = backgroundDrawable;
+        mBackgroundDrawableVisible = true;
+        mBackgroundDrawable.setAlpha(255);
         startParallax();
     }
 
@@ -88,8 +91,6 @@
         mParallaxEffect = mDetailsParallax
                 .addEffect(frameTop.atFraction(maxFrameTop), frameTop.atFraction(minFrameTop))
                 .target(new ParallaxTarget() {
-
-                    float mFraction;
                     @Override
                     public void update(float fraction) {
                         if (fraction == maxFrameTop) {
@@ -97,14 +98,11 @@
                         } else {
                             updateState(PLAY_VIDEO);
                         }
-                        mFraction = fraction;
-                    }
-
-                    @Override
-                    public float getFraction() {
-                        return mFraction;
                     }
                 });
+        // In case the VideoHelper is created after RecyclerView is created: perform initial
+        // parallax effect.
+        mDetailsParallax.updateValues();
     }
 
     void stopParallax() {
@@ -120,24 +118,44 @@
             return;
         }
         mCurrentState = state;
-        switch (state) {
+        applyState();
+    }
+
+    private void applyState() {
+        switch (mCurrentState) {
             case PLAY_VIDEO:
-                if (mPlaybackGlue.isReadyForPlayback()) {
-                    internalStartPlayback();
+                if (mPlaybackGlue != null) {
+                    if (mPlaybackGlue.isReadyForPlayback()) {
+                        internalStartPlayback();
+                    } else {
+                        mPlaybackGlue.setPlayerCallback(mControlStateCallback);
+                    }
                 } else {
-                    mPlaybackGlue.setPlayerCallback(new PlaybackControlStateCallback());
+                    crossFadeBackgroundToVideo(false);
                 }
                 break;
             case NO_VIDEO:
                 crossFadeBackgroundToVideo(false);
-                mPlaybackGlue.setPlayerCallback(null);
-                mPlaybackGlue.pause();
+                if (mPlaybackGlue != null) {
+                    mPlaybackGlue.setPlayerCallback(null);
+                    mPlaybackGlue.pause();
+                }
                 break;
         }
     }
 
+    void setPlaybackGlue(PlaybackGlue playbackGlue) {
+        if (mPlaybackGlue != null) {
+            mPlaybackGlue.setPlayerCallback(null);
+        }
+        mPlaybackGlue = playbackGlue;
+        applyState();
+    }
+
     private void internalStartPlayback() {
-        mPlaybackGlue.play();
+        if (mPlaybackGlue != null) {
+            mPlaybackGlue.play();
+        }
         mDetailsParallax.getRecyclerView().postDelayed(new Runnable() {
             @Override
             public void run() {
@@ -146,7 +164,26 @@
         }, CROSSFADE_DELAY);
     }
 
-    private void crossFadeBackgroundToVideo(final boolean crossFadeToVideo) {
+    void crossFadeBackgroundToVideo(boolean crossFadeToVideo) {
+        crossFadeBackgroundToVideo(crossFadeToVideo, false);
+    }
+
+    void crossFadeBackgroundToVideo(boolean crossFadeToVideo, boolean immediate) {
+        final boolean newVisible = !crossFadeToVideo;
+        if (mBackgroundDrawableVisible == newVisible) {
+            if (immediate) {
+                if (mBackgroundAnimator != null) {
+                    mBackgroundAnimator.cancel();
+                    mBackgroundAnimator = null;
+                }
+                if (mBackgroundDrawable != null) {
+                    mBackgroundDrawable.setAlpha(crossFadeToVideo ? 0 : 255);
+                    return;
+                }
+            }
+            return;
+        }
+        mBackgroundDrawableVisible = newVisible;
         if (mBackgroundAnimator != null) {
             mBackgroundAnimator.cancel();
             mBackgroundAnimator = null;
@@ -158,6 +195,10 @@
         if (mBackgroundDrawable == null) {
             return;
         }
+        if (immediate) {
+            mBackgroundDrawable.setAlpha(crossFadeToVideo ? 0 : 255);
+            return;
+        }
         mBackgroundAnimator = ValueAnimator.ofFloat(startAlpha, endAlpha);
         mBackgroundAnimator.setDuration(BACKGROUND_CROSS_FADE_DURATION);
         mBackgroundAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@@ -197,4 +238,6 @@
             internalStartPlayback();
         }
     }
+
+    PlaybackControlStateCallback mControlStateCallback = new PlaybackControlStateCallback();
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
index a2480d4..57a85a0 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
@@ -24,6 +24,8 @@
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.transition.TransitionListener;
+import android.support.v17.leanback.util.StateMachine.Event;
+import android.support.v17.leanback.util.StateMachine.State;
 import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
 import android.support.v17.leanback.widget.BaseOnItemViewSelectedListener;
 import android.support.v17.leanback.widget.BrowseFrameLayout;
@@ -41,6 +43,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 
 import java.lang.ref.WeakReference;
 
@@ -77,27 +80,200 @@
  * {@link FullWidthDetailsOverviewRowPresenter}.
  * </li>
  * </p>
+ *
+ * <p>
+ * DetailsFragment can use {@link DetailsFragmentBackgroundController} to add a parallax drawable
+ * background and embedded video playing fragment.
+ * </p>
  */
 public class DetailsFragment extends BaseFragment {
     static final String TAG = "DetailsFragment";
     static boolean DEBUG = false;
 
+    final State STATE_SET_ENTRANCE_START_STATE = new State("STATE_SET_ENTRANCE_START_STATE") {
+        @Override
+        public void run() {
+            mRowsFragment.setEntranceTransitionState(false);
+        }
+    };
+
+    final State STATE_ENTER_TRANSITION_INIT = new State("STATE_ENTER_TRANSIITON_INIT");
+
+    void switchToVideoBeforeVideoFragmentCreated() {
+        // if the video fragment is not ready: immediately fade out covering drawable,
+        // hide title and mark mPendingFocusOnVideo and set focus on it later.
+        mDetailsBackgroundController.crossFadeBackgroundToVideo(true, true);
+        showTitle(false);
+        mPendingFocusOnVideo = true;
+        slideOutGridView();
+    }
+
+    final State STATE_SWITCH_TO_VIDEO_IN_ON_CREATE = new State("STATE_SWITCH_TO_VIDEO_IN_ON_CREATE",
+            false, false) {
+        @Override
+        public void run() {
+            switchToVideoBeforeVideoFragmentCreated();
+        }
+    };
+
+    final State STATE_ENTER_TRANSITION_CANCEL = new State("STATE_ENTER_TRANSITION_CANCEL",
+            false, false) {
+        @Override
+        public void run() {
+            if (mWaitEnterTransitionTimeout != null) {
+                mWaitEnterTransitionTimeout.mRef.clear();
+            }
+            // clear the activity enter/sharedElement transition, return transitions are kept.
+            // keep the return transitions and clear enter transition
+            if (getActivity() != null) {
+                Window window = getActivity().getWindow();
+                Object returnTransition = TransitionHelper.getReturnTransition(window);
+                Object sharedReturnTransition = TransitionHelper
+                        .getSharedElementReturnTransition(window);
+                TransitionHelper.setEnterTransition(window, null);
+                TransitionHelper.setSharedElementEnterTransition(window, null);
+                TransitionHelper.setReturnTransition(window, returnTransition);
+                TransitionHelper.setSharedElementReturnTransition(window, sharedReturnTransition);
+            }
+        }
+    };
+
+    final State STATE_ENTER_TRANSITION_COMPLETE = new State("STATE_ENTER_TRANSIITON_COMPLETE",
+            true, false);
+
+    final State STATE_ENTER_TRANSITION_ADDLISTENER = new State("STATE_ENTER_TRANSITION_PENDING") {
+        @Override
+        public void run() {
+            Object transition = TransitionHelper.getEnterTransition(getActivity().getWindow());
+            TransitionHelper.addTransitionListener(transition, mEnterTransitionListener);
+        }
+    };
+
+    final State STATE_ENTER_TRANSITION_PENDING = new State("STATE_ENTER_TRANSITION_PENDING") {
+        @Override
+        public void run() {
+            if (mWaitEnterTransitionTimeout == null) {
+                new WaitEnterTransitionTimeout(DetailsFragment.this);
+            }
+        }
+    };
+
     /**
-     * Flag for "possibly" having enter transition not finished yet.
-     * @see #mStartAndTransitionFlag
+     * Start this task when first DetailsOverviewRow is created, if there is no entrance transition
+     * started, it will clear PF_ENTRANCE_TRANSITION_PENDING.
      */
-    static final int PF_ENTER_TRANSITION_PENDING = 0x1 << 0;
-    /**
-     * Flag for having entrance transition not finished yet.
-     * @see #mStartAndTransitionFlag
-     */
-    static final int PF_ENTRANCE_TRANSITION_PENDING = 0x1 << 1;
-    /**
-     * Flag that onStart() has been called and about to call onSafeStart() when
-     * pending transitions are finished.
-     * @see #mStartAndTransitionFlag
-     */
-    static final int PF_PENDING_START = 0x1 << 2;
+    static class WaitEnterTransitionTimeout implements Runnable {
+        static final long WAIT_ENTERTRANSITION_START = 200;
+
+        final WeakReference<DetailsFragment> mRef;
+
+        WaitEnterTransitionTimeout(DetailsFragment f) {
+            mRef = new WeakReference(f);
+            f.getView().postDelayed(this, WAIT_ENTERTRANSITION_START);
+        }
+
+        @Override
+        public void run() {
+            DetailsFragment f = mRef.get();
+            if (f != null) {
+                f.mStateMachine.fireEvent(f.EVT_ENTER_TRANSIITON_DONE);
+            }
+        }
+    }
+
+    final State STATE_ON_SAFE_START = new State("STATE_ON_SAFE_START") {
+        @Override
+        public void run() {
+            onSafeStart();
+        }
+    };
+
+    final Event EVT_ONSTART = new Event("onStart");
+
+    final Event EVT_NO_ENTER_TRANSITION = new Event("EVT_NO_ENTER_TRANSITION");
+
+    final Event EVT_DETAILS_ROW_LOADED = new Event("onFirstRowLoaded");
+
+    final Event EVT_ENTER_TRANSIITON_DONE = new Event("onEnterTransitionDone");
+
+    final Event EVT_SWITCH_TO_VIDEO = new Event("switchToVideo");
+
+    @Override
+    void createStateMachineStates() {
+        super.createStateMachineStates();
+        mStateMachine.addState(STATE_SET_ENTRANCE_START_STATE);
+        mStateMachine.addState(STATE_ON_SAFE_START);
+        mStateMachine.addState(STATE_SWITCH_TO_VIDEO_IN_ON_CREATE);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_INIT);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_ADDLISTENER);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_CANCEL);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_PENDING);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_COMPLETE);
+    }
+
+    @Override
+    void createStateMachineTransitions() {
+        super.createStateMachineTransitions();
+        /**
+         * Part 1: Processing enter transitions after fragment.onCreate
+         */
+        mStateMachine.addTransition(STATE_START, STATE_ENTER_TRANSITION_INIT, EVT_ON_CREATE);
+        // if transition is not supported, skip to complete
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_INIT, STATE_ENTER_TRANSITION_COMPLETE,
+                COND_TRANSITION_NOT_SUPPORTED);
+        // if transition is not set on Activity, skip to complete
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_INIT, STATE_ENTER_TRANSITION_COMPLETE,
+                EVT_NO_ENTER_TRANSITION);
+        // if switchToVideo is called before EVT_ON_CREATEVIEW, clear enter transition and skip to
+        // complete.
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_INIT, STATE_ENTER_TRANSITION_CANCEL,
+                EVT_SWITCH_TO_VIDEO);
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_CANCEL, STATE_ENTER_TRANSITION_COMPLETE);
+        // once after onCreateView, we cannot skip the enter transition, add a listener and wait
+        // it to finish
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_INIT, STATE_ENTER_TRANSITION_ADDLISTENER,
+                EVT_ON_CREATEVIEW);
+        // when enter transition finishes, go to complete, however this might never happen if
+        // the activity is not giving transition options in startActivity, there is no API to query
+        // if this activity is started in a enter transition mode. So we rely on a timer below:
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_ADDLISTENER,
+                STATE_ENTER_TRANSITION_COMPLETE, EVT_ENTER_TRANSIITON_DONE);
+        // we are expecting app to start delayed enter transition shortly after details row is
+        // loaded, so create a timer and wait for enter transition start.
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_ADDLISTENER,
+                STATE_ENTER_TRANSITION_PENDING, EVT_DETAILS_ROW_LOADED);
+        // if enter transition not started in the timer, skip to DONE, this can be also true when
+        // startActivity is not giving transition option.
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_PENDING, STATE_ENTER_TRANSITION_COMPLETE,
+                EVT_ENTER_TRANSIITON_DONE);
+
+        /**
+         * Part 2: modification to the entrance transition defined in BaseFragment
+         */
+        // Must finish enter transition before perform entrance transition.
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_COMPLETE, STATE_ENTRANCE_PERFORM);
+        // Calling switch to video would hide immediately and skip entrance transition
+        mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_SWITCH_TO_VIDEO_IN_ON_CREATE,
+                EVT_SWITCH_TO_VIDEO);
+        mStateMachine.addTransition(STATE_SWITCH_TO_VIDEO_IN_ON_CREATE, STATE_ENTRANCE_COMPLETE);
+        // if the entrance transition is skipped to complete by COND_TRANSITION_NOT_SUPPORTED, we
+        // still need to do the switchToVideo.
+        mStateMachine.addTransition(STATE_ENTRANCE_COMPLETE, STATE_SWITCH_TO_VIDEO_IN_ON_CREATE,
+                EVT_SWITCH_TO_VIDEO);
+
+        // for once the view is created in onStart and prepareEntranceTransition was called, we
+        // could setEntranceStartState:
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_SET_ENTRANCE_START_STATE, EVT_ONSTART);
+
+        /**
+         * Part 3: onSafeStart()
+         */
+        // for onSafeStart: the condition is onStart called, entrance transition complete
+        mStateMachine.addTransition(STATE_START, STATE_ON_SAFE_START, EVT_ONSTART);
+        mStateMachine.addTransition(STATE_ENTRANCE_COMPLETE, STATE_ON_SAFE_START);
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_COMPLETE, STATE_ON_SAFE_START);
+    }
 
     private class SetSelectionRunnable implements Runnable {
         int mPosition;
@@ -115,33 +291,6 @@
         }
     }
 
-    /**
-     * Start this task when first DetailsOverviewRow is created, if there is no entrance transition
-     * started, it will clear PF_ENTRANCE_TRANSITION_PENDING.
-     * @see #mStartAndTransitionFlag
-     */
-    static class WaitEnterTransitionTimeout implements Runnable {
-        static final long WAIT_ENTERTRANSITION_START = 200;
-
-        final WeakReference<DetailsFragment> mRef;
-
-        WaitEnterTransitionTimeout(DetailsFragment f) {
-            mRef = new WeakReference(f);
-            f.getView().postDelayed(this, WAIT_ENTERTRANSITION_START);
-        }
-
-        @Override
-        public void run() {
-            DetailsFragment f = mRef.get();
-            if (f != null) {
-                f.clearPendingEnterTransition();
-            }
-        }
-    }
-
-    /**
-     * @see #mStartAndTransitionFlag
-     */
     TransitionListener mEnterTransitionListener = new TransitionListener() {
         @Override
         public void onTransitionStart(Object transition) {
@@ -154,12 +303,12 @@
 
         @Override
         public void onTransitionCancel(Object transition) {
-            clearPendingEnterTransition();
+            mStateMachine.fireEvent(EVT_ENTER_TRANSIITON_DONE);
         }
 
         @Override
         public void onTransitionEnd(Object transition) {
-            clearPendingEnterTransition();
+            mStateMachine.fireEvent(EVT_ENTER_TRANSIITON_DONE);
         }
     };
 
@@ -182,23 +331,10 @@
     BaseOnItemViewClickedListener mOnItemViewClickedListener;
     DetailsFragmentBackgroundController mDetailsBackgroundController;
 
+    // A temporarily flag when switchToVideo() is called in onCreate(), if mPendingFocusOnVideo is
+    // true, we will focus to VideoFragment immediately after video fragment's view is created.
+    boolean mPendingFocusOnVideo = false;
 
-    /**
-     * Flags for enter transition, entrance transition and onStart.  When onStart() is called
-     * and both enter transiton and entrance transition are finished, we could call onSafeStart().
-     * 1. in onCreate:
-     *      if user call prepareEntranceTransition, set PF_ENTRANCE_TRANSITION_PENDING
-     *      if there is enterTransition, set PF_ENTER_TRANSITION_PENDING, but we dont know if
-     *      user will run enterTransition or not.
-     * 2. when user add row, start WaitEnterTransitionTimeout to wait possible enter transition
-     * start. If enter transition onTransitionStart is not invoked with a period, we can assume
-     * there is no enter transition running, then WaitEnterTransitionTimeout will clear
-     * PF_ENTER_TRANSITION_PENDING.
-     * 3. When enterTransition runs (either postponed or not),  we will stop the
-     * WaitEnterTransitionTimeout, and let onTransitionEnd/onTransitionCancel to clear
-     * PF_ENTER_TRANSITION_PENDING.
-     */
-    int mStartAndTransitionFlag = 0;
     WaitEnterTransitionTimeout mWaitEnterTransitionTimeout;
 
     Object mSceneAfterEntranceTransition;
@@ -282,14 +418,15 @@
         Activity activity = getActivity();
         if (activity != null) {
             Object transition = TransitionHelper.getEnterTransition(activity.getWindow());
-            if (transition != null) {
-                mStartAndTransitionFlag |= PF_ENTER_TRANSITION_PENDING;
-                TransitionHelper.addTransitionListener(transition, mEnterTransitionListener);
+            if (transition == null) {
+                mStateMachine.fireEvent(EVT_NO_ENTER_TRANSITION);
             }
             transition = TransitionHelper.getReturnTransition(activity.getWindow());
             if (transition != null) {
                 TransitionHelper.addTransitionListener(transition, mReturnTransitionListener);
             }
+        } else {
+            mStateMachine.fireEvent(EVT_NO_ENTER_TRANSITION);
         }
     }
 
@@ -444,6 +581,22 @@
         }
     }
 
+    void switchToVideo() {
+        if (mVideoFragment != null && mVideoFragment.getView() != null) {
+            mVideoFragment.getView().requestFocus();
+        } else {
+            mStateMachine.fireEvent(EVT_SWITCH_TO_VIDEO);
+        }
+    }
+
+    void switchToRows() {
+        mPendingFocusOnVideo = false;
+        VerticalGridView verticalGridView = getVerticalGridView();
+        if (verticalGridView != null && verticalGridView.getChildCount() > 0) {
+            verticalGridView.requestFocus();
+        }
+    }
+
     /**
      * This method asks DetailsFragmentBackgroundController to add a fragment for rendering video.
      * In case the fragment is already there, it will return the existing one. The method must be
@@ -460,6 +613,18 @@
             ft2.add(android.support.v17.leanback.R.id.video_surface_container,
                     fragment = mDetailsBackgroundController.onCreateVideoFragment());
             ft2.commit();
+            if (mPendingFocusOnVideo) {
+                // wait next cycle for Fragment view created so we can focus on it.
+                // This is a bit hack eventually we will do commitNow() which get view immediately.
+                getView().post(new Runnable() {
+                    public void run() {
+                        if (getView() != null) {
+                            switchToVideo();
+                        }
+                        mPendingFocusOnVideo = false;
+                    }
+                });
+            }
         }
         mVideoFragment = fragment;
         return mVideoFragment;
@@ -468,7 +633,7 @@
     void onRowSelected(int selectedPosition, int selectedSubPosition) {
         ObjectAdapter adapter = getAdapter();
         if (( mRowsFragment != null && mRowsFragment.getView() != null
-                && mRowsFragment.getView().hasFocus())
+                && mRowsFragment.getView().hasFocus() && !mPendingFocusOnVideo)
                 && (adapter == null || adapter.size() == 0
                 || (getVerticalGridView().getSelectedPosition() == 0
                 && getVerticalGridView().getSelectedSubPosition() == 0))) {
@@ -479,10 +644,8 @@
         if (adapter != null && adapter.size() > selectedPosition) {
             final VerticalGridView gridView = getVerticalGridView();
             final int count = gridView.getChildCount();
-            if (count > 0 && (mStartAndTransitionFlag & PF_ENTER_TRANSITION_PENDING) != 0) {
-                if (mWaitEnterTransitionTimeout == null) {
-                    mWaitEnterTransitionTimeout = new WaitEnterTransitionTimeout(this);
-                }
+            if (count > 0) {
+                mStateMachine.fireEvent(EVT_DETAILS_ROW_LOADED);
             }
             for (int i = 0; i < count; i++) {
                 ItemBridgeAdapter.ViewHolder bridgeViewHolder = (ItemBridgeAdapter.ViewHolder)
@@ -496,25 +659,6 @@
         }
     }
 
-    void clearPendingEnterTransition() {
-        if ((mStartAndTransitionFlag & PF_ENTER_TRANSITION_PENDING) != 0) {
-            mStartAndTransitionFlag &= ~PF_ENTER_TRANSITION_PENDING;
-            dispatchOnStartAndTransitionFinished();
-        }
-    }
-
-    void dispatchOnStartAndTransitionFinished() {
-        /**
-         * if onStart() was called and there is no pending enter transition or entrance transition.
-         */
-        if ((mStartAndTransitionFlag & PF_PENDING_START) != 0
-                && (mStartAndTransitionFlag
-                & (PF_ENTER_TRANSITION_PENDING | PF_ENTRANCE_TRANSITION_PENDING)) == 0) {
-            mStartAndTransitionFlag &= ~PF_PENDING_START;
-            onSafeStart();
-        }
-    }
-
     /**
      * Called when onStart and enter transition (postponed/none postponed) and entrance transition
      * are all finished.
@@ -609,17 +753,16 @@
     public void onStart() {
         super.onStart();
 
-        mStartAndTransitionFlag |= PF_PENDING_START;
-        dispatchOnStartAndTransitionFinished();
-
         setupChildFragmentLayout();
-        if (isEntranceTransitionEnabled()) {
-            mRowsFragment.setEntranceTransitionState(false);
-        }
+        mStateMachine.fireEvent(EVT_ONSTART);
         if (mDetailsParallax != null) {
             mDetailsParallax.setRecyclerView(mRowsFragment.getVerticalGridView());
         }
-        mRowsFragment.getVerticalGridView().requestFocus();
+        if (mPendingFocusOnVideo) {
+            slideOutGridView();
+        } else if (!getView().hasFocus()) {
+            mRowsFragment.getVerticalGridView().requestFocus();
+        }
     }
 
     @Override
@@ -635,14 +778,11 @@
 
     @Override
     protected void onEntranceTransitionEnd() {
-        mStartAndTransitionFlag &= ~PF_ENTRANCE_TRANSITION_PENDING;
-        dispatchOnStartAndTransitionFinished();
         mRowsFragment.onTransitionEnd();
     }
 
     @Override
     protected void onEntranceTransitionPrepare() {
-        mStartAndTransitionFlag |= PF_ENTRANCE_TRANSITION_PENDING;
         mRowsFragment.onTransitionPrepare();
     }
 
@@ -704,7 +844,10 @@
             public void onRequestChildFocus(View child, View focused) {
                 if (child != mRootView.getFocusedChild()) {
                     if (child.getId() == R.id.details_fragment_root) {
-                        showTitle(true);
+                        if (!mPendingFocusOnVideo) {
+                            slideInGridView();
+                            showTitle(true);
+                        }
                     } else if (child.getId() == R.id.video_surface_container) {
                         slideOutGridView();
                         showTitle(false);
@@ -720,19 +863,14 @@
                 if (mRowsFragment.getVerticalGridView() != null
                         && mRowsFragment.getVerticalGridView().hasFocus()) {
                     if (direction == View.FOCUS_UP) {
-                        if (mVideoFragment != null && mVideoFragment.getView() != null) {
+                        if (mDetailsBackgroundController != null
+                                && mDetailsBackgroundController.canNavigateToVideoFragment()
+                                && mVideoFragment != null && mVideoFragment.getView() != null) {
                             return mVideoFragment.getView();
                         } else if (getTitleView() != null && getTitleView().hasFocusable()) {
                             return getTitleView();
                         }
                     }
-                } else if (mVideoFragment != null && mVideoFragment.getView() != null
-                        && mVideoFragment.getView().hasFocus()) {
-                    if (direction == View.FOCUS_DOWN) {
-                        if (mRowsFragment.getVerticalGridView() != null) {
-                            return mRowsFragment.getVerticalGridView();
-                        }
-                    }
                 } else if (getTitleView() != null && getTitleView().hasFocus()) {
                     if (direction == View.FOCUS_DOWN) {
                         if (mRowsFragment.getVerticalGridView() != null) {
@@ -755,8 +893,10 @@
                 if (mVideoFragment != null && mVideoFragment.getView() != null
                         && mVideoFragment.getView().hasFocus()) {
                     if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
-                        getVerticalGridView().requestFocus();
-                        return true;
+                        if (getVerticalGridView().getChildCount() > 0) {
+                            getVerticalGridView().requestFocus();
+                            return true;
+                        }
                     }
                 }
 
@@ -774,4 +914,9 @@
         }
     }
 
+    void slideInGridView() {
+        if (getVerticalGridView() != null) {
+            getVerticalGridView().animateIn();
+        }
+    }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragmentBackgroundController.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragmentBackgroundController.java
index ef09ae6..f6f389c 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragmentBackgroundController.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragmentBackgroundController.java
@@ -107,14 +107,14 @@
  */
 public class DetailsFragmentBackgroundController {
 
-    private final DetailsFragment mFragment;
-    private DetailsParallaxDrawable mParallaxDrawable;
-    private int mParallaxDrawableMaxOffset;
-    private PlaybackGlue mPlaybackGlue;
-    private DetailsBackgroundVideoHelper mVideoHelper;
-    private Bitmap mCoverBitmap;
-    private int mSolidColor;
-    private boolean mCanUseHost = false;
+    final DetailsFragment mFragment;
+    DetailsParallaxDrawable mParallaxDrawable;
+    int mParallaxDrawableMaxOffset;
+    PlaybackGlue mPlaybackGlue;
+    DetailsBackgroundVideoHelper mVideoHelper;
+    Bitmap mCoverBitmap;
+    int mSolidColor;
+    boolean mCanUseHost = false;
 
     /**
      * Creates a DetailsFragmentBackgroundController for a DetailsFragment. Note that
@@ -204,14 +204,22 @@
                 bottomDrawable,
                 coverDrawableParallaxTarget);
         mFragment.setBackgroundDrawable(mParallaxDrawable);
+        // create a VideoHelper with null PlaybackGlue for changing CoverDrawable visibility
+        // before PlaybackGlue is ready.
+        mVideoHelper = new DetailsBackgroundVideoHelper(null,
+                mFragment.getParallax(), mParallaxDrawable.getCoverDrawable());
     }
 
     /**
      * Enable video playback and set proper {@link PlaybackGlueHost}. This method by default
      * creates a VideoFragment and VideoFragmentGlueHost to host the PlaybackGlue.
-     * This method must be called after calling details Fragment super.onCreate().
+     * This method must be called after calling details Fragment super.onCreate(). This method
+     * can be called multiple times to replace existing PlaybackGlue or calling
+     * setupVideoPlayback(null) to clear. Note a typical {@link PlaybackGlue} subclass releases
+     * resources in {@link PlaybackGlue#onDetachedFromHost()}, when the {@link PlaybackGlue}
+     * subclass is not doing that, it's app's responsibility to release the resources.
      *
-     * @param playbackGlue
+     * @param playbackGlue The new PlaybackGlue to set as background or null to clear existing one.
      * @see #onCreateVideoFragment()
      * @see #onCreateGlueHost().
      */
@@ -219,15 +227,70 @@
         if (mPlaybackGlue == playbackGlue) {
             return;
         }
+        if (mPlaybackGlue != null) {
+            mPlaybackGlue.setHost(null);
+        }
         mPlaybackGlue = playbackGlue;
-        mVideoHelper = new DetailsBackgroundVideoHelper(mPlaybackGlue,
-                mFragment.getParallax(), mParallaxDrawable.getCoverDrawable());
-        if (mCanUseHost) {
+        mVideoHelper.setPlaybackGlue(mPlaybackGlue);
+        if (mCanUseHost && mPlaybackGlue != null) {
             mPlaybackGlue.setHost(onCreateGlueHost());
         }
     }
 
     /**
+     * Returns current PlaybackGlue or null if not set or cleared.
+     *
+     * @return Current PlaybackGlue or null
+     */
+    public final PlaybackGlue getPlaybackGlue() {
+        return mPlaybackGlue;
+    }
+
+    /**
+     * Precondition allows user navigate to video fragment using DPAD. Default implementation
+     * returns true if PlaybackGlue is not null. Subclass may override, e.g. only allow navigation
+     * when {@link PlaybackGlue#isReadyForPlayback()} is true. Note this method does not block
+     * app calls {@link #switchToVideo}.
+     *
+     * @return True allow to navigate to video fragment.
+     */
+    public boolean canNavigateToVideoFragment() {
+        return mPlaybackGlue != null;
+    }
+
+    void crossFadeBackgroundToVideo(boolean fadeToBackground, boolean immediate) {
+        mVideoHelper.crossFadeBackgroundToVideo(fadeToBackground, immediate);
+    }
+
+    /**
+     * Switch to video fragment, note that this method is not affected by result of
+     * {@link #canNavigateToVideoFragment()}. If the method is called in DetailsFragment.onCreate()
+     * it will make video fragment to be initially focused once it is created.
+     * <p>
+     * Calling switchToVideo() in DetailsFragment.onCreate() will clear the activity enter
+     * transition and shared element transition.
+     * </p>
+     * <p>
+     * If switchToVideo() is called after {@link DetailsFragment#prepareEntranceTransition()} and
+     * before {@link DetailsFragment#onEntranceTransitionEnd()}, it will be ignored.
+     * </p>
+     * <p>
+     * If {@link DetailsFragment#prepareEntranceTransition()} is called after switchToVideo(), an
+     * IllegalStateException will be thrown.
+     * </p>
+     */
+    public final void switchToVideo() {
+        mFragment.switchToVideo();
+    }
+
+    /**
+     * Switch to rows fragment.
+     */
+    public final void switchToRows() {
+        mFragment.switchToRows();
+    }
+
+    /**
      * When fragment is started and no running transition. First set host if not yet set, second
      * start playing if it was paused before.
      */
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
index d2e0ef2..1a74ce1 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
@@ -27,6 +27,8 @@
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.transition.TransitionListener;
+import android.support.v17.leanback.util.StateMachine.Event;
+import android.support.v17.leanback.util.StateMachine.State;
 import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
 import android.support.v17.leanback.widget.BaseOnItemViewSelectedListener;
 import android.support.v17.leanback.widget.BrowseFrameLayout;
@@ -44,6 +46,7 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 
 import java.lang.ref.WeakReference;
 
@@ -80,27 +83,200 @@
  * {@link FullWidthDetailsOverviewRowPresenter}.
  * </li>
  * </p>
+ *
+ * <p>
+ * DetailsSupportFragment can use {@link DetailsSupportFragmentBackgroundController} to add a parallax drawable
+ * background and embedded video playing fragment.
+ * </p>
  */
 public class DetailsSupportFragment extends BaseSupportFragment {
     static final String TAG = "DetailsSupportFragment";
     static boolean DEBUG = false;
 
+    final State STATE_SET_ENTRANCE_START_STATE = new State("STATE_SET_ENTRANCE_START_STATE") {
+        @Override
+        public void run() {
+            mRowsSupportFragment.setEntranceTransitionState(false);
+        }
+    };
+
+    final State STATE_ENTER_TRANSITION_INIT = new State("STATE_ENTER_TRANSIITON_INIT");
+
+    void switchToVideoBeforeVideoSupportFragmentCreated() {
+        // if the video fragment is not ready: immediately fade out covering drawable,
+        // hide title and mark mPendingFocusOnVideo and set focus on it later.
+        mDetailsBackgroundController.crossFadeBackgroundToVideo(true, true);
+        showTitle(false);
+        mPendingFocusOnVideo = true;
+        slideOutGridView();
+    }
+
+    final State STATE_SWITCH_TO_VIDEO_IN_ON_CREATE = new State("STATE_SWITCH_TO_VIDEO_IN_ON_CREATE",
+            false, false) {
+        @Override
+        public void run() {
+            switchToVideoBeforeVideoSupportFragmentCreated();
+        }
+    };
+
+    final State STATE_ENTER_TRANSITION_CANCEL = new State("STATE_ENTER_TRANSITION_CANCEL",
+            false, false) {
+        @Override
+        public void run() {
+            if (mWaitEnterTransitionTimeout != null) {
+                mWaitEnterTransitionTimeout.mRef.clear();
+            }
+            // clear the activity enter/sharedElement transition, return transitions are kept.
+            // keep the return transitions and clear enter transition
+            if (getActivity() != null) {
+                Window window = getActivity().getWindow();
+                Object returnTransition = TransitionHelper.getReturnTransition(window);
+                Object sharedReturnTransition = TransitionHelper
+                        .getSharedElementReturnTransition(window);
+                TransitionHelper.setEnterTransition(window, null);
+                TransitionHelper.setSharedElementEnterTransition(window, null);
+                TransitionHelper.setReturnTransition(window, returnTransition);
+                TransitionHelper.setSharedElementReturnTransition(window, sharedReturnTransition);
+            }
+        }
+    };
+
+    final State STATE_ENTER_TRANSITION_COMPLETE = new State("STATE_ENTER_TRANSIITON_COMPLETE",
+            true, false);
+
+    final State STATE_ENTER_TRANSITION_ADDLISTENER = new State("STATE_ENTER_TRANSITION_PENDING") {
+        @Override
+        public void run() {
+            Object transition = TransitionHelper.getEnterTransition(getActivity().getWindow());
+            TransitionHelper.addTransitionListener(transition, mEnterTransitionListener);
+        }
+    };
+
+    final State STATE_ENTER_TRANSITION_PENDING = new State("STATE_ENTER_TRANSITION_PENDING") {
+        @Override
+        public void run() {
+            if (mWaitEnterTransitionTimeout == null) {
+                new WaitEnterTransitionTimeout(DetailsSupportFragment.this);
+            }
+        }
+    };
+
     /**
-     * Flag for "possibly" having enter transition not finished yet.
-     * @see #mStartAndTransitionFlag
+     * Start this task when first DetailsOverviewRow is created, if there is no entrance transition
+     * started, it will clear PF_ENTRANCE_TRANSITION_PENDING.
      */
-    static final int PF_ENTER_TRANSITION_PENDING = 0x1 << 0;
-    /**
-     * Flag for having entrance transition not finished yet.
-     * @see #mStartAndTransitionFlag
-     */
-    static final int PF_ENTRANCE_TRANSITION_PENDING = 0x1 << 1;
-    /**
-     * Flag that onStart() has been called and about to call onSafeStart() when
-     * pending transitions are finished.
-     * @see #mStartAndTransitionFlag
-     */
-    static final int PF_PENDING_START = 0x1 << 2;
+    static class WaitEnterTransitionTimeout implements Runnable {
+        static final long WAIT_ENTERTRANSITION_START = 200;
+
+        final WeakReference<DetailsSupportFragment> mRef;
+
+        WaitEnterTransitionTimeout(DetailsSupportFragment f) {
+            mRef = new WeakReference(f);
+            f.getView().postDelayed(this, WAIT_ENTERTRANSITION_START);
+        }
+
+        @Override
+        public void run() {
+            DetailsSupportFragment f = mRef.get();
+            if (f != null) {
+                f.mStateMachine.fireEvent(f.EVT_ENTER_TRANSIITON_DONE);
+            }
+        }
+    }
+
+    final State STATE_ON_SAFE_START = new State("STATE_ON_SAFE_START") {
+        @Override
+        public void run() {
+            onSafeStart();
+        }
+    };
+
+    final Event EVT_ONSTART = new Event("onStart");
+
+    final Event EVT_NO_ENTER_TRANSITION = new Event("EVT_NO_ENTER_TRANSITION");
+
+    final Event EVT_DETAILS_ROW_LOADED = new Event("onFirstRowLoaded");
+
+    final Event EVT_ENTER_TRANSIITON_DONE = new Event("onEnterTransitionDone");
+
+    final Event EVT_SWITCH_TO_VIDEO = new Event("switchToVideo");
+
+    @Override
+    void createStateMachineStates() {
+        super.createStateMachineStates();
+        mStateMachine.addState(STATE_SET_ENTRANCE_START_STATE);
+        mStateMachine.addState(STATE_ON_SAFE_START);
+        mStateMachine.addState(STATE_SWITCH_TO_VIDEO_IN_ON_CREATE);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_INIT);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_ADDLISTENER);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_CANCEL);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_PENDING);
+        mStateMachine.addState(STATE_ENTER_TRANSITION_COMPLETE);
+    }
+
+    @Override
+    void createStateMachineTransitions() {
+        super.createStateMachineTransitions();
+        /**
+         * Part 1: Processing enter transitions after fragment.onCreate
+         */
+        mStateMachine.addTransition(STATE_START, STATE_ENTER_TRANSITION_INIT, EVT_ON_CREATE);
+        // if transition is not supported, skip to complete
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_INIT, STATE_ENTER_TRANSITION_COMPLETE,
+                COND_TRANSITION_NOT_SUPPORTED);
+        // if transition is not set on Activity, skip to complete
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_INIT, STATE_ENTER_TRANSITION_COMPLETE,
+                EVT_NO_ENTER_TRANSITION);
+        // if switchToVideo is called before EVT_ON_CREATEVIEW, clear enter transition and skip to
+        // complete.
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_INIT, STATE_ENTER_TRANSITION_CANCEL,
+                EVT_SWITCH_TO_VIDEO);
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_CANCEL, STATE_ENTER_TRANSITION_COMPLETE);
+        // once after onCreateView, we cannot skip the enter transition, add a listener and wait
+        // it to finish
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_INIT, STATE_ENTER_TRANSITION_ADDLISTENER,
+                EVT_ON_CREATEVIEW);
+        // when enter transition finishes, go to complete, however this might never happen if
+        // the activity is not giving transition options in startActivity, there is no API to query
+        // if this activity is started in a enter transition mode. So we rely on a timer below:
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_ADDLISTENER,
+                STATE_ENTER_TRANSITION_COMPLETE, EVT_ENTER_TRANSIITON_DONE);
+        // we are expecting app to start delayed enter transition shortly after details row is
+        // loaded, so create a timer and wait for enter transition start.
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_ADDLISTENER,
+                STATE_ENTER_TRANSITION_PENDING, EVT_DETAILS_ROW_LOADED);
+        // if enter transition not started in the timer, skip to DONE, this can be also true when
+        // startActivity is not giving transition option.
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_PENDING, STATE_ENTER_TRANSITION_COMPLETE,
+                EVT_ENTER_TRANSIITON_DONE);
+
+        /**
+         * Part 2: modification to the entrance transition defined in BaseSupportFragment
+         */
+        // Must finish enter transition before perform entrance transition.
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_COMPLETE, STATE_ENTRANCE_PERFORM);
+        // Calling switch to video would hide immediately and skip entrance transition
+        mStateMachine.addTransition(STATE_ENTRANCE_INIT, STATE_SWITCH_TO_VIDEO_IN_ON_CREATE,
+                EVT_SWITCH_TO_VIDEO);
+        mStateMachine.addTransition(STATE_SWITCH_TO_VIDEO_IN_ON_CREATE, STATE_ENTRANCE_COMPLETE);
+        // if the entrance transition is skipped to complete by COND_TRANSITION_NOT_SUPPORTED, we
+        // still need to do the switchToVideo.
+        mStateMachine.addTransition(STATE_ENTRANCE_COMPLETE, STATE_SWITCH_TO_VIDEO_IN_ON_CREATE,
+                EVT_SWITCH_TO_VIDEO);
+
+        // for once the view is created in onStart and prepareEntranceTransition was called, we
+        // could setEntranceStartState:
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_SET_ENTRANCE_START_STATE, EVT_ONSTART);
+
+        /**
+         * Part 3: onSafeStart()
+         */
+        // for onSafeStart: the condition is onStart called, entrance transition complete
+        mStateMachine.addTransition(STATE_START, STATE_ON_SAFE_START, EVT_ONSTART);
+        mStateMachine.addTransition(STATE_ENTRANCE_COMPLETE, STATE_ON_SAFE_START);
+        mStateMachine.addTransition(STATE_ENTER_TRANSITION_COMPLETE, STATE_ON_SAFE_START);
+    }
 
     private class SetSelectionRunnable implements Runnable {
         int mPosition;
@@ -118,33 +294,6 @@
         }
     }
 
-    /**
-     * Start this task when first DetailsOverviewRow is created, if there is no entrance transition
-     * started, it will clear PF_ENTRANCE_TRANSITION_PENDING.
-     * @see #mStartAndTransitionFlag
-     */
-    static class WaitEnterTransitionTimeout implements Runnable {
-        static final long WAIT_ENTERTRANSITION_START = 200;
-
-        final WeakReference<DetailsSupportFragment> mRef;
-
-        WaitEnterTransitionTimeout(DetailsSupportFragment f) {
-            mRef = new WeakReference(f);
-            f.getView().postDelayed(this, WAIT_ENTERTRANSITION_START);
-        }
-
-        @Override
-        public void run() {
-            DetailsSupportFragment f = mRef.get();
-            if (f != null) {
-                f.clearPendingEnterTransition();
-            }
-        }
-    }
-
-    /**
-     * @see #mStartAndTransitionFlag
-     */
     TransitionListener mEnterTransitionListener = new TransitionListener() {
         @Override
         public void onTransitionStart(Object transition) {
@@ -157,12 +306,12 @@
 
         @Override
         public void onTransitionCancel(Object transition) {
-            clearPendingEnterTransition();
+            mStateMachine.fireEvent(EVT_ENTER_TRANSIITON_DONE);
         }
 
         @Override
         public void onTransitionEnd(Object transition) {
-            clearPendingEnterTransition();
+            mStateMachine.fireEvent(EVT_ENTER_TRANSIITON_DONE);
         }
     };
 
@@ -185,23 +334,10 @@
     BaseOnItemViewClickedListener mOnItemViewClickedListener;
     DetailsSupportFragmentBackgroundController mDetailsBackgroundController;
 
+    // A temporarily flag when switchToVideo() is called in onCreate(), if mPendingFocusOnVideo is
+    // true, we will focus to VideoSupportFragment immediately after video fragment's view is created.
+    boolean mPendingFocusOnVideo = false;
 
-    /**
-     * Flags for enter transition, entrance transition and onStart.  When onStart() is called
-     * and both enter transiton and entrance transition are finished, we could call onSafeStart().
-     * 1. in onCreate:
-     *      if user call prepareEntranceTransition, set PF_ENTRANCE_TRANSITION_PENDING
-     *      if there is enterTransition, set PF_ENTER_TRANSITION_PENDING, but we dont know if
-     *      user will run enterTransition or not.
-     * 2. when user add row, start WaitEnterTransitionTimeout to wait possible enter transition
-     * start. If enter transition onTransitionStart is not invoked with a period, we can assume
-     * there is no enter transition running, then WaitEnterTransitionTimeout will clear
-     * PF_ENTER_TRANSITION_PENDING.
-     * 3. When enterTransition runs (either postponed or not),  we will stop the
-     * WaitEnterTransitionTimeout, and let onTransitionEnd/onTransitionCancel to clear
-     * PF_ENTER_TRANSITION_PENDING.
-     */
-    int mStartAndTransitionFlag = 0;
     WaitEnterTransitionTimeout mWaitEnterTransitionTimeout;
 
     Object mSceneAfterEntranceTransition;
@@ -285,14 +421,15 @@
         FragmentActivity activity = getActivity();
         if (activity != null) {
             Object transition = TransitionHelper.getEnterTransition(activity.getWindow());
-            if (transition != null) {
-                mStartAndTransitionFlag |= PF_ENTER_TRANSITION_PENDING;
-                TransitionHelper.addTransitionListener(transition, mEnterTransitionListener);
+            if (transition == null) {
+                mStateMachine.fireEvent(EVT_NO_ENTER_TRANSITION);
             }
             transition = TransitionHelper.getReturnTransition(activity.getWindow());
             if (transition != null) {
                 TransitionHelper.addTransitionListener(transition, mReturnTransitionListener);
             }
+        } else {
+            mStateMachine.fireEvent(EVT_NO_ENTER_TRANSITION);
         }
     }
 
@@ -447,6 +584,22 @@
         }
     }
 
+    void switchToVideo() {
+        if (mVideoSupportFragment != null && mVideoSupportFragment.getView() != null) {
+            mVideoSupportFragment.getView().requestFocus();
+        } else {
+            mStateMachine.fireEvent(EVT_SWITCH_TO_VIDEO);
+        }
+    }
+
+    void switchToRows() {
+        mPendingFocusOnVideo = false;
+        VerticalGridView verticalGridView = getVerticalGridView();
+        if (verticalGridView != null && verticalGridView.getChildCount() > 0) {
+            verticalGridView.requestFocus();
+        }
+    }
+
     /**
      * This method asks DetailsSupportFragmentBackgroundController to add a fragment for rendering video.
      * In case the fragment is already there, it will return the existing one. The method must be
@@ -463,6 +616,18 @@
             ft2.add(android.support.v17.leanback.R.id.video_surface_container,
                     fragment = mDetailsBackgroundController.onCreateVideoSupportFragment());
             ft2.commit();
+            if (mPendingFocusOnVideo) {
+                // wait next cycle for Fragment view created so we can focus on it.
+                // This is a bit hack eventually we will do commitNow() which get view immediately.
+                getView().post(new Runnable() {
+                    public void run() {
+                        if (getView() != null) {
+                            switchToVideo();
+                        }
+                        mPendingFocusOnVideo = false;
+                    }
+                });
+            }
         }
         mVideoSupportFragment = fragment;
         return mVideoSupportFragment;
@@ -471,7 +636,7 @@
     void onRowSelected(int selectedPosition, int selectedSubPosition) {
         ObjectAdapter adapter = getAdapter();
         if (( mRowsSupportFragment != null && mRowsSupportFragment.getView() != null
-                && mRowsSupportFragment.getView().hasFocus())
+                && mRowsSupportFragment.getView().hasFocus() && !mPendingFocusOnVideo)
                 && (adapter == null || adapter.size() == 0
                 || (getVerticalGridView().getSelectedPosition() == 0
                 && getVerticalGridView().getSelectedSubPosition() == 0))) {
@@ -482,10 +647,8 @@
         if (adapter != null && adapter.size() > selectedPosition) {
             final VerticalGridView gridView = getVerticalGridView();
             final int count = gridView.getChildCount();
-            if (count > 0 && (mStartAndTransitionFlag & PF_ENTER_TRANSITION_PENDING) != 0) {
-                if (mWaitEnterTransitionTimeout == null) {
-                    mWaitEnterTransitionTimeout = new WaitEnterTransitionTimeout(this);
-                }
+            if (count > 0) {
+                mStateMachine.fireEvent(EVT_DETAILS_ROW_LOADED);
             }
             for (int i = 0; i < count; i++) {
                 ItemBridgeAdapter.ViewHolder bridgeViewHolder = (ItemBridgeAdapter.ViewHolder)
@@ -499,25 +662,6 @@
         }
     }
 
-    void clearPendingEnterTransition() {
-        if ((mStartAndTransitionFlag & PF_ENTER_TRANSITION_PENDING) != 0) {
-            mStartAndTransitionFlag &= ~PF_ENTER_TRANSITION_PENDING;
-            dispatchOnStartAndTransitionFinished();
-        }
-    }
-
-    void dispatchOnStartAndTransitionFinished() {
-        /**
-         * if onStart() was called and there is no pending enter transition or entrance transition.
-         */
-        if ((mStartAndTransitionFlag & PF_PENDING_START) != 0
-                && (mStartAndTransitionFlag
-                & (PF_ENTER_TRANSITION_PENDING | PF_ENTRANCE_TRANSITION_PENDING)) == 0) {
-            mStartAndTransitionFlag &= ~PF_PENDING_START;
-            onSafeStart();
-        }
-    }
-
     /**
      * Called when onStart and enter transition (postponed/none postponed) and entrance transition
      * are all finished.
@@ -612,17 +756,16 @@
     public void onStart() {
         super.onStart();
 
-        mStartAndTransitionFlag |= PF_PENDING_START;
-        dispatchOnStartAndTransitionFinished();
-
         setupChildFragmentLayout();
-        if (isEntranceTransitionEnabled()) {
-            mRowsSupportFragment.setEntranceTransitionState(false);
-        }
+        mStateMachine.fireEvent(EVT_ONSTART);
         if (mDetailsParallax != null) {
             mDetailsParallax.setRecyclerView(mRowsSupportFragment.getVerticalGridView());
         }
-        mRowsSupportFragment.getVerticalGridView().requestFocus();
+        if (mPendingFocusOnVideo) {
+            slideOutGridView();
+        } else if (!getView().hasFocus()) {
+            mRowsSupportFragment.getVerticalGridView().requestFocus();
+        }
     }
 
     @Override
@@ -638,14 +781,11 @@
 
     @Override
     protected void onEntranceTransitionEnd() {
-        mStartAndTransitionFlag &= ~PF_ENTRANCE_TRANSITION_PENDING;
-        dispatchOnStartAndTransitionFinished();
         mRowsSupportFragment.onTransitionEnd();
     }
 
     @Override
     protected void onEntranceTransitionPrepare() {
-        mStartAndTransitionFlag |= PF_ENTRANCE_TRANSITION_PENDING;
         mRowsSupportFragment.onTransitionPrepare();
     }
 
@@ -707,7 +847,10 @@
             public void onRequestChildFocus(View child, View focused) {
                 if (child != mRootView.getFocusedChild()) {
                     if (child.getId() == R.id.details_fragment_root) {
-                        showTitle(true);
+                        if (!mPendingFocusOnVideo) {
+                            slideInGridView();
+                            showTitle(true);
+                        }
                     } else if (child.getId() == R.id.video_surface_container) {
                         slideOutGridView();
                         showTitle(false);
@@ -723,19 +866,14 @@
                 if (mRowsSupportFragment.getVerticalGridView() != null
                         && mRowsSupportFragment.getVerticalGridView().hasFocus()) {
                     if (direction == View.FOCUS_UP) {
-                        if (mVideoSupportFragment != null && mVideoSupportFragment.getView() != null) {
+                        if (mDetailsBackgroundController != null
+                                && mDetailsBackgroundController.canNavigateToVideoSupportFragment()
+                                && mVideoSupportFragment != null && mVideoSupportFragment.getView() != null) {
                             return mVideoSupportFragment.getView();
                         } else if (getTitleView() != null && getTitleView().hasFocusable()) {
                             return getTitleView();
                         }
                     }
-                } else if (mVideoSupportFragment != null && mVideoSupportFragment.getView() != null
-                        && mVideoSupportFragment.getView().hasFocus()) {
-                    if (direction == View.FOCUS_DOWN) {
-                        if (mRowsSupportFragment.getVerticalGridView() != null) {
-                            return mRowsSupportFragment.getVerticalGridView();
-                        }
-                    }
                 } else if (getTitleView() != null && getTitleView().hasFocus()) {
                     if (direction == View.FOCUS_DOWN) {
                         if (mRowsSupportFragment.getVerticalGridView() != null) {
@@ -758,8 +896,10 @@
                 if (mVideoSupportFragment != null && mVideoSupportFragment.getView() != null
                         && mVideoSupportFragment.getView().hasFocus()) {
                     if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_ESCAPE) {
-                        getVerticalGridView().requestFocus();
-                        return true;
+                        if (getVerticalGridView().getChildCount() > 0) {
+                            getVerticalGridView().requestFocus();
+                            return true;
+                        }
                     }
                 }
 
@@ -777,4 +917,9 @@
         }
     }
 
+    void slideInGridView() {
+        if (getVerticalGridView() != null) {
+            getVerticalGridView().animateIn();
+        }
+    }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragmentBackgroundController.java b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragmentBackgroundController.java
index 071a04a..763b84f2 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragmentBackgroundController.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragmentBackgroundController.java
@@ -110,14 +110,14 @@
  */
 public class DetailsSupportFragmentBackgroundController {
 
-    private final DetailsSupportFragment mFragment;
-    private DetailsParallaxDrawable mParallaxDrawable;
-    private int mParallaxDrawableMaxOffset;
-    private PlaybackGlue mPlaybackGlue;
-    private DetailsBackgroundVideoHelper mVideoHelper;
-    private Bitmap mCoverBitmap;
-    private int mSolidColor;
-    private boolean mCanUseHost = false;
+    final DetailsSupportFragment mFragment;
+    DetailsParallaxDrawable mParallaxDrawable;
+    int mParallaxDrawableMaxOffset;
+    PlaybackGlue mPlaybackGlue;
+    DetailsBackgroundVideoHelper mVideoHelper;
+    Bitmap mCoverBitmap;
+    int mSolidColor;
+    boolean mCanUseHost = false;
 
     /**
      * Creates a DetailsSupportFragmentBackgroundController for a DetailsSupportFragment. Note that
@@ -207,14 +207,22 @@
                 bottomDrawable,
                 coverDrawableParallaxTarget);
         mFragment.setBackgroundDrawable(mParallaxDrawable);
+        // create a VideoHelper with null PlaybackGlue for changing CoverDrawable visibility
+        // before PlaybackGlue is ready.
+        mVideoHelper = new DetailsBackgroundVideoHelper(null,
+                mFragment.getParallax(), mParallaxDrawable.getCoverDrawable());
     }
 
     /**
      * Enable video playback and set proper {@link PlaybackGlueHost}. This method by default
      * creates a VideoSupportFragment and VideoSupportFragmentGlueHost to host the PlaybackGlue.
-     * This method must be called after calling details Fragment super.onCreate().
+     * This method must be called after calling details Fragment super.onCreate(). This method
+     * can be called multiple times to replace existing PlaybackGlue or calling
+     * setupVideoPlayback(null) to clear. Note a typical {@link PlaybackGlue} subclass releases
+     * resources in {@link PlaybackGlue#onDetachedFromHost()}, when the {@link PlaybackGlue}
+     * subclass is not doing that, it's app's responsibility to release the resources.
      *
-     * @param playbackGlue
+     * @param playbackGlue The new PlaybackGlue to set as background or null to clear existing one.
      * @see #onCreateVideoSupportFragment()
      * @see #onCreateGlueHost().
      */
@@ -222,15 +230,70 @@
         if (mPlaybackGlue == playbackGlue) {
             return;
         }
+        if (mPlaybackGlue != null) {
+            mPlaybackGlue.setHost(null);
+        }
         mPlaybackGlue = playbackGlue;
-        mVideoHelper = new DetailsBackgroundVideoHelper(mPlaybackGlue,
-                mFragment.getParallax(), mParallaxDrawable.getCoverDrawable());
-        if (mCanUseHost) {
+        mVideoHelper.setPlaybackGlue(mPlaybackGlue);
+        if (mCanUseHost && mPlaybackGlue != null) {
             mPlaybackGlue.setHost(onCreateGlueHost());
         }
     }
 
     /**
+     * Returns current PlaybackGlue or null if not set or cleared.
+     *
+     * @return Current PlaybackGlue or null
+     */
+    public final PlaybackGlue getPlaybackGlue() {
+        return mPlaybackGlue;
+    }
+
+    /**
+     * Precondition allows user navigate to video fragment using DPAD. Default implementation
+     * returns true if PlaybackGlue is not null. Subclass may override, e.g. only allow navigation
+     * when {@link PlaybackGlue#isReadyForPlayback()} is true. Note this method does not block
+     * app calls {@link #switchToVideo}.
+     *
+     * @return True allow to navigate to video fragment.
+     */
+    public boolean canNavigateToVideoSupportFragment() {
+        return mPlaybackGlue != null;
+    }
+
+    void crossFadeBackgroundToVideo(boolean fadeToBackground, boolean immediate) {
+        mVideoHelper.crossFadeBackgroundToVideo(fadeToBackground, immediate);
+    }
+
+    /**
+     * Switch to video fragment, note that this method is not affected by result of
+     * {@link #canNavigateToVideoSupportFragment()}. If the method is called in DetailsSupportFragment.onCreate()
+     * it will make video fragment to be initially focused once it is created.
+     * <p>
+     * Calling switchToVideo() in DetailsSupportFragment.onCreate() will clear the activity enter
+     * transition and shared element transition.
+     * </p>
+     * <p>
+     * If switchToVideo() is called after {@link DetailsSupportFragment#prepareEntranceTransition()} and
+     * before {@link DetailsSupportFragment#onEntranceTransitionEnd()}, it will be ignored.
+     * </p>
+     * <p>
+     * If {@link DetailsSupportFragment#prepareEntranceTransition()} is called after switchToVideo(), an
+     * IllegalStateException will be thrown.
+     * </p>
+     */
+    public final void switchToVideo() {
+        mFragment.switchToVideo();
+    }
+
+    /**
+     * Switch to rows fragment.
+     */
+    public final void switchToRows() {
+        mFragment.switchToRows();
+    }
+
+    /**
      * When fragment is started and no running transition. First set host if not yet set, second
      * start playing if it was paused before.
      */
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..df83ae9 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
@@ -179,7 +179,7 @@
     // No need to save/restore the logo resource ID, because the logo animation will not appear when
     // the fragment is restored.
     private int mLogoResourceId;
-    boolean mEnterTransitionFinished;
+    boolean mLogoAnimationFinished;
     int mCurrentPageIndex;
 
     private AnimatorSet mAnimator;
@@ -187,7 +187,7 @@
     private final OnClickListener mOnClickListener = new OnClickListener() {
         @Override
         public void onClick(View view) {
-            if (!mEnterTransitionFinished) {
+            if (!mLogoAnimationFinished) {
                 // Do not change page until the enter transition finishes.
                 return;
             }
@@ -202,7 +202,7 @@
     private final OnKeyListener mOnKeyListener = new OnKeyListener() {
         @Override
         public boolean onKey(View v, int keyCode, KeyEvent event) {
-            if (!mEnterTransitionFinished) {
+            if (!mLogoAnimationFinished) {
                 // Ignore key event until the enter transition finishes.
                 return keyCode != KeyEvent.KEYCODE_BACK;
             }
@@ -235,13 +235,28 @@
         }
     };
 
-    void moveToPreviousPage() {
+    /**
+     * Navigates to the previous page.
+     */
+    protected void moveToPreviousPage() {
+        if (!mLogoAnimationFinished) {
+            // Ignore if the logo enter transition is in progress.
+            return;
+        }
         if (mCurrentPageIndex > 0) {
             --mCurrentPageIndex;
             onPageChangedInternal(mCurrentPageIndex + 1);
         }
     }
-    void moveToNextPage() {
+
+    /**
+     * Navigates to the next page.
+     */
+    protected void moveToNextPage() {
+        if (!mLogoAnimationFinished) {
+            // Ignore if the logo enter transition is in progress.
+            return;
+        }
         if (mCurrentPageIndex < getPageCount() - 1) {
             ++mCurrentPageIndex;
             onPageChangedInternal(mCurrentPageIndex - 1);
@@ -274,7 +289,7 @@
         }
         if (savedInstanceState == null) {
             mCurrentPageIndex = 0;
-            mEnterTransitionFinished = false;
+            mLogoAnimationFinished = false;
             mPageIndicator.onPageSelected(0, false);
             view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
                 @Override
@@ -287,7 +302,7 @@
                 }
             });
         } else {
-            mEnterTransitionFinished = true;
+            mLogoAnimationFinished = true;
             mCurrentPageIndex = savedInstanceState.getInt(KEY_CURRENT_PAGE_INDEX);
             initializeViews(view);
         }
@@ -450,10 +465,19 @@
         // Header views.
         mTitleView.setText(getPageTitle(mCurrentPageIndex));
         mDescriptionView.setText(getPageDescription(mCurrentPageIndex));
+        onLogoAnimationFinished();
+    }
+
+    /**
+     * Called immediately after fragment views become visible. This method gives subclasses a chance
+     * to initialize themselves. If a logo animation is specified, calling this method is delayed
+     * until after the logo animation is complete.
+     */
+    protected void onLogoAnimationFinished() {
     }
 
     void startEnterAnimation() {
-        mEnterTransitionFinished = true;
+        mLogoAnimationFinished = true;
         initializeViews(getView());
         List<Animator> animators = new ArrayList<>();
         final Context context = FragmentUtil.getContext(this);
@@ -490,6 +514,15 @@
     }
 
     /**
+     * Returns whether the logo enter transition is finished.
+     *
+     * @return {@code true} if the logo enter transition is finished, {@code false} otherwise
+     */
+    protected final boolean isLogoAnimationFinished() {
+        return mLogoAnimationFinished;
+    }
+
+    /**
      * Returns the page count.
      *
      * @return The page count.
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..2c43ed8 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
@@ -182,7 +182,7 @@
     // No need to save/restore the logo resource ID, because the logo animation will not appear when
     // the fragment is restored.
     private int mLogoResourceId;
-    boolean mEnterTransitionFinished;
+    boolean mLogoAnimationFinished;
     int mCurrentPageIndex;
 
     private AnimatorSet mAnimator;
@@ -190,7 +190,7 @@
     private final OnClickListener mOnClickListener = new OnClickListener() {
         @Override
         public void onClick(View view) {
-            if (!mEnterTransitionFinished) {
+            if (!mLogoAnimationFinished) {
                 // Do not change page until the enter transition finishes.
                 return;
             }
@@ -205,7 +205,7 @@
     private final OnKeyListener mOnKeyListener = new OnKeyListener() {
         @Override
         public boolean onKey(View v, int keyCode, KeyEvent event) {
-            if (!mEnterTransitionFinished) {
+            if (!mLogoAnimationFinished) {
                 // Ignore key event until the enter transition finishes.
                 return keyCode != KeyEvent.KEYCODE_BACK;
             }
@@ -238,13 +238,28 @@
         }
     };
 
-    void moveToPreviousPage() {
+    /**
+     * Navigates to the previous page.
+     */
+    protected void moveToPreviousPage() {
+        if (!mLogoAnimationFinished) {
+            // Ignore if the logo enter transition is in progress.
+            return;
+        }
         if (mCurrentPageIndex > 0) {
             --mCurrentPageIndex;
             onPageChangedInternal(mCurrentPageIndex + 1);
         }
     }
-    void moveToNextPage() {
+
+    /**
+     * Navigates to the next page.
+     */
+    protected void moveToNextPage() {
+        if (!mLogoAnimationFinished) {
+            // Ignore if the logo enter transition is in progress.
+            return;
+        }
         if (mCurrentPageIndex < getPageCount() - 1) {
             ++mCurrentPageIndex;
             onPageChangedInternal(mCurrentPageIndex - 1);
@@ -277,7 +292,7 @@
         }
         if (savedInstanceState == null) {
             mCurrentPageIndex = 0;
-            mEnterTransitionFinished = false;
+            mLogoAnimationFinished = false;
             mPageIndicator.onPageSelected(0, false);
             view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
                 @Override
@@ -290,7 +305,7 @@
                 }
             });
         } else {
-            mEnterTransitionFinished = true;
+            mLogoAnimationFinished = true;
             mCurrentPageIndex = savedInstanceState.getInt(KEY_CURRENT_PAGE_INDEX);
             initializeViews(view);
         }
@@ -453,10 +468,19 @@
         // Header views.
         mTitleView.setText(getPageTitle(mCurrentPageIndex));
         mDescriptionView.setText(getPageDescription(mCurrentPageIndex));
+        onLogoAnimationFinished();
+    }
+
+    /**
+     * Called immediately after fragment views become visible. This method gives subclasses a chance
+     * to initialize themselves. If a logo animation is specified, calling this method is delayed
+     * until after the logo animation is complete.
+     */
+    protected void onLogoAnimationFinished() {
     }
 
     void startEnterAnimation() {
-        mEnterTransitionFinished = true;
+        mLogoAnimationFinished = true;
         initializeViews(getView());
         List<Animator> animators = new ArrayList<>();
         final Context context = getContext();
@@ -493,6 +517,15 @@
     }
 
     /**
+     * Returns whether the logo enter transition is finished.
+     *
+     * @return {@code true} if the logo enter transition is finished, {@code false} otherwise
+     */
+    protected final boolean isLogoAnimationFinished() {
+        return mLogoAnimationFinished;
+    }
+
+    /**
      * Returns the page count.
      *
      * @return The page count.
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
index 8d6367a..60cd06b 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackFragment.java
@@ -33,6 +33,7 @@
 import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
 import android.support.v17.leanback.widget.BaseOnItemViewSelectedListener;
 import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.ItemAlignmentFacet;
 import android.support.v17.leanback.widget.ItemBridgeAdapter;
 import android.support.v17.leanback.widget.ObjectAdapter;
 import android.support.v17.leanback.widget.PlaybackRowPresenter;
@@ -40,6 +41,7 @@
 import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.Row;
 import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
 import android.support.v17.leanback.widget.VerticalGridView;
 import android.support.v7.widget.RecyclerView;
 import android.util.Log;
@@ -62,8 +64,12 @@
  * of {@link RowPresenter}.
  * </p>
  * <p>
- * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
- * at position 0 in the adapter.
+ * A playback row is a row rendered by {@link PlaybackRowPresenter}.
+ * App can call {@link #setPlaybackRow(Row)} to set playback row for the first element of adapter.
+ * App can call {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} to set presenter for it.
+ * {@link #setPlaybackRow(Row)} and {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} are
+ * optional, app can pass playback row and PlaybackRowPresenter in the adapter using
+ * {@link #setAdapter(ObjectAdapter)}.
  * </p>
  */
 public class PlaybackFragment extends Fragment {
@@ -76,7 +82,7 @@
      * A dark translucent background.
      */
     public static final int BG_DARK = 1;
-    private PlaybackGlueHost.HostCallback mHostCallback;
+    PlaybackGlueHost.HostCallback mHostCallback;
 
     /**
      * Resets the focus on the button in the middle of control row.
@@ -108,13 +114,13 @@
      * A light translucent background.
      */
     public static final int BG_LIGHT = 2;
-    private RowsFragment mRowsFragment;
-    private ObjectAdapter mAdapter;
-    private PlaybackRowPresenter mPresenter;
-    private Row mRow;
-    private BaseOnItemViewSelectedListener mExternalItemSelectedListener;
-    private BaseOnItemViewClickedListener mExternalItemClickedListener;
-    private BaseOnItemViewClickedListener mPlaybackItemClickedListener;
+    RowsFragment mRowsFragment;
+    ObjectAdapter mAdapter;
+    PlaybackRowPresenter mPresenter;
+    Row mRow;
+    BaseOnItemViewSelectedListener mExternalItemSelectedListener;
+    BaseOnItemViewClickedListener mExternalItemClickedListener;
+    BaseOnItemViewClickedListener mPlaybackItemClickedListener;
 
     private final BaseOnItemViewClickedListener mOnItemViewClickedListener =
             new BaseOnItemViewClickedListener() {
@@ -179,23 +185,23 @@
     private static final int IN = 1;
     private static final int OUT = 2;
 
-    private int mPaddingTop;
-    private int mPaddingBottom;
-    private View mRootView;
-    private int mBackgroundType = BG_DARK;
-    private int mBgDarkColor;
-    private int mBgLightColor;
-    private int mShowTimeMs;
-    private int mMajorFadeTranslateY, mMinorFadeTranslateY;
-    private int mAnimationTranslateY;
-    private OnFadeCompleteListener mFadeCompleteListener;
-    private View.OnKeyListener mInputEventHandler;
-    private boolean mFadingEnabled = true;
-    private int mFadingStatus = IDLE;
-    private int mBgAlpha;
-    private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
-    private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
-    private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
+    int mPaddingBottom;
+    int mOtherRowsCenterToBottom;
+    View mRootView;
+    int mBackgroundType = BG_DARK;
+    int mBgDarkColor;
+    int mBgLightColor;
+    int mShowTimeMs;
+    int mMajorFadeTranslateY, mMinorFadeTranslateY;
+    int mAnimationTranslateY;
+    OnFadeCompleteListener mFadeCompleteListener;
+    View.OnKeyListener mInputEventHandler;
+    boolean mFadingEnabled = true;
+    int mFadingStatus = IDLE;
+    int mBgAlpha;
+    ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
+    ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
+    ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
 
     private final Animator.AnimatorListener mFadeListener =
             new Animator.AnimatorListener() {
@@ -594,6 +600,8 @@
                 mOtherRowFadeInAnimator.reverse();
             }
         }
+        getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
+                : R.string.lb_playback_controls_hidden));
 
         // If fading in while control row is focused, set initial translationY so
         // views slide in from below.
@@ -633,31 +641,30 @@
         if (listview == null) {
             return;
         }
-        // Padding affects alignment when last row is focused
-        // (last is first when there's only one row).
-        setPadding(listview, mPaddingTop, mPaddingBottom);
 
-        // Item alignment affects focused row that isn't the last.
-        listview.setItemAlignmentOffset(0);
+        // we set the base line of alignment to -paddingBottom
+        listview.setWindowAlignmentOffset(-mPaddingBottom);
+        listview.setWindowAlignmentOffsetPercent(
+                VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
+
+        // align other rows that arent the last to center of screen, since our baseline is
+        // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
+        listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
         listview.setItemAlignmentOffsetPercent(50);
 
-        // Push rows to the bottom.
-        listview.setWindowAlignmentOffset(0);
-        listview.setWindowAlignmentOffsetPercent(50);
-        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
-    }
-
-    private static void setPadding(View view, int paddingTop, int paddingBottom) {
-        view.setPadding(view.getPaddingLeft(), paddingTop,
-                view.getPaddingRight(), paddingBottom);
+        // Push last row to the bottom padding
+        // Padding affects alignment when last row is focused
+        listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
+                listview.getPaddingRight(), mPaddingBottom);
+        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
     }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mPaddingTop =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top);
+        mOtherRowsCenterToBottom = getResources()
+                .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
         mPaddingBottom =
                 getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
         mBgDarkColor =
@@ -844,7 +851,9 @@
     }
 
     /**
-     * Sets the playback row for the playback controls.
+     * Sets the playback row for the playback controls. The row will be set as first element
+     * of adapter if the adapter is {@link ArrayObjectAdapter} or {@link SparseArrayObjectAdapter}.
+     * @param row The row that represents the playback.
      */
     public void setPlaybackRow(Row row) {
         this.mRow = row;
@@ -853,11 +862,38 @@
     }
 
     /**
-     * Sets the presenter for rendering the playback controls.
+     * Sets the presenter for rendering the playback row set by {@link #setPlaybackRow(Row)}. If
+     * adapter does not set a {@link PresenterSelector}, {@link #setAdapter(ObjectAdapter)} will
+     * create a {@link ClassPresenterSelector} by default and map from the row object class to this
+     * {@link PlaybackRowPresenter}.
+     *
+     * @param  presenter Presenter used to render {@link #setPlaybackRow(Row)}.
      */
     public void setPlaybackRowPresenter(PlaybackRowPresenter presenter) {
         this.mPresenter = presenter;
         setupPresenter();
+        setPlaybackRowPresenterAlignment();
+    }
+
+    void setPlaybackRowPresenterAlignment() {
+        if (mAdapter != null && mAdapter.getPresenterSelector() != null) {
+            Presenter[] presenters = mAdapter.getPresenterSelector().getPresenters();
+            if (presenters != null) {
+                for (int i = 0; i < presenters.length; i++) {
+                    if (presenters[i] instanceof PlaybackRowPresenter
+                            && presenters[i].getFacet(ItemAlignmentFacet.class) == null) {
+                        ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
+                        ItemAlignmentFacet.ItemAlignmentDef def =
+                                new ItemAlignmentFacet.ItemAlignmentDef();
+                        def.setItemAlignmentOffset(0);
+                        def.setItemAlignmentOffsetPercent(100);
+                        itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
+                                {def});
+                        presenters[i].setFacet(ItemAlignmentFacet.class, itemAlignment);
+                    }
+                }
+            }
+        }
     }
 
     /**
@@ -871,12 +907,19 @@
     }
 
     /**
-     * Sets the list of rows for the fragment.
+     * Sets the list of rows for the fragment. A default {@link ClassPresenterSelector} will be
+     * created if {@link ObjectAdapter#getPresenterSelector()} is null. if user provides
+     * {@link #setPlaybackRow(Row)} and {@link #setPlaybackRowPresenter(PlaybackRowPresenter)},
+     * the row and presenter will be set onto the adapter.
+     *
+     * @param adapter The adapter that contains related rows and optional playback row.
      */
     public void setAdapter(ObjectAdapter adapter) {
         mAdapter = adapter;
         setupRow();
         setupPresenter();
+        setPlaybackRowPresenterAlignment();
+
         if (mRowsFragment != null) {
             mRowsFragment.setAdapter(adapter);
         }
@@ -890,6 +933,9 @@
             } else {
                 adapter.replace(0, mRow);
             }
+        } else if (mAdapter instanceof SparseArrayObjectAdapter && mRow != null) {
+            SparseArrayObjectAdapter adapter = ((SparseArrayObjectAdapter) mAdapter);
+            adapter.set(0, mRow);
         }
     }
 
@@ -898,10 +944,9 @@
             PresenterSelector selector = mAdapter.getPresenterSelector();
             if (selector == null) {
                 selector = new ClassPresenterSelector();
+                ((ClassPresenterSelector) selector).addClassPresenter(mRow.getClass(), mPresenter);
                 mAdapter.setPresenterSelector(selector);
-            }
-
-            if (selector instanceof ClassPresenterSelector) {
+            } else if (selector instanceof ClassPresenterSelector) {
                 ((ClassPresenterSelector) selector).addClassPresenter(mRow.getClass(), mPresenter);
             }
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
index c601b2e..c934f6b 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
@@ -28,10 +28,12 @@
 import android.support.v17.leanback.animation.LogAccelerateInterpolator;
 import android.support.v17.leanback.animation.LogDecelerateInterpolator;
 import android.support.v17.leanback.media.PlaybackGlueHost;
+import android.support.v17.leanback.widget.ItemAlignmentFacet;
 import android.support.v17.leanback.widget.ItemBridgeAdapter;
 import android.support.v17.leanback.widget.ObjectAdapter;
 import android.support.v17.leanback.widget.ObjectAdapter.DataObserver;
 import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.PlaybackRowPresenter;
 import android.support.v17.leanback.widget.Presenter;
 import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.RowPresenter;
@@ -105,7 +107,7 @@
     private static final int IN = 1;
     static final int OUT = 2;
 
-    private int mPaddingTop;
+    private int mOtherRowsCenterToBottom;
     private int mPaddingBottom;
     private View mRootView;
     private int mBackgroundType = BG_DARK;
@@ -610,6 +612,8 @@
                 mDescriptionFadeInAnimator.reverse();
             }
         }
+        getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
+                : R.string.lb_playback_controls_hidden));
 
         // If fading in while control row is focused, set initial translationY so
         // views slide in from below.
@@ -638,35 +642,52 @@
     }
 
     @Override
+    protected void setupPresenter(Presenter rowPresenter) {
+        if (rowPresenter instanceof PlaybackRowPresenter) {
+            if (rowPresenter.getFacet(ItemAlignmentFacet.class) == null) {
+                ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
+                ItemAlignmentFacet.ItemAlignmentDef def =
+                        new ItemAlignmentFacet.ItemAlignmentDef();
+                def.setItemAlignmentOffset(0);
+                def.setItemAlignmentOffsetPercent(100);
+                itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
+                        {def});
+                rowPresenter.setFacet(ItemAlignmentFacet.class, itemAlignment);
+            }
+        } else {
+            super.setupPresenter(rowPresenter);
+        }
+    }
+
+    @Override
     void setVerticalGridViewLayout(VerticalGridView listview) {
         if (listview == null) {
             return;
         }
-        // Padding affects alignment when last row is focused
-        // (last is first when there's only one row).
-        setPadding(listview, mPaddingTop, mPaddingBottom);
 
-        // Item alignment affects focused row that isn't the last.
-        listview.setItemAlignmentOffset(0);
+        // we set the base line of alignment to -paddingBottom
+        listview.setWindowAlignmentOffset(-mPaddingBottom);
+        listview.setWindowAlignmentOffsetPercent(
+                VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
+
+        // align other rows that arent the last to center of screen, since our baseline is
+        // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
+        listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
         listview.setItemAlignmentOffsetPercent(50);
 
-        // Push rows to the bottom.
-        listview.setWindowAlignmentOffset(0);
-        listview.setWindowAlignmentOffsetPercent(50);
-        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
-    }
-
-    private static void setPadding(View view, int paddingTop, int paddingBottom) {
-        view.setPadding(view.getPaddingLeft(), paddingTop,
-                view.getPaddingRight(), paddingBottom);
+        // Push last row to the bottom padding
+        // Padding affects alignment when last row is focused
+        listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
+                listview.getPaddingRight(), mPaddingBottom);
+        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
     }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mPaddingTop =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top);
+        mOtherRowsCenterToBottom = getResources()
+                .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
         mPaddingBottom =
                 getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
         mBgDarkColor =
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
index b4df936..ecabdaa 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
@@ -31,10 +31,12 @@
 import android.support.v17.leanback.animation.LogAccelerateInterpolator;
 import android.support.v17.leanback.animation.LogDecelerateInterpolator;
 import android.support.v17.leanback.media.PlaybackGlueHost;
+import android.support.v17.leanback.widget.ItemAlignmentFacet;
 import android.support.v17.leanback.widget.ItemBridgeAdapter;
 import android.support.v17.leanback.widget.ObjectAdapter;
 import android.support.v17.leanback.widget.ObjectAdapter.DataObserver;
 import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.PlaybackRowPresenter;
 import android.support.v17.leanback.widget.Presenter;
 import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.RowPresenter;
@@ -108,7 +110,7 @@
     private static final int IN = 1;
     static final int OUT = 2;
 
-    private int mPaddingTop;
+    private int mOtherRowsCenterToBottom;
     private int mPaddingBottom;
     private View mRootView;
     private int mBackgroundType = BG_DARK;
@@ -613,6 +615,8 @@
                 mDescriptionFadeInAnimator.reverse();
             }
         }
+        getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
+                : R.string.lb_playback_controls_hidden));
 
         // If fading in while control row is focused, set initial translationY so
         // views slide in from below.
@@ -641,35 +645,52 @@
     }
 
     @Override
+    protected void setupPresenter(Presenter rowPresenter) {
+        if (rowPresenter instanceof PlaybackRowPresenter) {
+            if (rowPresenter.getFacet(ItemAlignmentFacet.class) == null) {
+                ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
+                ItemAlignmentFacet.ItemAlignmentDef def =
+                        new ItemAlignmentFacet.ItemAlignmentDef();
+                def.setItemAlignmentOffset(0);
+                def.setItemAlignmentOffsetPercent(100);
+                itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
+                        {def});
+                rowPresenter.setFacet(ItemAlignmentFacet.class, itemAlignment);
+            }
+        } else {
+            super.setupPresenter(rowPresenter);
+        }
+    }
+
+    @Override
     void setVerticalGridViewLayout(VerticalGridView listview) {
         if (listview == null) {
             return;
         }
-        // Padding affects alignment when last row is focused
-        // (last is first when there's only one row).
-        setPadding(listview, mPaddingTop, mPaddingBottom);
 
-        // Item alignment affects focused row that isn't the last.
-        listview.setItemAlignmentOffset(0);
+        // we set the base line of alignment to -paddingBottom
+        listview.setWindowAlignmentOffset(-mPaddingBottom);
+        listview.setWindowAlignmentOffsetPercent(
+                VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
+
+        // align other rows that arent the last to center of screen, since our baseline is
+        // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
+        listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
         listview.setItemAlignmentOffsetPercent(50);
 
-        // Push rows to the bottom.
-        listview.setWindowAlignmentOffset(0);
-        listview.setWindowAlignmentOffsetPercent(50);
-        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
-    }
-
-    private static void setPadding(View view, int paddingTop, int paddingBottom) {
-        view.setPadding(view.getPaddingLeft(), paddingTop,
-                view.getPaddingRight(), paddingBottom);
+        // Push last row to the bottom padding
+        // Padding affects alignment when last row is focused
+        listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
+                listview.getPaddingRight(), mPaddingBottom);
+        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
     }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mPaddingTop =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top);
+        mOtherRowsCenterToBottom = getResources()
+                .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
         mPaddingBottom =
                 getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
         mBgDarkColor =
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
index 31332645..81e76a6 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackSupportFragment.java
@@ -36,6 +36,7 @@
 import android.support.v17.leanback.widget.BaseOnItemViewClickedListener;
 import android.support.v17.leanback.widget.BaseOnItemViewSelectedListener;
 import android.support.v17.leanback.widget.ClassPresenterSelector;
+import android.support.v17.leanback.widget.ItemAlignmentFacet;
 import android.support.v17.leanback.widget.ItemBridgeAdapter;
 import android.support.v17.leanback.widget.ObjectAdapter;
 import android.support.v17.leanback.widget.PlaybackRowPresenter;
@@ -43,6 +44,7 @@
 import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.Row;
 import android.support.v17.leanback.widget.RowPresenter;
+import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
 import android.support.v17.leanback.widget.VerticalGridView;
 import android.support.v7.widget.RecyclerView;
 import android.util.Log;
@@ -65,8 +67,12 @@
  * of {@link RowPresenter}.
  * </p>
  * <p>
- * An instance of {@link android.support.v17.leanback.widget.PlaybackControlsRow} is expected to be
- * at position 0 in the adapter.
+ * A playback row is a row rendered by {@link PlaybackRowPresenter}.
+ * App can call {@link #setPlaybackRow(Row)} to set playback row for the first element of adapter.
+ * App can call {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} to set presenter for it.
+ * {@link #setPlaybackRow(Row)} and {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} are
+ * optional, app can pass playback row and PlaybackRowPresenter in the adapter using
+ * {@link #setAdapter(ObjectAdapter)}.
  * </p>
  */
 public class PlaybackSupportFragment extends Fragment {
@@ -79,7 +85,7 @@
      * A dark translucent background.
      */
     public static final int BG_DARK = 1;
-    private PlaybackGlueHost.HostCallback mHostCallback;
+    PlaybackGlueHost.HostCallback mHostCallback;
 
     /**
      * Resets the focus on the button in the middle of control row.
@@ -111,13 +117,13 @@
      * A light translucent background.
      */
     public static final int BG_LIGHT = 2;
-    private RowsSupportFragment mRowsSupportFragment;
-    private ObjectAdapter mAdapter;
-    private PlaybackRowPresenter mPresenter;
-    private Row mRow;
-    private BaseOnItemViewSelectedListener mExternalItemSelectedListener;
-    private BaseOnItemViewClickedListener mExternalItemClickedListener;
-    private BaseOnItemViewClickedListener mPlaybackItemClickedListener;
+    RowsSupportFragment mRowsSupportFragment;
+    ObjectAdapter mAdapter;
+    PlaybackRowPresenter mPresenter;
+    Row mRow;
+    BaseOnItemViewSelectedListener mExternalItemSelectedListener;
+    BaseOnItemViewClickedListener mExternalItemClickedListener;
+    BaseOnItemViewClickedListener mPlaybackItemClickedListener;
 
     private final BaseOnItemViewClickedListener mOnItemViewClickedListener =
             new BaseOnItemViewClickedListener() {
@@ -182,23 +188,23 @@
     private static final int IN = 1;
     private static final int OUT = 2;
 
-    private int mPaddingTop;
-    private int mPaddingBottom;
-    private View mRootView;
-    private int mBackgroundType = BG_DARK;
-    private int mBgDarkColor;
-    private int mBgLightColor;
-    private int mShowTimeMs;
-    private int mMajorFadeTranslateY, mMinorFadeTranslateY;
-    private int mAnimationTranslateY;
-    private OnFadeCompleteListener mFadeCompleteListener;
-    private View.OnKeyListener mInputEventHandler;
-    private boolean mFadingEnabled = true;
-    private int mFadingStatus = IDLE;
-    private int mBgAlpha;
-    private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
-    private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
-    private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
+    int mPaddingBottom;
+    int mOtherRowsCenterToBottom;
+    View mRootView;
+    int mBackgroundType = BG_DARK;
+    int mBgDarkColor;
+    int mBgLightColor;
+    int mShowTimeMs;
+    int mMajorFadeTranslateY, mMinorFadeTranslateY;
+    int mAnimationTranslateY;
+    OnFadeCompleteListener mFadeCompleteListener;
+    View.OnKeyListener mInputEventHandler;
+    boolean mFadingEnabled = true;
+    int mFadingStatus = IDLE;
+    int mBgAlpha;
+    ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
+    ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
+    ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
 
     private final Animator.AnimatorListener mFadeListener =
             new Animator.AnimatorListener() {
@@ -597,6 +603,8 @@
                 mOtherRowFadeInAnimator.reverse();
             }
         }
+        getView().announceForAccessibility(getString(fadeIn ? R.string.lb_playback_controls_shown
+                : R.string.lb_playback_controls_hidden));
 
         // If fading in while control row is focused, set initial translationY so
         // views slide in from below.
@@ -636,31 +644,30 @@
         if (listview == null) {
             return;
         }
-        // Padding affects alignment when last row is focused
-        // (last is first when there's only one row).
-        setPadding(listview, mPaddingTop, mPaddingBottom);
 
-        // Item alignment affects focused row that isn't the last.
-        listview.setItemAlignmentOffset(0);
+        // we set the base line of alignment to -paddingBottom
+        listview.setWindowAlignmentOffset(-mPaddingBottom);
+        listview.setWindowAlignmentOffsetPercent(
+                VerticalGridView.WINDOW_ALIGN_OFFSET_PERCENT_DISABLED);
+
+        // align other rows that arent the last to center of screen, since our baseline is
+        // -mPaddingBottom, we need subtract that from mOtherRowsCenterToBottom.
+        listview.setItemAlignmentOffset(mOtherRowsCenterToBottom - mPaddingBottom);
         listview.setItemAlignmentOffsetPercent(50);
 
-        // Push rows to the bottom.
-        listview.setWindowAlignmentOffset(0);
-        listview.setWindowAlignmentOffsetPercent(50);
-        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_BOTH_EDGE);
-    }
-
-    private static void setPadding(View view, int paddingTop, int paddingBottom) {
-        view.setPadding(view.getPaddingLeft(), paddingTop,
-                view.getPaddingRight(), paddingBottom);
+        // Push last row to the bottom padding
+        // Padding affects alignment when last row is focused
+        listview.setPadding(listview.getPaddingLeft(), listview.getPaddingTop(),
+                listview.getPaddingRight(), mPaddingBottom);
+        listview.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_HIGH_EDGE);
     }
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mPaddingTop =
-                getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_top);
+        mOtherRowsCenterToBottom = getResources()
+                .getDimensionPixelSize(R.dimen.lb_playback_other_rows_center_to_bottom);
         mPaddingBottom =
                 getResources().getDimensionPixelSize(R.dimen.lb_playback_controls_padding_bottom);
         mBgDarkColor =
@@ -847,7 +854,9 @@
     }
 
     /**
-     * Sets the playback row for the playback controls.
+     * Sets the playback row for the playback controls. The row will be set as first element
+     * of adapter if the adapter is {@link ArrayObjectAdapter} or {@link SparseArrayObjectAdapter}.
+     * @param row The row that represents the playback.
      */
     public void setPlaybackRow(Row row) {
         this.mRow = row;
@@ -856,11 +865,38 @@
     }
 
     /**
-     * Sets the presenter for rendering the playback controls.
+     * Sets the presenter for rendering the playback row set by {@link #setPlaybackRow(Row)}. If
+     * adapter does not set a {@link PresenterSelector}, {@link #setAdapter(ObjectAdapter)} will
+     * create a {@link ClassPresenterSelector} by default and map from the row object class to this
+     * {@link PlaybackRowPresenter}.
+     *
+     * @param  presenter Presenter used to render {@link #setPlaybackRow(Row)}.
      */
     public void setPlaybackRowPresenter(PlaybackRowPresenter presenter) {
         this.mPresenter = presenter;
         setupPresenter();
+        setPlaybackRowPresenterAlignment();
+    }
+
+    void setPlaybackRowPresenterAlignment() {
+        if (mAdapter != null && mAdapter.getPresenterSelector() != null) {
+            Presenter[] presenters = mAdapter.getPresenterSelector().getPresenters();
+            if (presenters != null) {
+                for (int i = 0; i < presenters.length; i++) {
+                    if (presenters[i] instanceof PlaybackRowPresenter
+                            && presenters[i].getFacet(ItemAlignmentFacet.class) == null) {
+                        ItemAlignmentFacet itemAlignment = new ItemAlignmentFacet();
+                        ItemAlignmentFacet.ItemAlignmentDef def =
+                                new ItemAlignmentFacet.ItemAlignmentDef();
+                        def.setItemAlignmentOffset(0);
+                        def.setItemAlignmentOffsetPercent(100);
+                        itemAlignment.setAlignmentDefs(new ItemAlignmentFacet.ItemAlignmentDef[]
+                                {def});
+                        presenters[i].setFacet(ItemAlignmentFacet.class, itemAlignment);
+                    }
+                }
+            }
+        }
     }
 
     /**
@@ -874,12 +910,19 @@
     }
 
     /**
-     * Sets the list of rows for the fragment.
+     * Sets the list of rows for the fragment. A default {@link ClassPresenterSelector} will be
+     * created if {@link ObjectAdapter#getPresenterSelector()} is null. if user provides
+     * {@link #setPlaybackRow(Row)} and {@link #setPlaybackRowPresenter(PlaybackRowPresenter)},
+     * the row and presenter will be set onto the adapter.
+     *
+     * @param adapter The adapter that contains related rows and optional playback row.
      */
     public void setAdapter(ObjectAdapter adapter) {
         mAdapter = adapter;
         setupRow();
         setupPresenter();
+        setPlaybackRowPresenterAlignment();
+
         if (mRowsSupportFragment != null) {
             mRowsSupportFragment.setAdapter(adapter);
         }
@@ -893,6 +936,9 @@
             } else {
                 adapter.replace(0, mRow);
             }
+        } else if (mAdapter instanceof SparseArrayObjectAdapter && mRow != null) {
+            SparseArrayObjectAdapter adapter = ((SparseArrayObjectAdapter) mAdapter);
+            adapter.set(0, mRow);
         }
     }
 
@@ -901,10 +947,9 @@
             PresenterSelector selector = mAdapter.getPresenterSelector();
             if (selector == null) {
                 selector = new ClassPresenterSelector();
+                ((ClassPresenterSelector) selector).addClassPresenter(mRow.getClass(), mPresenter);
                 mAdapter.setPresenterSelector(selector);
-            }
-
-            if (selector instanceof ClassPresenterSelector) {
+            } else if (selector instanceof ClassPresenterSelector) {
                 ((ClassPresenterSelector) selector).addClassPresenter(mRow.getClass(), mPresenter);
             }
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java b/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
index d3a45a0..fe0e26f 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
@@ -349,6 +349,10 @@
             if (mExternalAdapterListener != null) {
                 mExternalAdapterListener.onCreate(vh);
             }
+            RowPresenter rowPresenter = (RowPresenter) vh.getPresenter();
+            RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(vh.getViewHolder());
+            rowVh.setOnItemViewSelectedListener(mOnItemViewSelectedListener);
+            rowVh.setOnItemViewClickedListener(mOnItemViewClickedListener);
         }
 
         @Override
@@ -362,8 +366,6 @@
             setRowViewExpanded(vh, mExpand);
             RowPresenter rowPresenter = (RowPresenter) vh.getPresenter();
             RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(vh.getViewHolder());
-            rowVh.setOnItemViewSelectedListener(mOnItemViewSelectedListener);
-            rowVh.setOnItemViewClickedListener(mOnItemViewClickedListener);
             rowPresenter.setEntranceTransitionState(rowVh, mAfterEntranceTransition);
             if (mExternalAdapterListener != null) {
                 mExternalAdapterListener.onAttachedToWindow(vh);
diff --git a/v17/leanback/src/android/support/v17/leanback/app/RowsSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/RowsSupportFragment.java
index 5582644..9f55aa2 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/RowsSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/RowsSupportFragment.java
@@ -352,6 +352,10 @@
             if (mExternalAdapterListener != null) {
                 mExternalAdapterListener.onCreate(vh);
             }
+            RowPresenter rowPresenter = (RowPresenter) vh.getPresenter();
+            RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(vh.getViewHolder());
+            rowVh.setOnItemViewSelectedListener(mOnItemViewSelectedListener);
+            rowVh.setOnItemViewClickedListener(mOnItemViewClickedListener);
         }
 
         @Override
@@ -365,8 +369,6 @@
             setRowViewExpanded(vh, mExpand);
             RowPresenter rowPresenter = (RowPresenter) vh.getPresenter();
             RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(vh.getViewHolder());
-            rowVh.setOnItemViewSelectedListener(mOnItemViewSelectedListener);
-            rowVh.setOnItemViewClickedListener(mOnItemViewClickedListener);
             rowPresenter.setEntranceTransitionState(rowVh, mAfterEntranceTransition);
             if (mExternalAdapterListener != null) {
                 mExternalAdapterListener.onAttachedToWindow(vh);
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
index cfa27df..9e80dfc 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
@@ -16,6 +16,7 @@
 import android.os.Bundle;
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.transition.TransitionHelper;
+import android.support.v17.leanback.util.StateMachine.State;
 import android.support.v17.leanback.widget.BrowseFrameLayout;
 import android.support.v17.leanback.widget.ObjectAdapter;
 import android.support.v17.leanback.widget.OnChildLaidOutListener;
@@ -49,6 +50,29 @@
     private int mSelectedPosition = -1;
 
     /**
+     * State to setEntranceTransitionState(false)
+     */
+    final State STATE_SET_ENTRANCE_START_STATE = new State("SET_ENTRANCE_START_STATE") {
+        @Override
+        public void run() {
+            setEntranceTransitionState(false);
+        }
+    };
+
+    @Override
+    void createStateMachineStates() {
+        super.createStateMachineStates();
+        mStateMachine.addState(STATE_SET_ENTRANCE_START_STATE);
+    }
+
+    @Override
+    void createStateMachineTransitions() {
+        super.createStateMachineTransitions();
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_SET_ENTRANCE_START_STATE, EVT_ON_CREATEVIEW);
+    }
+
+    /**
      * Sets the grid presenter.
      */
     public void setGridPresenter(VerticalGridPresenter gridPresenter) {
@@ -160,13 +184,8 @@
         ViewGroup gridFrame = (ViewGroup) root.findViewById(R.id.grid_frame);
         installTitleView(inflater, gridFrame, savedInstanceState);
         getProgressBarManager().setRootView(root);
-        return root;
-    }
 
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock);
+        ViewGroup gridDock = (ViewGroup) root.findViewById(R.id.browse_grid_dock);
         mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock);
         gridDock.addView(mGridViewHolder.view);
         mGridViewHolder.getGridView().setOnChildLaidOutListener(mChildLaidOutListener);
@@ -179,6 +198,7 @@
         });
 
         updateAdapter();
+        return root;
     }
 
     private void setupFocusSearchListener() {
@@ -191,9 +211,6 @@
     public void onStart() {
         super.onStart();
         setupFocusSearchListener();
-        if (isEntranceTransitionEnabled()) {
-            setEntranceTransitionState(false);
-        }
     }
 
     @Override
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
index 55e079d..6327790 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
@@ -19,6 +19,7 @@
 import android.os.Bundle;
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.transition.TransitionHelper;
+import android.support.v17.leanback.util.StateMachine.State;
 import android.support.v17.leanback.widget.BrowseFrameLayout;
 import android.support.v17.leanback.widget.ObjectAdapter;
 import android.support.v17.leanback.widget.OnChildLaidOutListener;
@@ -52,6 +53,29 @@
     private int mSelectedPosition = -1;
 
     /**
+     * State to setEntranceTransitionState(false)
+     */
+    final State STATE_SET_ENTRANCE_START_STATE = new State("SET_ENTRANCE_START_STATE") {
+        @Override
+        public void run() {
+            setEntranceTransitionState(false);
+        }
+    };
+
+    @Override
+    void createStateMachineStates() {
+        super.createStateMachineStates();
+        mStateMachine.addState(STATE_SET_ENTRANCE_START_STATE);
+    }
+
+    @Override
+    void createStateMachineTransitions() {
+        super.createStateMachineTransitions();
+        mStateMachine.addTransition(STATE_ENTRANCE_ON_PREPARED,
+                STATE_SET_ENTRANCE_START_STATE, EVT_ON_CREATEVIEW);
+    }
+
+    /**
      * Sets the grid presenter.
      */
     public void setGridPresenter(VerticalGridPresenter gridPresenter) {
@@ -163,13 +187,8 @@
         ViewGroup gridFrame = (ViewGroup) root.findViewById(R.id.grid_frame);
         installTitleView(inflater, gridFrame, savedInstanceState);
         getProgressBarManager().setRootView(root);
-        return root;
-    }
 
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        ViewGroup gridDock = (ViewGroup) view.findViewById(R.id.browse_grid_dock);
+        ViewGroup gridDock = (ViewGroup) root.findViewById(R.id.browse_grid_dock);
         mGridViewHolder = mGridPresenter.onCreateViewHolder(gridDock);
         gridDock.addView(mGridViewHolder.view);
         mGridViewHolder.getGridView().setOnChildLaidOutListener(mChildLaidOutListener);
@@ -182,6 +201,7 @@
         });
 
         updateAdapter();
+        return root;
     }
 
     private void setupFocusSearchListener() {
@@ -194,9 +214,6 @@
     public void onStart() {
         super.onStart();
         setupFocusSearchListener();
-        if (isEntranceTransitionEnabled()) {
-            setEntranceTransitionState(false);
-        }
     }
 
     @Override
diff --git a/v17/leanback/src/android/support/v17/leanback/graphics/BoundsRule.java b/v17/leanback/src/android/support/v17/leanback/graphics/BoundsRule.java
index 75ab391..700f7f0 100644
--- a/v17/leanback/src/android/support/v17/leanback/graphics/BoundsRule.java
+++ b/v17/leanback/src/android/support/v17/leanback/graphics/BoundsRule.java
@@ -23,88 +23,87 @@
  * rectangular bound - left/top/right/bottom.
  */
 public class BoundsRule {
-    static final int INHERIT_PARENT = 0;
-    static final int ABSOLUTE_VALUE = 1;
-    static final int INHERIT_WITH_OFFSET = 2;
 
     /**
-     * This class represents individual rules for updating the bounds. Currently we support
-     * 3 different rule types -
-     *
-     * <ul>
-     *     <li>inheritFromParent: it applies a percentage to the parent property to compute
-     *     the final value </li>
-     *     <li>absoluteValue: it always used the supplied absolute value</li>
-     *     <li>inheritFromParentWithOffset: this uses a combination of INHERIT_PARENT
-     *     and ABSOLUTE_VALUE. First it applies the percentage on the parent and then adds the
-     *     offset to compute the final value</li>
-     * </ul>
+     * This class represents individual rules for updating the bounds.
      */
     public final static class ValueRule {
-        private final int type;
-        private float fraction;
-        private int absoluteValue;
+        float mFraction;
+        int mAbsoluteValue;
 
-        ValueRule(int type, int absoluteValue, float fraction) {
-            this.type = type;
-            this.absoluteValue = absoluteValue;
-            this.fraction = fraction;
+        /**
+         * Creates ValueRule using a fraction of parent size.
+         *
+         * @param fraction Percentage of parent.
+         * @return Newly created ValueRule.
+         */
+        public static ValueRule inheritFromParent(float fraction) {
+            return new ValueRule(0, fraction);
+        }
+
+        /**
+         * Creates ValueRule using an absolute value.
+         *
+         * @param absoluteValue Absolute value.
+         * @return Newly created ValueRule.
+         */
+        public static ValueRule absoluteValue(int absoluteValue) {
+            return new ValueRule(absoluteValue, 0);
+        }
+
+        /**
+         * Creates ValueRule of fraction and offset.
+         *
+         * @param fraction Percentage of parent.
+         * @param value    Offset
+         * @return Newly created ValueRule.
+         */
+        public static ValueRule inheritFromParentWithOffset(float fraction, int value) {
+            return new ValueRule(value, fraction);
+        }
+
+        ValueRule(int absoluteValue, float fraction) {
+            this.mAbsoluteValue = absoluteValue;
+            this.mFraction = fraction;
         }
 
         ValueRule(ValueRule rule) {
-            this.type = rule.type;
-            this.fraction = rule.fraction;
-            this.absoluteValue = rule.absoluteValue;
+            this.mFraction = rule.mFraction;
+            this.mAbsoluteValue = rule.mAbsoluteValue;
         }
 
         /**
          * Sets the fractional value (percentage of parent) for this rule.
+         *
+         * @param fraction Percentage of parent.
          */
         public void setFraction(float fraction) {
-            this.fraction = fraction;
+            this.mFraction = fraction;
         }
 
         /**
-         * Returns the current fractional value.
+         * @return The current fractional value.
          */
         public float getFraction() {
-            return fraction;
+            return mFraction;
         }
 
         /**
-         * Sets the absolute value for this rule.
+         * Sets the absolute/offset value for rule.
+         *
+         * @param absoluteValue Absolute value.
          */
         public void setAbsoluteValue(int absoluteValue) {
-            this.absoluteValue = absoluteValue;
+            this.mAbsoluteValue = absoluteValue;
         }
 
         /**
-         * Returns the current absolute value.
+         * @return The current absolute/offset value forrule.
          */
         public int getAbsoluteValue() {
-            return absoluteValue;
+            return mAbsoluteValue;
         }
-    }
 
-    /**
-     * Factory method for creating ValueRule of type INHERIT_FROM_PARENT.
-     */
-    public static ValueRule inheritFromParent(float fraction) {
-        return new ValueRule(INHERIT_PARENT, 0, fraction);
-    }
-
-    /**
-     * Factory method for creating ValueRule of type ABSOLUTE_VALUE.
-     */
-    public static ValueRule absoluteValue(int value) {
-        return new ValueRule(ABSOLUTE_VALUE, value, 0);
-    }
-
-    /**
-     * Factory method for creating ValueRule of type INHERIT_WITH_OFFSET.
-     */
-    public static ValueRule inheritFromParentWithOffset(float fraction, int value) {
-        return new ValueRule(INHERIT_WITH_OFFSET, value, fraction);
     }
 
     /**
@@ -150,17 +149,7 @@
     }
 
     private int doCalculate(int value, ValueRule rule, int size) {
-        int offset = 0;
-        switch(rule.type) {
-            case INHERIT_WITH_OFFSET:
-                offset = rule.absoluteValue;
-            case INHERIT_PARENT:
-                return value + offset + (int)(rule.fraction * size);
-            case ABSOLUTE_VALUE:
-                return rule.absoluteValue;
-        }
-
-        throw new IllegalArgumentException("Invalid type: "+rule.type);
+        return value + rule.mAbsoluteValue + (int) (rule.mFraction * size);
     }
 
     /** {@link ValueRule} for left attribute of {@link BoundsRule} */
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 b7f77bd..5788393 100644
--- a/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java
+++ b/v17/leanback/src/android/support/v17/leanback/graphics/CompositeDrawable.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.support.annotation.NonNull;
+import android.support.v17.leanback.graphics.BoundsRule.ValueRule;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.util.Property;
 
@@ -319,7 +320,7 @@
             @Override
             public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
                 if (obj.getBoundsRule().top == null) {
-                    obj.getBoundsRule().top = BoundsRule.absoluteValue(value);
+                    obj.getBoundsRule().top = ValueRule.absoluteValue(value);
                 } else {
                     obj.getBoundsRule().top.setAbsoluteValue(value);
                 }
@@ -345,7 +346,7 @@
             @Override
             public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
                 if (obj.getBoundsRule().bottom == null) {
-                    obj.getBoundsRule().bottom = BoundsRule.absoluteValue(value);
+                    obj.getBoundsRule().bottom = ValueRule.absoluteValue(value);
                 } else {
                     obj.getBoundsRule().bottom.setAbsoluteValue(value);
                 }
@@ -372,7 +373,7 @@
             @Override
             public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
                 if (obj.getBoundsRule().left == null) {
-                    obj.getBoundsRule().left = BoundsRule.absoluteValue(value);
+                    obj.getBoundsRule().left = ValueRule.absoluteValue(value);
                 } else {
                     obj.getBoundsRule().left.setAbsoluteValue(value);
                 }
@@ -398,7 +399,7 @@
             @Override
             public void set(CompositeDrawable.ChildDrawable obj, Integer value) {
                 if (obj.getBoundsRule().right == null) {
-                    obj.getBoundsRule().right = BoundsRule.absoluteValue(value);
+                    obj.getBoundsRule().right = ValueRule.absoluteValue(value);
                 } else {
                     obj.getBoundsRule().right.setAbsoluteValue(value);
                 }
@@ -427,7 +428,7 @@
             @Override
             public void set(CompositeDrawable.ChildDrawable obj, Float value) {
                 if (obj.getBoundsRule().top == null) {
-                    obj.getBoundsRule().top = BoundsRule.inheritFromParent(value);
+                    obj.getBoundsRule().top = ValueRule.inheritFromParent(value);
                 } else {
                     obj.getBoundsRule().top.setFraction(value);
                 }
@@ -457,7 +458,7 @@
             @Override
             public void set(CompositeDrawable.ChildDrawable obj, Float value) {
                 if (obj.getBoundsRule().bottom == null) {
-                    obj.getBoundsRule().bottom = BoundsRule.inheritFromParent(value);
+                    obj.getBoundsRule().bottom = ValueRule.inheritFromParent(value);
                 } else {
                     obj.getBoundsRule().bottom.setFraction(value);
                 }
@@ -486,7 +487,7 @@
             @Override
             public void set(CompositeDrawable.ChildDrawable obj, Float value) {
                 if (obj.getBoundsRule().left == null) {
-                    obj.getBoundsRule().left = BoundsRule.inheritFromParent(value);
+                    obj.getBoundsRule().left = ValueRule.inheritFromParent(value);
                 } else {
                     obj.getBoundsRule().left.setFraction(value);
                 }
@@ -511,11 +512,11 @@
          * isn't available at compile time.
          */
         public static final Property<CompositeDrawable.ChildDrawable, Float> RIGHT_FRACTION =
-                new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractoinRight") {
+                new Property<CompositeDrawable.ChildDrawable, Float>(Float.class, "fractionRight") {
             @Override
             public void set(CompositeDrawable.ChildDrawable obj, Float value) {
                 if (obj.getBoundsRule().right == null) {
-                    obj.getBoundsRule().right = BoundsRule.inheritFromParent(value);
+                    obj.getBoundsRule().right = ValueRule.inheritFromParent(value);
                 } else {
                     obj.getBoundsRule().right.setFraction(value);
                 }
diff --git a/v17/leanback/src/android/support/v17/leanback/media/MediaPlayerGlue.java b/v17/leanback/src/android/support/v17/leanback/media/MediaPlayerGlue.java
index b0f0b8a..38d6c92 100644
--- a/v17/leanback/src/android/support/v17/leanback/media/MediaPlayerGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/media/MediaPlayerGlue.java
@@ -381,17 +381,12 @@
      * @see MediaPlayer#setDataSource(String)
      */
     public boolean setMediaSource(Uri uri) {
-        if (mMediaSourceUri != null && mMediaSourceUri.equals(uri)) {
+        if (mMediaSourceUri != null ? mMediaSourceUri.equals(uri) : uri == null) {
             return false;
         }
-        if (mMediaSourceUri != null || mMediaSourcePath != null) {
-            mMediaSourceUri = uri;
-            mMediaSourcePath = null;
-            prepareMediaForPlaying();
-        } else {
-            mMediaSourceUri = uri;
-            prepareMediaForPlaying();
-        }
+        mMediaSourceUri = uri;
+        mMediaSourcePath = null;
+        prepareMediaForPlaying();
         return true;
     }
 
@@ -403,17 +398,12 @@
      * @see MediaPlayer#setDataSource(String)
      */
     public boolean setMediaSource(String path) {
-        if (mMediaSourcePath != null && mMediaSourcePath.equals(mMediaSourcePath)) {
+        if (mMediaSourcePath != null ? mMediaSourcePath.equals(path) : path == null) {
             return false;
         }
-        if (mMediaSourceUri != null || mMediaSourcePath != null) {
-            mMediaSourceUri = null;
-            mMediaSourcePath = path;
-            prepareMediaForPlaying();
-        } else {
-            mMediaSourcePath = path;
-            prepareMediaForPlaying();
-        }
+        mMediaSourceUri = null;
+        mMediaSourcePath = path;
+        prepareMediaForPlaying();
         return true;
     }
 
diff --git a/v17/leanback/src/android/support/v17/leanback/media/PlaybackControlGlue.java b/v17/leanback/src/android/support/v17/leanback/media/PlaybackControlGlue.java
index 215ba22..945999d 100644
--- a/v17/leanback/src/android/support/v17/leanback/media/PlaybackControlGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/media/PlaybackControlGlue.java
@@ -27,6 +27,7 @@
 import android.support.v17.leanback.widget.OnActionClickedListener;
 import android.support.v17.leanback.widget.PlaybackControlsRow;
 import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.PlaybackRowPresenter;
 import android.support.v17.leanback.widget.PresenterSelector;
 import android.support.v17.leanback.widget.RowPresenter;
 import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
@@ -54,8 +55,10 @@
  * inform the glue what speed levels are supported for fast forward/rewind.
  * </p>
  *
- * <p>You may override {@link #onCreateControlsRowAndPresenter()} which will set a controls
- * row and return a row presenter you can use to present the row.
+ * <p>You may override {@link #onCreateControlsRowAndPresenter()} which will create a
+ * {@link PlaybackControlsRow} and a {@link PlaybackControlsRowPresenter}. You may call
+ * {@link #setControlsRow(PlaybackControlsRow)} and
+ * {@link #setPlaybackRowPresenter(PlaybackRowPresenter)} to customize your own row and presenter.
  * </p>
  *
  * <p>The helper sets a {@link SparseArrayObjectAdapter}
@@ -176,7 +179,7 @@
     private final int[] mFastForwardSpeeds;
     private final int[] mRewindSpeeds;
     private PlaybackControlsRow mControlsRow;
-    private PlaybackControlsRowPresenter mControlsRowPresenter;
+    private PlaybackRowPresenter mControlsRowPresenter;
     private PlaybackControlsRow.PlayPauseAction mPlayPauseAction;
     private PlaybackControlsRow.SkipNextAction mSkipNextAction;
     private PlaybackControlsRow.SkipPreviousAction mSkipPreviousAction;
@@ -237,10 +240,10 @@
         super.onAttachedToHost(host);
         host.setOnKeyInterceptListener(this);
         host.setOnActionClickedListener(this);
-        if (getControlsRow() == null || getControlsRowPresenter() == null) {
+        if (getControlsRow() == null || getPlaybackRowPresenter() == null) {
             onCreateControlsRowAndPresenter();
         }
-        host.setPlaybackRowPresenter(getControlsRowPresenter());
+        host.setPlaybackRowPresenter(getPlaybackRowPresenter());
         host.setPlaybackRow(getControlsRow());
     }
 
@@ -265,37 +268,40 @@
      * {@link PlaybackControlsRowPresenter}. Subclass may override.
      */
     protected void onCreateControlsRowAndPresenter() {
-        PlaybackControlsRow controlsRow = new PlaybackControlsRow(this);
-        setControlsRow(controlsRow);
+        if (getControlsRow() == null) {
+            PlaybackControlsRow controlsRow = new PlaybackControlsRow(this);
+            setControlsRow(controlsRow);
+        }
+        if (getPlaybackRowPresenter() == null) {
+            final AbstractDetailsDescriptionPresenter detailsPresenter =
+                    new AbstractDetailsDescriptionPresenter() {
+                        @Override
+                        protected void onBindDescription(ViewHolder
+                                viewHolder, Object object) {
+                            PlaybackControlGlue glue = (PlaybackControlGlue) object;
+                            if (glue.hasValidMedia()) {
+                                viewHolder.getTitle().setText(glue.getMediaTitle());
+                                viewHolder.getSubtitle().setText(glue.getMediaSubtitle());
+                            } else {
+                                viewHolder.getTitle().setText("");
+                                viewHolder.getSubtitle().setText("");
+                            }
+                        }
+                    };
 
-        final AbstractDetailsDescriptionPresenter detailsPresenter =
-                new AbstractDetailsDescriptionPresenter() {
-            @Override
-            protected void onBindDescription(ViewHolder
-                                                     viewHolder, Object object) {
-                PlaybackControlGlue glue = (PlaybackControlGlue) object;
-                if (glue.hasValidMedia()) {
-                    viewHolder.getTitle().setText(glue.getMediaTitle());
-                    viewHolder.getSubtitle().setText(glue.getMediaSubtitle());
-                } else {
-                    viewHolder.getTitle().setText("");
-                    viewHolder.getSubtitle().setText("");
+            setPlaybackRowPresenter(new PlaybackControlsRowPresenter(detailsPresenter) {
+                @Override
+                protected void onBindRowViewHolder(RowPresenter.ViewHolder vh, Object item) {
+                    super.onBindRowViewHolder(vh, item);
+                    vh.setOnKeyListener(PlaybackControlGlue.this);
                 }
-            }
-        };
-
-        setControlsRowPresenter(new PlaybackControlsRowPresenter(detailsPresenter) {
-            @Override
-            protected void onBindRowViewHolder(RowPresenter.ViewHolder vh, Object item) {
-                super.onBindRowViewHolder(vh, item);
-                vh.setOnKeyListener(PlaybackControlGlue.this);
-            }
-            @Override
-            protected void onUnbindRowViewHolder(RowPresenter.ViewHolder vh) {
-                super.onUnbindRowViewHolder(vh);
-                vh.setOnKeyListener(null);
-            }
-        });
+                @Override
+                protected void onUnbindRowViewHolder(RowPresenter.ViewHolder vh) {
+                    super.onUnbindRowViewHolder(vh);
+                    vh.setOnKeyListener(null);
+                }
+            });
+        }
     }
 
     /**
@@ -358,7 +364,10 @@
 
     /**
      * Sets the controls row Presenter to be managed by the glue layer.
+     * @deprecated PlaybackControlGlue supports any PlaybackRowPresenter, use
+     * {@link #setPlaybackRowPresenter(PlaybackRowPresenter)}.
      */
+    @Deprecated
     public void setControlsRowPresenter(PlaybackControlsRowPresenter presenter) {
         mControlsRowPresenter = presenter;
     }
@@ -372,8 +381,28 @@
 
     /**
      * Returns the playback controls row Presenter managed by the glue layer.
+     * @deprecated PlaybackControlGlue supports any PlaybackRowPresenter, use
+     * {@link #getPlaybackRowPresenter()}.
      */
+    @Deprecated
     public PlaybackControlsRowPresenter getControlsRowPresenter() {
+        return mControlsRowPresenter instanceof PlaybackControlsRowPresenter
+                ? (PlaybackControlsRowPresenter) mControlsRowPresenter : null;
+    }
+
+    /**
+     * Sets the controls row Presenter to be passed to {@link PlaybackGlueHost} in
+     * {@link #onAttachedToHost(PlaybackGlueHost)}.
+     */
+    public void setPlaybackRowPresenter(PlaybackRowPresenter presenter) {
+        mControlsRowPresenter = presenter;
+    }
+
+    /**
+     * Returns the playback row Presenter to be passed to {@link PlaybackGlueHost} in
+     * {@link #onAttachedToHost(PlaybackGlueHost)}.
+     */
+    public PlaybackRowPresenter getPlaybackRowPresenter() {
         return mControlsRowPresenter;
     }
 
@@ -535,6 +564,7 @@
 
     private void updateControlsRow() {
         updateRowMetadata();
+        updateControlButtons();
         sHandler.removeMessages(MSG_UPDATE_PLAYBACK_STATE, mGlueWeakReference);
         updatePlaybackState();
     }
@@ -591,6 +621,49 @@
         }
     }
 
+    void updateControlButtons() {
+        final SparseArrayObjectAdapter primaryActionsAdapter = (SparseArrayObjectAdapter)
+                getControlsRow().getPrimaryActionsAdapter();
+        final long actions = getSupportedActions();
+        if ((actions & ACTION_SKIP_TO_PREVIOUS) != 0 && mSkipPreviousAction == null) {
+            mSkipPreviousAction = new PlaybackControlsRow.SkipPreviousAction(getContext());
+            primaryActionsAdapter.set(ACTION_SKIP_TO_PREVIOUS, mSkipPreviousAction);
+        } else if ((actions & ACTION_SKIP_TO_PREVIOUS) == 0 && mSkipPreviousAction != null) {
+            primaryActionsAdapter.clear(ACTION_SKIP_TO_PREVIOUS);
+            mSkipPreviousAction = null;
+        }
+        if ((actions & ACTION_REWIND) != 0 && mRewindAction == null) {
+            mRewindAction = new PlaybackControlsRow.RewindAction(getContext(),
+                    mRewindSpeeds.length);
+            primaryActionsAdapter.set(ACTION_REWIND, mRewindAction);
+        } else if ((actions & ACTION_REWIND) == 0 && mRewindAction != null) {
+            primaryActionsAdapter.clear(ACTION_REWIND);
+            mRewindAction = null;
+        }
+        if ((actions & ACTION_PLAY_PAUSE) != 0 && mPlayPauseAction == null) {
+            mPlayPauseAction = new PlaybackControlsRow.PlayPauseAction(getContext());
+            primaryActionsAdapter.set(ACTION_PLAY_PAUSE, mPlayPauseAction);
+        } else if ((actions & ACTION_PLAY_PAUSE) == 0 && mPlayPauseAction != null) {
+            primaryActionsAdapter.clear(ACTION_PLAY_PAUSE);
+            mPlayPauseAction = null;
+        }
+        if ((actions & ACTION_FAST_FORWARD) != 0 && mFastForwardAction == null) {
+            mFastForwardAction = new PlaybackControlsRow.FastForwardAction(getContext(),
+                    mFastForwardSpeeds.length);
+            primaryActionsAdapter.set(ACTION_FAST_FORWARD, mFastForwardAction);
+        } else if ((actions & ACTION_FAST_FORWARD) == 0 && mFastForwardAction != null) {
+            primaryActionsAdapter.clear(ACTION_FAST_FORWARD);
+            mFastForwardAction = null;
+        }
+        if ((actions & ACTION_SKIP_TO_NEXT) != 0 && mSkipNextAction == null) {
+            mSkipNextAction = new PlaybackControlsRow.SkipNextAction(getContext());
+            primaryActionsAdapter.set(ACTION_SKIP_TO_NEXT, mSkipNextAction);
+        } else if ((actions & ACTION_SKIP_TO_NEXT) == 0 && mSkipNextAction != null) {
+            primaryActionsAdapter.clear(ACTION_SKIP_TO_NEXT);
+            mSkipNextAction = null;
+        }
+    }
+
     private void updatePlaybackState(int playbackSpeed) {
         if (mControlsRow == null) {
             return;
@@ -598,56 +671,6 @@
 
         final SparseArrayObjectAdapter primaryActionsAdapter = (SparseArrayObjectAdapter)
                 getControlsRow().getPrimaryActionsAdapter();
-        final long actions = getSupportedActions();
-        if ((actions & ACTION_SKIP_TO_PREVIOUS) != 0) {
-            if (mSkipPreviousAction == null) {
-                mSkipPreviousAction = new PlaybackControlsRow.SkipPreviousAction(getContext());
-            }
-            primaryActionsAdapter.set(ACTION_SKIP_TO_PREVIOUS, mSkipPreviousAction);
-        } else {
-            primaryActionsAdapter.clear(ACTION_SKIP_TO_PREVIOUS);
-            mSkipPreviousAction = null;
-        }
-        if ((actions & ACTION_REWIND) != 0) {
-            if (mRewindAction == null) {
-                mRewindAction = new PlaybackControlsRow.RewindAction(
-                        getContext(),
-                        mRewindSpeeds.length);
-            }
-            primaryActionsAdapter.set(ACTION_REWIND, mRewindAction);
-        } else {
-            primaryActionsAdapter.clear(ACTION_REWIND);
-            mRewindAction = null;
-        }
-        if ((actions & ACTION_PLAY_PAUSE) != 0) {
-            if (mPlayPauseAction == null) {
-                mPlayPauseAction = new PlaybackControlsRow.PlayPauseAction(getContext());
-            }
-            primaryActionsAdapter.set(ACTION_PLAY_PAUSE, mPlayPauseAction);
-        } else {
-            primaryActionsAdapter.clear(ACTION_PLAY_PAUSE);
-            mPlayPauseAction = null;
-        }
-        if ((actions & ACTION_FAST_FORWARD) != 0) {
-            if (mFastForwardAction == null) {
-                mFastForwardAction = new PlaybackControlsRow.FastForwardAction(
-                        getContext(),
-                        mFastForwardSpeeds.length);
-            }
-            primaryActionsAdapter.set(ACTION_FAST_FORWARD, mFastForwardAction);
-        } else {
-            primaryActionsAdapter.clear(ACTION_FAST_FORWARD);
-            mFastForwardAction = null;
-        }
-        if ((actions & ACTION_SKIP_TO_NEXT) != 0) {
-            if (mSkipNextAction == null) {
-                mSkipNextAction = new PlaybackControlsRow.SkipNextAction(getContext());
-            }
-            primaryActionsAdapter.set(ACTION_SKIP_TO_NEXT, mSkipNextAction);
-        } else {
-            primaryActionsAdapter.clear(ACTION_SKIP_TO_NEXT);
-            mSkipNextAction = null;
-        }
 
         if (mFastForwardAction != null) {
             int index = 0;
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..b710694 100644
--- a/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java
+++ b/v17/leanback/src/android/support/v17/leanback/transition/ParallaxTransition.java
@@ -57,7 +57,7 @@
     }
 
     Animator createAnimator(View view) {
-        final Parallax<?> source = (Parallax) view.getTag(R.id.lb_parallax_source);
+        final Parallax source = (Parallax) view.getTag(R.id.lb_parallax_source);
         if (source == null) {
             return null;
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/transition/TransitionHelper.java b/v17/leanback/src/android/support/v17/leanback/transition/TransitionHelper.java
index bef3d8d..9f92066 100644
--- a/v17/leanback/src/android/support/v17/leanback/transition/TransitionHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/transition/TransitionHelper.java
@@ -62,100 +62,108 @@
     /**
      * Interface implemented by classes that support Transition animations.
      */
-    static interface TransitionHelperVersionImpl {
+    interface TransitionHelperVersionImpl {
 
-        public void setEnterTransition(android.app.Fragment fragment, Object transition);
+        void setEnterTransition(android.app.Fragment fragment, Object transition);
 
-        public void setExitTransition(android.app.Fragment fragment, Object transition);
+        void setExitTransition(android.app.Fragment fragment, Object transition);
 
-        public void setSharedElementEnterTransition(android.app.Fragment fragment,
+        void setSharedElementEnterTransition(android.app.Fragment fragment,
                 Object transition);
 
-        public void addSharedElement(android.app.FragmentTransaction ft,
+        void addSharedElement(android.app.FragmentTransaction ft,
                 View view, String transitionName);
 
-        public Object getSharedElementEnterTransition(Window window);
+        Object getSharedElementEnterTransition(Window window);
 
-        public Object getSharedElementReturnTransition(Window window);
+        void setSharedElementEnterTransition(Window window, Object transition);
 
-        public Object getSharedElementExitTransition(Window window);
+        Object getSharedElementReturnTransition(Window window);
 
-        public Object getSharedElementReenterTransition(Window window);
+        void setSharedElementReturnTransition(Window window, Object transition);
 
-        public Object getEnterTransition(Window window);
+        Object getSharedElementExitTransition(Window window);
 
-        public Object getReturnTransition(Window window);
+        Object getSharedElementReenterTransition(Window window);
 
-        public Object getExitTransition(Window window);
+        Object getEnterTransition(Window window);
 
-        public Object getReenterTransition(Window window);
+        void setEnterTransition(Window window, Object transition);
 
-        public Object createScene(ViewGroup sceneRoot, Runnable r);
+        Object getReturnTransition(Window window);
 
-        public Object createAutoTransition();
+        void setReturnTransition(Window window, Object transition);
 
-        public Object createSlide(int slideEdge);
+        Object getExitTransition(Window window);
 
-        public Object createScale();
+        Object getReenterTransition(Window window);
 
-        public Object createFadeTransition(int fadingMode);
+        Object createScene(ViewGroup sceneRoot, Runnable r);
 
-        public Object createChangeTransform();
+        Object createAutoTransition();
 
-        public Object createChangeBounds(boolean reparent);
+        Object createSlide(int slideEdge);
 
-        public Object createFadeAndShortSlide(int edge);
+        Object createScale();
 
-        public Object createFadeAndShortSlide(int edge, float distance);
+        Object createFadeTransition(int fadingMode);
 
-        public void setChangeBoundsStartDelay(Object changeBounds, View view, int startDelay);
+        Object createChangeTransform();
 
-        public void setChangeBoundsStartDelay(Object changeBounds, int viewId, int startDelay);
+        Object createChangeBounds(boolean reparent);
 
-        public void setChangeBoundsStartDelay(Object changeBounds, String className,
+        Object createFadeAndShortSlide(int edge);
+
+        Object createFadeAndShortSlide(int edge, float distance);
+
+        void setChangeBoundsStartDelay(Object changeBounds, View view, int startDelay);
+
+        void setChangeBoundsStartDelay(Object changeBounds, int viewId, int startDelay);
+
+        void setChangeBoundsStartDelay(Object changeBounds, String className,
                 int startDelay);
 
-        public void setChangeBoundsDefaultStartDelay(Object changeBounds, int startDelay);
+        void setChangeBoundsDefaultStartDelay(Object changeBounds, int startDelay);
 
-        public Object createTransitionSet(boolean sequential);
+        Object createTransitionSet(boolean sequential);
 
-        public void addTransition(Object transitionSet, Object transition);
+        void addTransition(Object transitionSet, Object transition);
 
-        public void addTransitionListener(Object transition, TransitionListener listener);
+        void addTransitionListener(Object transition, TransitionListener listener);
 
-        public void removeTransitionListener(Object transition, TransitionListener listener);
+        void removeTransitionListener(Object transition, TransitionListener listener);
 
-        public void runTransition(Object scene, Object transition);
+        void runTransition(Object scene, Object transition);
 
-        public void exclude(Object transition, int targetId, boolean exclude);
+        void exclude(Object transition, int targetId, boolean exclude);
 
-        public void exclude(Object transition, View targetView, boolean exclude);
+        void exclude(Object transition, View targetView, boolean exclude);
 
-        public void excludeChildren(Object transition, int targetId, boolean exclude);
+        void excludeChildren(Object transition, int targetId, boolean exclude);
 
-        public void excludeChildren(Object transition, View target, boolean exclude);
+        void excludeChildren(Object transition, View target, boolean exclude);
 
-        public void include(Object transition, int targetId);
+        void include(Object transition, int targetId);
 
-        public void include(Object transition, View targetView);
+        void include(Object transition, View targetView);
 
-        public void setStartDelay(Object transition, long startDelay);
+        void setStartDelay(Object transition, long startDelay);
 
-        public void setDuration(Object transition, long duration);
+        void setDuration(Object transition, long duration);
 
-        public void setInterpolator(Object transition, Object timeInterpolator);
+        void setInterpolator(Object transition, Object timeInterpolator);
 
-        public void addTarget(Object transition, View view);
+        void addTarget(Object transition, View view);
 
-        public Object createDefaultInterpolator(Context context);
+        Object createDefaultInterpolator(Context context);
 
-        public Object loadTransition(Context context, int resId);
+        Object loadTransition(Context context, int resId);
 
-        public void beginDelayedTransition(ViewGroup sceneRoot, Object transitionObject);
+        void beginDelayedTransition(ViewGroup sceneRoot, Object transitionObject);
 
-        public void setTransitionGroup(ViewGroup viewGroup, boolean transitionGroup);
+        void setTransitionGroup(ViewGroup viewGroup, boolean transitionGroup);
 
-        public void setEpicenterCallback(Object transitionObject,
+        void setEpicenterCallback(Object transitionObject,
                 TransitionEpicenterCallback callback);
     }
 
@@ -195,11 +203,19 @@
         }
 
         @Override
+        public void setSharedElementEnterTransition(Window window, Object object) {
+        }
+
+        @Override
         public Object getSharedElementReturnTransition(Window window) {
             return null;
         }
 
         @Override
+        public void setSharedElementReturnTransition(Window window, Object transition) {
+        }
+
+        @Override
         public Object getSharedElementExitTransition(Window window) {
             return null;
         }
@@ -215,11 +231,19 @@
         }
 
         @Override
+        public void setEnterTransition(Window window, Object transition) {
+        }
+
+        @Override
         public Object getReturnTransition(Window window) {
             return null;
         }
 
         @Override
+        public void setReturnTransition(Window window, Object transition) {
+        }
+
+        @Override
         public Object getExitTransition(Window window) {
             return null;
         }
@@ -572,11 +596,21 @@
         }
 
         @Override
+        public void setSharedElementEnterTransition(Window window, Object object) {
+            TransitionHelperApi21.setSharedElementEnterTransition(window, object);
+        }
+
+        @Override
         public Object getSharedElementReturnTransition(Window window) {
             return TransitionHelperApi21.getSharedElementReturnTransition(window);
         }
 
         @Override
+        public void setSharedElementReturnTransition(Window window, Object transition) {
+            TransitionHelperApi21.setSharedElementReturnTransition(window, transition);
+        }
+
+        @Override
         public Object getSharedElementExitTransition(Window window) {
             return TransitionHelperApi21.getSharedElementExitTransition(window);
         }
@@ -607,11 +641,21 @@
         }
 
         @Override
+        public void setEnterTransition(Window window, Object transition) {
+            TransitionHelperApi21.setEnterTransition(window, transition);
+        }
+
+        @Override
         public Object getReturnTransition(Window window) {
             return TransitionHelperApi21.getReturnTransition(window);
         }
 
         @Override
+        public void setReturnTransition(Window window, Object transition) {
+            TransitionHelperApi21.setReturnTransition(window, transition);
+        }
+
+        @Override
         public Object getExitTransition(Window window) {
             return TransitionHelperApi21.getExitTransition(window);
         }
@@ -662,10 +706,18 @@
         return sImpl.getSharedElementEnterTransition(window);
     }
 
+    public static void setSharedElementEnterTransition(Window window, Object transition) {
+        sImpl.setSharedElementEnterTransition(window, transition);
+    }
+
     public static Object getSharedElementReturnTransition(Window window) {
         return sImpl.getSharedElementReturnTransition(window);
     }
 
+    public static void setSharedElementReturnTransition(Window window, Object transition) {
+        sImpl.setSharedElementReturnTransition(window, transition);
+    }
+
     public static Object getSharedElementExitTransition(Window window) {
         return sImpl.getSharedElementExitTransition(window);
     }
@@ -678,10 +730,18 @@
         return sImpl.getEnterTransition(window);
     }
 
+    public static void setEnterTransition(Window window, Object transition) {
+        sImpl.setEnterTransition(window, transition);
+    }
+
     public static Object getReturnTransition(Window window) {
         return sImpl.getReturnTransition(window);
     }
 
+    public static void setReturnTransition(Window window, Object transition) {
+        sImpl.setReturnTransition(window, transition);
+    }
+
     public static Object getExitTransition(Window window) {
         return sImpl.getExitTransition(window);
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/util/StateMachine.java b/v17/leanback/src/android/support/v17/leanback/util/StateMachine.java
index a00bbc5..dfc228c 100644
--- a/v17/leanback/src/android/support/v17/leanback/util/StateMachine.java
+++ b/v17/leanback/src/android/support/v17/leanback/util/StateMachine.java
@@ -16,42 +16,169 @@
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
 import android.support.annotation.RestrictTo;
+import android.util.Log;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
 
 /**
- * Linear or DAG of {@link State}s. StateMachine is by default a linear model, until
- * {@link #addState(State, State)} is called.  Each State has three status:
- * STATUS_ZERO, STATUS_INVOKED, STATUS_EXECUTED.   We allow client to run a State, which will
- * put State in STATUS_INVOKED.  A State will be executed when prior States are executed and
- * Precondition for this State is true, then the State will be marked as STATUS_EXECUTED.
- *
+ * State: each State has incoming Transitions and outgoing Transitions.
+ * When {@link State#mBranchStart} is true, all the outgoing Transitions may be triggered, when
+ * {@link State#mBranchStart} is false, only first outgoing Transition will be triggered.
+ * When {@link State#mBranchEnd} is true, all the incoming Transitions must be triggered for the
+ * State to run. When {@link State#mBranchEnd} is false, only need one incoming Transition triggered
+ * for the State to run.
+ * Transition: three types:
+ * 1. Event based transition, transition will be triggered when {@link #fireEvent(Event)} is called.
+ * 2. Auto transition, transition will be triggered when {@link Transition#mFromState} is executed.
+ * 3. Condiitonal Auto transition, transition will be triggered when {@link Transition#mFromState}
+ * is executed and {@link Transition#mCondition} passes.
  * @hide
  */
 @RestrictTo(LIBRARY_GROUP)
 public final class StateMachine {
 
+    static boolean DEBUG = false;
+    static final String TAG = "StateMachine";
+
     /**
      * No request on the State
      */
     public static final int STATUS_ZERO = 0;
+
     /**
-     * Somebody wants to run the state but not yet executed because either the condition is
-     * false or lower States are not executed.
+     * Has been executed
      */
     public static final int STATUS_INVOKED = 1;
-    /**
-     * Somebody wants to run the State and the State was executed.
-     */
-    public static final int STATUS_EXECUTED = 2;
 
+    /**
+     * Used in Transition
+     */
+    public static class Event {
+        final String mName;
+
+        public Event(String name) {
+            mName = name;
+        }
+    }
+
+    /**
+     * Used in transition
+     */
+    public static class Condition {
+        final String mName;
+
+        public Condition(String name) {
+            mName = name;
+        }
+
+        /**
+         * @return True if can proceed and mark the transition INVOKED
+         */
+        public boolean canProceed() {
+            return true;
+        }
+    }
+
+    static class Transition {
+        final State mFromState;
+        final State mToState;
+        final Event mEvent;
+        final Condition mCondition;
+        int mState = STATUS_ZERO;
+
+        Transition(State fromState, State toState, Event event) {
+            if (event == null) {
+                throw new IllegalArgumentException();
+            }
+            mFromState = fromState;
+            mToState = toState;
+            mEvent = event;
+            mCondition = null;
+        }
+
+        Transition(State fromState, State toState) {
+            mFromState = fromState;
+            mToState = toState;
+            mEvent = null;
+            mCondition = null;
+        }
+
+        Transition(State fromState, State toState, Condition condition) {
+            if (condition == null) {
+                throw new IllegalArgumentException();
+            }
+            mFromState = fromState;
+            mToState = toState;
+            mEvent = null;
+            mCondition = condition;
+        }
+
+        @Override
+        public String toString() {
+            String signalName;
+            if (mEvent != null) {
+                signalName = mEvent.mName;
+            } else if (mCondition != null) {
+                signalName = mCondition.mName;
+            } else {
+                signalName = "auto";
+            }
+            return "[" + mFromState.mName + " -> " + mToState.mName + " <"
+                    + signalName + ">]";
+        }
+    }
+
+    /**
+     * @see StateMachine
+     */
     public static class State {
 
-        private int mStatus;
-        ArrayList<State> mPriorStates;
+        final String mName;
+        final boolean mBranchStart;
+        final boolean mBranchEnd;
+        int mStatus = STATUS_ZERO;
+        int mInvokedOutTransitions = 0;
+        ArrayList<Transition> mIncomings;
+        ArrayList<Transition> mOutgoings;
+
+        @Override
+        public String toString() {
+            return "[" + mName + " " + mStatus + "]";
+        }
+
+        /**
+         * Create a State which is not branch start and a branch end.
+         */
+        public State(String name) {
+            this(name, false, true);
+        }
+
+        /**
+         * Create a State
+         * @param branchStart True if can run all out going transitions or false execute the first
+         *                    out going transition.
+         * @param branchEnd True if wait all incoming transitions executed or false
+         *                              only need one of the transition executed.
+         */
+        public State(String name, boolean branchStart, boolean branchEnd) {
+            mName = name;
+            mBranchStart = branchStart;
+            mBranchEnd = branchEnd;
+        }
+
+        void addIncoming(Transition t) {
+            if (mIncomings == null) {
+                mIncomings = new ArrayList();
+            }
+            mIncomings.add(t);
+        }
+
+        void addOutgoing(Transition t) {
+            if (mOutgoings == null) {
+                mOutgoings = new ArrayList();
+            }
+            mOutgoings.add(t);
+        }
 
         /**
          * Run State, Subclass may override.
@@ -59,166 +186,194 @@
         public void run() {
         }
 
-        /**
-         * Returns true if State can run, false otherwise.  Subclass may override.
-         * @return True if State can run, false otherwise.  Subclass may override.
-         */
-        public boolean canRun() {
-            return true;
+        final boolean checkPreCondition() {
+            if (mIncomings == null) {
+                return true;
+            }
+            if (mBranchEnd) {
+                for (Transition t: mIncomings) {
+                    if (t.mState != STATUS_INVOKED) {
+                        return false;
+                    }
+                }
+                return true;
+            } else {
+                for (Transition t: mIncomings) {
+                    if (t.mState == STATUS_INVOKED) {
+                        return true;
+                    }
+                }
+                return false;
+            }
         }
 
         /**
          * @return True if the State has been executed.
          */
         final boolean runIfNeeded() {
-            if (mStatus!= STATUS_EXECUTED) {
-                if (mStatus == STATUS_INVOKED && canRun()) {
+            if (mStatus != STATUS_INVOKED) {
+                if (checkPreCondition()) {
+                    if (DEBUG) {
+                        Log.d(TAG, "execute " + this);
+                    }
+                    mStatus = STATUS_INVOKED;
                     run();
-                    mStatus = STATUS_EXECUTED;
-                } else {
-                    return false;
+                    signalAutoTransitionsAfterRun();
+                    return true;
                 }
             }
-            return true;
+            return false;
         }
 
-        void addPriorState(State state) {
-            if (mPriorStates == null) {
-                mPriorStates = new ArrayList<State>();
+        final void signalAutoTransitionsAfterRun() {
+            if (mOutgoings != null) {
+                for (Transition t: mOutgoings) {
+                    if (t.mEvent == null) {
+                        if (t.mCondition == null || t.mCondition.canProceed()) {
+                            if (DEBUG) {
+                                Log.d(TAG, "signal " + t);
+                            }
+                            mInvokedOutTransitions++;
+                            t.mState = STATUS_INVOKED;
+                            if (!mBranchStart) {
+                                break;
+                            }
+                        }
+                    }
+                }
             }
-            if (!mPriorStates.contains(state)) {
-                mPriorStates.add(state);
-            }
-        }
-
-        final void markInvoked() {
-            if (mStatus == STATUS_ZERO) {
-                mStatus = STATUS_INVOKED;
-            }
-        }
-
-        final void updateStatus(int status) {
-            mStatus = status;
         }
 
         /**
-         * Get status, return one of {@link #STATUS_ZERO}, {@link #STATUS_INVOKED},
-         * {@link #STATUS_EXECUTED}.
+         * Get status, return one of {@link #STATUS_ZERO}, {@link #STATUS_INVOKED}.
          * @return Status of the State.
          */
         public final int getStatus() {
             return mStatus;
         }
-
-        @Override
-        public final boolean equals(Object other) {
-            return this == other;
-        }
     }
 
-    private boolean mSorted = true;
-    private final ArrayList<State> mSortedList = new ArrayList<State>();
+    final ArrayList<State> mStates = new ArrayList<State>();
+    final ArrayList<State> mFinishedStates = new ArrayList();
+    final ArrayList<State> mUnfinishedStates = new ArrayList();
+
+    public StateMachine() {
+    }
 
     /**
      * Add a State to StateMachine, ignore if it is already added.
      * @param state The state to add.
      */
     public void addState(State state) {
-        if (!mSortedList.contains(state)) {
-            state.updateStatus(STATUS_ZERO);
-            mSortedList.add(state);
+        if (!mStates.contains(state)) {
+            mStates.add(state);
         }
     }
 
     /**
-     * Add two States to StateMachine and create an edge between this two.
-     * StateMachine is by default a linear model, until {@link #addState(State, State)} is called.
-     * sort() is required to sort the Direct acyclic graph.
+     * Add event-triggered transition between two states.
+     * @param fromState The from state.
+     * @param toState The to state.
+     * @param event The event that needed to perform the transition.
+     */
+    public void addTransition(State fromState, State toState, Event event) {
+        Transition transition = new Transition(fromState, toState, event);
+        toState.addIncoming(transition);
+        fromState.addOutgoing(transition);
+    }
+
+    /**
+     * Add a conditional auto transition between two states.
+     * @param fromState The from state.
+     * @param toState The to state.
+     */
+    public void addTransition(State fromState, State toState, Condition condition) {
+        Transition transition = new Transition(fromState, toState, condition);
+        toState.addIncoming(transition);
+        fromState.addOutgoing(transition);
+    }
+
+    /**
+     * Add an auto transition between two states.
      * @param fromState The from state to add.
      * @param toState The to state to add.
      */
-    public void addState(State fromState, State toState) {
-        addState(fromState);
-        addState(toState);
-        toState.addPriorState(fromState);
-        mSorted = false;
-    }
-
-    void verifySorted() {
-        if (!mSorted) {
-            throw new RuntimeException("Graph not sorted");
-        }
-    }
-
-    public void runState(State state) {
-        verifySorted();
-        state.markInvoked();
-        runPendingStates();
-    }
-
-    public void runPendingStates() {
-        verifySorted();
-        for (int i = 0, size = mSortedList.size(); i < size; i++) {
-            if (!mSortedList.get(i).runIfNeeded()) {
-                break;
-            }
-        }
-    }
-
-    public void resetStatus() {
-        for (int i = 0, size = mSortedList.size(); i < size; i++) {
-            mSortedList.get(i).updateStatus(STATUS_ZERO);
-        }
+    public void addTransition(State fromState, State toState) {
+        Transition transition = new Transition(fromState, toState);
+        toState.addIncoming(transition);
+        fromState.addOutgoing(transition);
     }
 
     /**
-     * StateMachine is by default a linear model, until {@link #addState(State, State)} is called.
-     * sort() is required to sort the Direct acyclic graph.
+     * Start the state machine.
      */
-    public void sort() {
-        if (mSorted) {
-            return;
+    public void start() {
+        if (DEBUG) {
+            Log.d(TAG, "start");
         }
-        // L: Empty list that will contain the sorted States
-        ArrayList<State> L = new ArrayList<State>();
-        // S: Set of all nodes with no incoming edges
-        ArrayList<State> S = new ArrayList<State>();
-        HashMap<State, ArrayList<State>> edges = new HashMap<State, ArrayList<State>>();
-        for (int i = mSortedList.size() - 1; i >= 0 ; i--) {
-            State state = mSortedList.get(i);
-            if (state.mPriorStates != null && state.mPriorStates.size() > 0) {
-                edges.put(state, new ArrayList<State>(state.mPriorStates));
-            } else {
-                S.add(state);
-            }
-        }
+        mUnfinishedStates.addAll(mStates);
+        runUnfinishedStates();
+    }
 
-        while (!S.isEmpty()) {
-            // remove a State without incoming Node from S, add to L
-            State state = S.remove(S.size() - 1);
-            L.add(state);
-            // for each toState that having an incoming edge from "state":
-            for (Iterator<Map.Entry<State, ArrayList<State>>> iterator =
-                    edges.entrySet().iterator(); iterator.hasNext();) {
-                Map.Entry<State, ArrayList<State>> entry = iterator.next();
-                ArrayList<State> fromStates = entry.getValue();
-                // remove edge from graph
-                if (fromStates.remove(state)) {
-                    if (fromStates.size() == 0) {
-                        State toState = entry.getKey();
-                        // insert the toState to S if it has no more incoming edges
-                        S.add(toState);
-                        iterator.remove();
+    void runUnfinishedStates() {
+        boolean changed;
+        do {
+            changed = false;
+            for (int i = mUnfinishedStates.size() - 1; i >= 0; i--) {
+                State state = mUnfinishedStates.get(i);
+                if (state.runIfNeeded()) {
+                    mUnfinishedStates.remove(i);
+                    mFinishedStates.add(state);
+                    changed = true;
+                }
+            }
+        } while (changed);
+    }
+
+    /**
+     * Find outgoing Transitions of invoked State whose Event matches, mark the Transition invoked.
+     */
+    public void fireEvent(Event event) {
+        for (int i = 0; i < mFinishedStates.size(); i++) {
+            State state = mFinishedStates.get(i);
+            if (state.mOutgoings != null) {
+                if (!state.mBranchStart && state.mInvokedOutTransitions > 0) {
+                    continue;
+                }
+                for (Transition t : state.mOutgoings) {
+                    if (t.mState != STATUS_INVOKED && t.mEvent == event) {
+                        if (DEBUG) {
+                            Log.d(TAG, "signal " + t);
+                        }
+                        t.mState = STATUS_INVOKED;
+                        state.mInvokedOutTransitions++;
+                        if (!state.mBranchStart) {
+                            break;
+                        }
                     }
                 }
             }
         }
-        if (edges.size() > 0) {
-            throw new RuntimeException("Cycle in Graph");
-        }
+        runUnfinishedStates();
+    }
 
-        mSortedList.clear();
-        mSortedList.addAll(L);
-        mSorted = true;
+    /**
+     * Reset status to orignal status
+     */
+    public void reset() {
+        if (DEBUG) {
+            Log.d(TAG, "reset");
+        }
+        mUnfinishedStates.clear();
+        mFinishedStates.clear();
+        for (State state: mStates) {
+            state.mStatus = STATUS_ZERO;
+            state.mInvokedOutTransitions = 0;
+            if (state.mOutgoings != null) {
+                for (Transition t: state.mOutgoings) {
+                    t.mState = STATUS_ZERO;
+                }
+            }
+        }
     }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaItemPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaItemPresenter.java
index c607d64..196fa93 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaItemPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaItemPresenter.java
@@ -372,7 +372,7 @@
          * @param position The index of the child view to display.
          */
         public void setSelectedMediaItemNumberView(int position) {
-            if (position >= 0 & position < mMediaItemNumberViewFlipper.getChildCount()) {
+            if (position >= 0 && position < mMediaItemNumberViewFlipper.getChildCount()) {
                 mMediaItemNumberViewFlipper.setDisplayedChild(position);
             }
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ActionPresenterSelector.java b/v17/leanback/src/android/support/v17/leanback/widget/ActionPresenterSelector.java
index 1064c45..1ced4d4 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ActionPresenterSelector.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ActionPresenterSelector.java
@@ -55,7 +55,7 @@
         }
     }
 
-    class OneLineActionPresenter extends Presenter {
+    static class OneLineActionPresenter extends Presenter {
         @Override
         public ViewHolder onCreateViewHolder(ViewGroup parent) {
             View v = LayoutInflater.from(parent.getContext())
@@ -77,7 +77,7 @@
         }
     }
 
-    class TwoLineActionPresenter extends Presenter {
+    static class TwoLineActionPresenter extends Presenter {
         @Override
         public ViewHolder onCreateViewHolder(ViewGroup parent) {
             View v = LayoutInflater.from(parent.getContext())
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ArrayObjectAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/ArrayObjectAdapter.java
index 68190d4..b31d30a 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ArrayObjectAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ArrayObjectAdapter.java
@@ -90,7 +90,7 @@
 
     /**
      * Inserts an item into this adapter at the specified index.
-     * If the index is >= {@link #size} an exception will be thrown.
+     * If the index is > {@link #size} an exception will be thrown.
      *
      * @param index The index at which the item should be inserted.
      * @param item The item to insert into the adapter.
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/BaseCardView.java b/v17/leanback/src/android/support/v17/leanback/widget/BaseCardView.java
index b9c4948..9ca331fe 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/BaseCardView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/BaseCardView.java
@@ -681,6 +681,8 @@
         if (mAnim != null) {
             mAnim.cancel();
             mAnim = null;
+            // force-clear the animation, as Animation#cancel() doesn't work prior to N,
+            // and will instead cause the animation to infinitely loop
             clearAnimation();
         }
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java b/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
index 005a441..08c4b883 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
@@ -197,7 +197,7 @@
     /**
      * Number of items to prefetch when first coming on screen with new data.
      */
-    int mInitialItemPrefetchCount = 4;
+    int mInitialPrefetchItemCount = 4;
 
     public BaseGridView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
@@ -1004,21 +1004,39 @@
 
     /**
      * Temporarily slide out child views to bottom (for VerticalGridView) or end
-     * (for HorizontalGridView). The views will be automatically slide-in in next
-     * {@link #smoothScrollToPosition(int)} or {@link #scrollToPosition(int)}.
+     * (for HorizontalGridView). Layout and scrolling will be suppressed until
+     * {@link #animateIn()} is called.
      */
     public void animateOut() {
         mLayoutManager.slideOut();
     }
 
     /**
-     * @deprecated No longer needed. Children being slide out by {@link #animateOut()} will be
-     * slide in next focus or (smooth)scrollToPosition action.
+     * Undo animateOut() and slide in child views.
      */
-    @Deprecated
     public void animateIn() {
+        mLayoutManager.slideIn();
     }
 
+    @Override
+    public void scrollToPosition(int position) {
+        // dont abort the animateOut() animation, just record the position
+        if (mLayoutManager.mIsSlidingChildViews) {
+            mLayoutManager.setSelectionWithSub(position, 0, 0);
+            return;
+        }
+        super.scrollToPosition(position);
+    }
+
+    @Override
+    public void smoothScrollToPosition(int position) {
+        // dont abort the animateOut() animation, just record the position
+        if (mLayoutManager.mIsSlidingChildViews) {
+            mLayoutManager.setSelectionWithSub(position, 0, 0);
+            return;
+        }
+        super.smoothScrollToPosition(position);
+    }
 
     /**
      * Sets the number of items to prefetch in
@@ -1045,12 +1063,12 @@
      *
      * @param itemCount Number of items to prefetch
      *
-     * @see #getInitialItemPrefetchCount()
+     * @see #getInitialPrefetchItemCount()
      * @see RecyclerView.LayoutManager#isItemPrefetchEnabled()
      * @see RecyclerView.LayoutManager#collectInitialPrefetchPositions(int, RecyclerView.LayoutManager.LayoutPrefetchRegistry)
      */
     public void setInitialPrefetchItemCount(int itemCount) {
-        mInitialItemPrefetchCount = itemCount;
+        mInitialPrefetchItemCount = itemCount;
     }
 
     /**
@@ -1065,7 +1083,7 @@
      *
      * @return number of items to prefetch.
      */
-    public int getInitialItemPrefetchCount() {
-        return mInitialItemPrefetchCount;
+    public int getInitialPrefetchItemCount() {
+        return mInitialPrefetchItemCount;
     }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ControlBar.java b/v17/leanback/src/android/support/v17/leanback/widget/ControlBar.java
index 7146371..be5fd83 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ControlBar.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ControlBar.java
@@ -17,8 +17,11 @@
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.View;
+import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
+import java.util.ArrayList;
+
 class ControlBar extends LinearLayout {
 
     public interface OnChildFocusedListener {
@@ -27,6 +30,7 @@
 
     private int mChildMarginFromCenter;
     private OnChildFocusedListener mOnChildFocusedListener;
+    int mLastFocusIndex = -1;
 
     public ControlBar(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -37,13 +41,28 @@
     }
 
     @Override
-    public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
         if (getChildCount() > 0) {
-            if (getChildAt(getChildCount() / 2).requestFocus(direction, previouslyFocusedRect)) {
+            int index = mLastFocusIndex >= 0 && mLastFocusIndex < getChildCount()
+                    ? mLastFocusIndex : getChildCount() / 2;
+            if (getChildAt(index).requestFocus(direction, previouslyFocusedRect)) {
                 return true;
             }
         }
-        return super.requestFocus(direction, previouslyFocusedRect);
+        return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
+    }
+
+    @Override
+    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+        if ((direction == ViewGroup.FOCUS_UP || direction == ViewGroup.FOCUS_DOWN)) {
+            if (mLastFocusIndex >= 0 && mLastFocusIndex < getChildCount()) {
+                views.add(getChildAt(mLastFocusIndex));
+            } else if (getChildCount() > 0) {
+                views.add(getChildAt(getChildCount() / 2));
+            }
+        } else {
+            super.addFocusables(views, direction, focusableMode);
+        }
     }
 
     public void setOnChildFocusedListener(OnChildFocusedListener listener) {
@@ -57,6 +76,7 @@
     @Override
     public void requestChildFocus (View child, View focused) {
         super.requestChildFocus(child, focused);
+        mLastFocusIndex = indexOfChild(child);
         if (mOnChildFocusedListener != null) {
             mOnChildFocusedListener.onChildFocusedListener(child, focused);
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewSharedElementHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewSharedElementHelper.java
index 0bd03f1..50f0da3 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewSharedElementHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewSharedElementHelper.java
@@ -182,8 +182,8 @@
 
     void setSharedElementEnterTransition(Activity activity, String sharedElementName,
             long timeoutMs) {
-        if (activity == null && !TextUtils.isEmpty(sharedElementName)
-                || activity != null && TextUtils.isEmpty(sharedElementName)) {
+        if ((activity == null && !TextUtils.isEmpty(sharedElementName))
+                || (activity != null && TextUtils.isEmpty(sharedElementName))) {
             throw new IllegalArgumentException();
         }
         if (activity == mActivityToRunTransition
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallax.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallax.java
index 374485d..ad5f13a 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallax.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallax.java
@@ -34,19 +34,17 @@
  * @see android.support.v17.leanback.app.DetailsSupportFragmentBackgroundController
  */
 public class DetailsParallax extends RecyclerViewParallax {
-    final Parallax.IntProperty mFrameTop;
-    final Parallax.IntProperty mFrameBottom;
+    final IntProperty mFrameTop;
+    final IntProperty mFrameBottom;
 
     public DetailsParallax() {
         // track the top edge of details_frame of first item of adapter
-        mFrameTop = this
-                .addProperty("overviewRowTop")
+        mFrameTop = addProperty("overviewRowTop")
                 .adapterPosition(0)
                 .viewId(R.id.details_frame);
 
         // track the bottom edge of details_frame of first item of adapter
-        mFrameBottom = this
-                .addProperty("overviewRowBottom")
+        mFrameBottom = addProperty("overviewRowBottom")
                 .adapterPosition(0)
                 .viewId(R.id.details_frame)
                 .fraction(1.0f);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallaxDrawable.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallaxDrawable.java
index d77bc44..37e3480 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallaxDrawable.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsParallaxDrawable.java
@@ -23,7 +23,6 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.ColorInt;
 import android.support.v17.leanback.R;
-import android.support.v17.leanback.graphics.BoundsRule;
 import android.support.v17.leanback.graphics.CompositeDrawable;
 import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
 import android.util.TypedValue;
@@ -124,8 +123,6 @@
         }
         addChildDrawable(coverDrawable);
         addChildDrawable(mBottomDrawable = bottomDrawable);
-        getChildAt(0).getBoundsRule().bottom = BoundsRule.inheritFromParent(1f);
-        getChildAt(1).getBoundsRule().top = BoundsRule.inheritFromParent(1f);
         connect(context, parallax, coverDrawableParallaxTarget);
     }
 
@@ -179,23 +176,18 @@
                 .getDimensionPixelSize(R.dimen.lb_details_v2_align_pos_for_actions);
         final int toValue = context.getResources()
                 .getDimensionPixelSize(R.dimen.lb_details_v2_align_pos_for_description);
-        parallax
-                .addEffect(frameTop.atAbsolute(fromValue), frameTop.atAbsolute(toValue))
+        parallax.addEffect(frameTop.atAbsolute(fromValue), frameTop.atAbsolute(toValue))
                 .target(coverDrawableParallaxTarget);
 
         // Add solid color parallax effect:
         // When frameBottom moves from bottom of the screen to top of the screen,
         // change solid ColorDrawable's top from bottom of screen to top of the screen.
-        parallax.addEffect(frameBottom.atFraction(1f), frameBottom.atFraction(0f))
-                .target(getChildAt(1),
-                        PropertyValuesHolder.ofFloat(
-                                CompositeDrawable.ChildDrawable.TOP_FRACTION, 1f, 0f));
+        parallax.addEffect(frameBottom.atMax(), frameBottom.atMin())
+                .target(getChildAt(1), ChildDrawable.TOP_ABSOLUTE);
         // Also when frameTop moves from bottom of screen to top of the screen,
         // we are changing bottom of the bitmap from bottom of screen to top of screen.
-        parallax.addEffect(frameTop.atFraction(1f), frameTop.atFraction(0f))
-                .target(getChildAt(0),
-                        PropertyValuesHolder.ofFloat(
-                                CompositeDrawable.ChildDrawable.BOTTOM_FRACTION, 1f, 0f));
+        parallax.addEffect(frameTop.atMax(), frameTop.atMin())
+                .target(getChildAt(0), ChildDrawable.BOTTOM_ABSOLUTE);
     }
 
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHelper.java
index 728d31f..988a9fc2 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHelper.java
@@ -251,7 +251,7 @@
             }
         }
 
-        class HeaderFocusAnimator extends FocusAnimator {
+        static class HeaderFocusAnimator extends FocusAnimator {
 
             ItemBridgeAdapter.ViewHolder mViewHolder;
             HeaderFocusAnimator(View view, float scale, int duration) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewSharedElementHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewSharedElementHelper.java
index 570a7f2..c2d57b6 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewSharedElementHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewSharedElementHelper.java
@@ -74,8 +74,8 @@
 
     public void setSharedElementEnterTransition(Activity activity, String sharedElementName,
             long timeoutMs) {
-        if (activity == null && !TextUtils.isEmpty(sharedElementName)
-                || activity != null && TextUtils.isEmpty(sharedElementName)) {
+        if ((activity == null && !TextUtils.isEmpty(sharedElementName))
+                || (activity != null && TextUtils.isEmpty(sharedElementName))) {
             throw new IllegalArgumentException();
         }
         if (activity == mActivityToRunTransition
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 5569836..2c9f069 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
@@ -16,6 +16,7 @@
 import static android.support.v7.widget.RecyclerView.HORIZONTAL;
 import static android.support.v7.widget.RecyclerView.NO_ID;
 import static android.support.v7.widget.RecyclerView.NO_POSITION;
+import static android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE;
 import static android.support.v7.widget.RecyclerView.VERTICAL;
 
 import android.content.Context;
@@ -208,6 +209,10 @@
                 super.onStop();
                 return;
             }
+            if (mFocusPosition != getTargetPosition()) {
+                // This should not happen since we cropped value in startPositionSmoothScroller()
+                mFocusPosition = getTargetPosition();
+            }
             if (hasFocus()) {
                 mInSelection = true;
                 targetView.requestFocus();
@@ -379,6 +384,7 @@
 
     // Represents whether child views are temporarily sliding out
     boolean mIsSlidingChildViews;
+    boolean mLayoutEatenInSliding;
 
     String getTag() {
         return TAG + ":" + mBaseGridView.getId();
@@ -871,7 +877,7 @@
             // when item is removed, the position value can be any value.
             return NO_POSITION;
         }
-        return params.getViewPosition();
+        return params.getViewAdapterPosition();
     }
 
     int getSubPositionByView(View view, View childView) {
@@ -1649,14 +1655,14 @@
                 ? Gravity.getAbsoluteGravity(mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK,
                 View.LAYOUT_DIRECTION_RTL)
                 : mGravity & Gravity.HORIZONTAL_GRAVITY_MASK;
-        if (mOrientation == HORIZONTAL && verticalGravity == Gravity.TOP
-                || mOrientation == VERTICAL && horizontalGravity == Gravity.LEFT) {
+        if ((mOrientation == HORIZONTAL && verticalGravity == Gravity.TOP)
+                || (mOrientation == VERTICAL && horizontalGravity == Gravity.LEFT)) {
             // do nothing
-        } else if (mOrientation == HORIZONTAL && verticalGravity == Gravity.BOTTOM
-                || mOrientation == VERTICAL && horizontalGravity == Gravity.RIGHT) {
+        } else if ((mOrientation == HORIZONTAL && verticalGravity == Gravity.BOTTOM)
+                || (mOrientation == VERTICAL && horizontalGravity == Gravity.RIGHT)) {
             startSecondary += getRowSizeSecondary(rowIndex) - sizeSecondary;
-        } else if (mOrientation == HORIZONTAL && verticalGravity == Gravity.CENTER_VERTICAL
-                || mOrientation == VERTICAL && horizontalGravity == Gravity.CENTER_HORIZONTAL) {
+        } else if ((mOrientation == HORIZONTAL && verticalGravity == Gravity.CENTER_VERTICAL)
+                || (mOrientation == VERTICAL && horizontalGravity == Gravity.CENTER_HORIZONTAL)) {
             startSecondary += (getRowSizeSecondary(rowIndex) - sizeSecondary) / 2;
         }
         int left, top, right, bottom;
@@ -1738,40 +1744,86 @@
         return mGrid.appendOneColumnVisibleItems();
     }
 
+    void slideIn() {
+        if (mIsSlidingChildViews) {
+            mIsSlidingChildViews = false;
+            if (mFocusPosition >= 0) {
+                scrollToSelection(mFocusPosition, mSubFocusPosition, true, mPrimaryScrollExtra);
+            } else {
+                mLayoutEatenInSliding = false;
+                requestLayout();
+            }
+            if (mLayoutEatenInSliding) {
+                mLayoutEatenInSliding = false;
+                if (mBaseGridView.getScrollState() != SCROLL_STATE_IDLE || isSmoothScrolling()) {
+                    mBaseGridView.addOnScrollListener(new RecyclerView.OnScrollListener() {
+                        @Override
+                        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+                            if (newState == SCROLL_STATE_IDLE) {
+                                mBaseGridView.removeOnScrollListener(this);
+                                requestLayout();
+                            }
+                        }
+                    });
+                } else {
+                    requestLayout();
+                }
+            }
+        }
+    }
+
+    int getSlideOutDistance() {
+        int distance;
+        if (mOrientation == VERTICAL) {
+            distance = -getHeight();
+            if (getChildCount() > 0) {
+                int top = getChildAt(0).getTop();
+                if (top < 0) {
+                    // scroll more if first child is above top edge
+                    distance = distance + top;
+                }
+            }
+        } else {
+            if (mReverseFlowPrimary) {
+                distance = getWidth();
+                if (getChildCount() > 0) {
+                    int start = getChildAt(0).getRight();
+                    if (start > distance) {
+                        // scroll more if first child is outside right edge
+                        distance = start;
+                    }
+                }
+            } else {
+                distance = -getWidth();
+                if (getChildCount() > 0) {
+                    int start = getChildAt(0).getLeft();
+                    if (start < 0) {
+                        // scroll more if first child is out side left edge
+                        distance = distance + start;
+                    }
+                }
+            }
+        }
+        return distance;
+    }
+
     /**
-     * Temporarily slide out child and will be auto slide-in in next scrollToView().
+     * Temporarily slide out child and block layout and scroll requests.
      */
     void slideOut() {
         if (mIsSlidingChildViews) {
             return;
         }
         mIsSlidingChildViews = true;
+        if (getChildCount() == 0) {
+            return;
+        }
         if (mOrientation == VERTICAL) {
-            int distance = -getHeight();
-            int top = getChildAt(0).getTop();
-            if (top < 0) {
-                // scroll more if first child is above top edge
-                distance = distance + top;
-            }
-            mBaseGridView.smoothScrollBy(0, distance, new AccelerateDecelerateInterpolator());
+            mBaseGridView.smoothScrollBy(0, getSlideOutDistance(),
+                    new AccelerateDecelerateInterpolator());
         } else {
-            int distance;
-            if (mReverseFlowPrimary) {
-                distance = getWidth();
-                int start = getChildAt(0).getRight();
-                if (start > distance) {
-                    // scroll more if first child is outside right edge
-                    distance = start;
-                }
-            } else {
-                distance = -getWidth();
-                int start = getChildAt(0).getLeft();
-                if (start < 0) {
-                    // scroll more if first child is out side left edge
-                    distance = distance + start;
-                }
-            }
-            mBaseGridView.smoothScrollBy(distance, 0, new AccelerateDecelerateInterpolator());
+            mBaseGridView.smoothScrollBy(getSlideOutDistance(), 0,
+                    new AccelerateDecelerateInterpolator());
         }
     }
 
@@ -1936,6 +1988,14 @@
             return;
         }
 
+        if (mIsSlidingChildViews) {
+            // if there is already children, delay the layout process until slideIn(), if it's
+            // first time layout children: scroll them offscreen at end of onLayoutChildren()
+            if (getChildCount() > 0) {
+                mLayoutEatenInSliding = true;
+                return;
+            }
+        }
         if (!mLayoutEnabled) {
             discardLayoutInfo();
             removeAndRecycleAllViews(recycler);
@@ -1983,10 +2043,6 @@
 
         if (mInFastRelayout = layoutInit()) {
             fastRelayout();
-            // appends items till focus position.
-            if (mFocusPosition != NO_POSITION) {
-                scrollToFocusViewInLayout(hadFocus, scrollToFocus);
-            }
         } else {
             mInLayoutSearchFocus = hadFocus;
             if (mFocusPosition != NO_POSITION) {
@@ -1994,23 +2050,24 @@
                 while (appendOneColumnVisibleItems()
                         && findViewByPosition(mFocusPosition) == null) ;
             }
-            // multiple rounds: scrollToView of first round may drag first/last child into
-            // "visible window" and we update scrollMin/scrollMax then run second scrollToView
-            int oldFirstVisible;
-            int oldLastVisible;
-            do {
-                updateScrollMin();
-                updateScrollMax();
-                oldFirstVisible = mGrid.getFirstVisibleIndex();
-                oldLastVisible = mGrid.getLastVisibleIndex();
-                scrollToFocusViewInLayout(hadFocus, true);
-                appendVisibleItems();
-                prependVisibleItems();
-                removeInvisibleViewsAtFront();
-                removeInvisibleViewsAtEnd();
-            } while (mGrid.getFirstVisibleIndex() != oldFirstVisible
-                    || mGrid.getLastVisibleIndex() != oldLastVisible);
         }
+        // multiple rounds: scrollToView of first round may drag first/last child into
+        // "visible window" and we update scrollMin/scrollMax then run second scrollToView
+        // we must do this for fastRelayout() for the append item case
+        int oldFirstVisible;
+        int oldLastVisible;
+        do {
+            updateScrollMin();
+            updateScrollMax();
+            oldFirstVisible = mGrid.getFirstVisibleIndex();
+            oldLastVisible = mGrid.getLastVisibleIndex();
+            scrollToFocusViewInLayout(hadFocus, scrollToFocus);
+            appendVisibleItems();
+            prependVisibleItems();
+            removeInvisibleViewsAtFront();
+            removeInvisibleViewsAtEnd();
+        } while (mGrid.getFirstVisibleIndex() != oldFirstVisible
+                || mGrid.getLastVisibleIndex() != oldLastVisible);
 
         if (scrollToFocus) {
             scrollDirectionPrimary(-delta);
@@ -2045,6 +2102,9 @@
         }
         dispatchChildSelectedAndPositioned();
 
+        if (mIsSlidingChildViews) {
+            scrollDirectionPrimary(getSlideOutDistance());
+        }
         mInLayout = false;
         leaveContext();
         if (DEBUG) Log.v(getTag(), "layoutChildren end");
@@ -2211,7 +2271,7 @@
     @Override
     public void collectInitialPrefetchPositions(int adapterItemCount,
             LayoutPrefetchRegistry layoutPrefetchRegistry) {
-        int numToPrefetch = mBaseGridView.mInitialItemPrefetchCount;
+        int numToPrefetch = mBaseGridView.mInitialPrefetchItemCount;
         if (adapterItemCount != 0 && numToPrefetch != 0) {
             // prefetch items centered around mFocusPosition
             int initialPos = Math.max(0, Math.min(mFocusPosition - (numToPrefetch - 1)/ 2,
@@ -2385,7 +2445,7 @@
 
     public void setSelection(int position, int subposition, boolean smooth,
             int primaryScrollExtra) {
-        if (mIsSlidingChildViews || mFocusPosition != position && position != NO_POSITION
+        if ((mFocusPosition != position && position != NO_POSITION)
                 || subposition != mSubFocusPosition || primaryScrollExtra != mPrimaryScrollExtra) {
             scrollToSelection(position, subposition, smooth, primaryScrollExtra);
         }
@@ -2404,7 +2464,7 @@
             mFocusPosition = position;
             mSubFocusPosition = subposition;
             mFocusPositionOffset = Integer.MIN_VALUE;
-            if (!mLayoutEnabled) {
+            if (!mLayoutEnabled || mIsSlidingChildViews) {
                 return;
             }
             if (smooth) {
@@ -2413,7 +2473,12 @@
                             + "not be called before first layout pass");
                     return;
                 }
-                startPositionSmoothScroller(position);
+                position = startPositionSmoothScroller(position);
+                if (position != mFocusPosition) {
+                    // gets cropped by adapter size
+                    mFocusPosition = position;
+                    mSubFocusPosition = 0;
+                }
             } else {
                 mForceFullLayout = true;
                 requestLayout();
@@ -2422,7 +2487,7 @@
         if (TRACE) TraceCompat.endSection();
     }
 
-    void startPositionSmoothScroller(int position) {
+    int startPositionSmoothScroller(int position) {
         LinearSmoothScroller linearSmoothScroller = new GridLinearSmoothScroller() {
             @Override
             public PointF computeScrollVectorForPosition(int targetPosition) {
@@ -2445,6 +2510,7 @@
         };
         linearSmoothScroller.setTargetPosition(position);
         startSmoothScroll(linearSmoothScroller);
+        return linearSmoothScroller.getTargetPosition();
     }
 
     private void processPendingMovement(boolean forward) {
@@ -2546,8 +2612,7 @@
             return true;
         }
         if (getPositionByView(child) == NO_POSITION) {
-            // This shouldn't happen, but in case it does be sure not to attempt a
-            // scroll to a view whose item has been removed.
+            // This is could be the last view in DISAPPEARING animation.
             return true;
         }
         if (!mInLayout && !mInSelection && !mInScroll) {
@@ -2651,17 +2716,19 @@
     }
 
     /**
-     * Scroll to a given child view and change mFocusPosition.
+     * Scroll to a given child view and change mFocusPosition. Ignored when in slideOut() state.
      */
     void scrollToView(View view, boolean smooth) {
         scrollToView(view, view == null ? null : view.findFocus(), smooth);
     }
 
     /**
-     * Scroll to a given child view and change mFocusPosition.
+     * Scroll to a given child view and change mFocusPosition. Ignored when in slideOut() state.
      */
     private void scrollToView(View view, View childView, boolean smooth) {
-        mIsSlidingChildViews = false;
+        if (mIsSlidingChildViews) {
+            return;
+        }
         int newFocusPosition = getPositionByView(view);
         int newSubFocusPosition = getSubPositionByView(view, childView);
         if (newFocusPosition != mFocusPosition || newSubFocusPosition != mSubFocusPosition) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedAction.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedAction.java
index 62ff2d7..632c287 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedAction.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedAction.java
@@ -13,15 +13,14 @@
  */
 package android.support.v17.leanback.widget;
 
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.StringRes;
 import android.support.v17.leanback.R;
 import android.support.v4.content.ContextCompat;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
 import android.text.InputType;
 
 import java.util.List;
@@ -201,10 +200,10 @@
                 mTitle = mContext.getString(R.string.lb_guidedaction_continue_title);
             } else if (id == ACTION_ID_YES) {
                 mId = ACTION_ID_YES;
-                mTitle = mContext.getString(android.R.string.yes);
+                mTitle = mContext.getString(android.R.string.ok);
             } else if (id == ACTION_ID_NO) {
                 mId = ACTION_ID_NO;
-                mTitle = mContext.getString(android.R.string.no);
+                mTitle = mContext.getString(android.R.string.cancel);
             }
             return (B) this;
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ItemAlignmentFacetHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/ItemAlignmentFacetHelper.java
index 3230848..a51d1ca 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ItemAlignmentFacetHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ItemAlignmentFacetHelper.java
@@ -55,8 +55,8 @@
                 }
             }
             if (facet.mOffsetPercent != ITEM_ALIGN_OFFSET_PERCENT_DISABLED) {
-                alignPos += ((view == itemView ? p.getOpticalWidth(view) : view.getWidth())
-                        * facet.mOffsetPercent) / 100f;
+                alignPos += (int) (((view == itemView ? p.getOpticalWidth(view) : view.getWidth())
+                        * facet.mOffsetPercent) / 100f);
             }
             if (itemView != view) {
                 sRect.left = alignPos;
@@ -74,8 +74,8 @@
                 }
             }
             if (facet.mOffsetPercent != ITEM_ALIGN_OFFSET_PERCENT_DISABLED) {
-                alignPos += ((view == itemView ? p.getOpticalHeight(view) : view.getHeight())
-                        * facet.mOffsetPercent) / 100f;
+                alignPos += (int) (((view == itemView ? p.getOpticalHeight(view) : view.getHeight())
+                        * facet.mOffsetPercent) / 100f);
             }
             if (itemView != view) {
                 sRect.top = alignPos;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/Parallax.java b/v17/leanback/src/android/support/v17/leanback/widget/Parallax.java
index 573ca02..aebf9b4 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/Parallax.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/Parallax.java
@@ -31,22 +31,40 @@
  * rules to mapping property values to {@link ParallaxTarget}.
  *
  * <p>
- * There are two types of Parallax, int or float. App should subclass either
- * {@link Parallax.IntParallax} or {@link Parallax.FloatParallax}. App may subclass
- * {@link Parallax.IntProperty} or {@link Parallax.FloatProperty} to supply additional information
- * about how to retrieve Property value.  {@link RecyclerViewParallax} is a great example of
- * Parallax implementation tracking child view positions on screen.
+ * Example:
+ * <code>
+ *     // when Property "var1" changes from 15 to max value, perform parallax effect to
+ *     // change myView's translationY from 0 to 100.
+ *     Parallax<IntProperty> parallax = new Parallax<IntProperty>() {...};
+ *     p1 = parallax.addProperty("var1");
+ *     parallax.addEffect(p1.at(15), p1.atMax())
+ *             .target(myView, PropertyValuesHolder.ofFloat("translationY", 0, 100));
+ * </code>
+ * </p>
+ *
+ * <p>
+ * To create a {@link ParallaxEffect}, user calls {@link #addEffect(PropertyMarkerValue[])} with a
+ * list of {@link PropertyMarkerValue} which defines the range of {@link Parallax.IntProperty} or
+ * {@link Parallax.FloatProperty}. Then user adds {@link ParallaxTarget} into
+ * {@link ParallaxEffect}.
+ * </p>
+ * <p>
+ * App may subclass {@link Parallax.IntProperty} or {@link Parallax.FloatProperty} to supply
+ * additional information about how to retrieve Property value.  {@link RecyclerViewParallax} is
+ * a great example of Parallax implementation tracking child view positions on screen.
  * </p>
  * <p>
  * <ul>Restrictions of properties
+ * <li>FloatProperty and IntProperty cannot be mixed in one Parallax</li>
  * <li>Values must be in ascending order.</li>
  * <li>If the UI element is unknown above screen, use UNKNOWN_BEFORE.</li>
  * <li>if the UI element is unknown below screen, use UNKNOWN_AFTER.</li>
  * <li>UNKNOWN_BEFORE and UNKNOWN_AFTER are not allowed to be next to each other.</li>
  * </ul>
- * These rules can be verified by {@link #verifyProperties()}.
+ * These rules will be verified at runtime.
  * </p>
- * Subclass should override {@link #updateValues()} to update property values and perform
+ * <p>
+ * Subclass must override {@link #updateValues()} to update property values and perform
  * {@link ParallaxEffect}s. Subclass may call {@link #updateValues()} automatically e.g.
  * {@link RecyclerViewParallax} calls {@link #updateValues()} in RecyclerView scrolling. App might
  * call {@link #updateValues()} manually when Parallax is unaware of the value change. For example,
@@ -54,15 +72,12 @@
  * changes; it's the app's responsibility to call {@link #updateValues()} in every frame of
  * animation.
  * </p>
- * @param <PropertyT> Class of the property, e.g. {@link IntProperty} or {@link FloatProperty}.
+ * @param <PropertyT> Subclass of {@link Parallax.IntProperty} or {@link Parallax.FloatProperty}
  */
-public abstract class Parallax<PropertyT extends Property> {
-
-    private final List<ParallaxEffect> mEffects = new ArrayList<ParallaxEffect>(4);
+public abstract class Parallax<PropertyT extends android.util.Property> {
 
     /**
      * Class holding a fixed value for a Property in {@link Parallax}.
-     * Base class for {@link IntPropertyMarkerValue} and {@link FloatPropertyMarkerValue}.
      * @param <PropertyT> Class of the property, e.g. {@link IntProperty} or {@link FloatProperty}.
      */
     public static class PropertyMarkerValue<PropertyT> {
@@ -82,10 +97,10 @@
 
     /**
      * IntProperty provide access to an index based integer type property inside
-     * {@link IntParallax}. The IntProperty typically represents UI element position inside
-     * {@link IntParallax}.
+     * {@link Parallax}. The IntProperty typically represents UI element position inside
+     * {@link Parallax}.
      */
-    public static class IntProperty extends Property<IntParallax, Integer> {
+    public static class IntProperty extends Property<Parallax, Integer> {
 
         /**
          * Property value is unknown and it's smaller than minimal value of Parallax. For
@@ -94,7 +109,7 @@
         public static final int UNKNOWN_BEFORE = Integer.MIN_VALUE;
 
         /**
-         * Property value is unknown and it's larger than {@link IntParallax#getMaxValue()}. For
+         * Property value is unknown and it's larger than {@link Parallax#getMaxValue()}. For
          * example if a child is not created and after the last visible child of RecyclerView.
          */
         public static final int UNKNOWN_AFTER = Integer.MAX_VALUE;
@@ -105,7 +120,7 @@
          * Constructor.
          *
          * @param name Name of this Property.
-         * @param index Index of this Property inside {@link IntParallax}.
+         * @param index Index of this Property inside {@link Parallax}.
          */
         public IntProperty(String name, int index) {
             super(Integer.class, name);
@@ -113,168 +128,112 @@
         }
 
         @Override
-        public final Integer get(IntParallax object) {
-            return getIntValue(object);
+        public final Integer get(Parallax object) {
+            return object.getIntPropertyValue(mIndex);
         }
 
         @Override
-        public final void set(IntParallax object, Integer value) {
-            setIntValue(object, value);
-        }
-
-        final int getIntValue(IntParallax source) {
-            return source.getPropertyValue(mIndex);
-        }
-
-        final void setIntValue(IntParallax source, int value) {
-            source.setPropertyValue(mIndex, value);
+        public final void set(Parallax object, Integer value) {
+            object.setIntPropertyValue(mIndex, value);
         }
 
         /**
-         * @return Index of this Property in {@link IntParallax}.
+         * @return Index of this Property in {@link Parallax}.
          */
         public final int getIndex() {
             return mIndex;
         }
 
         /**
-         * Creates an {@link IntPropertyMarkerValue} object for the absolute marker value.
+         * Fast version of get() method that returns a primitive int value of the Property.
+         * @param object The Parallax object that owns this Property.
+         * @return Int value of the Property.
+         */
+        public final int getValue(Parallax object) {
+            return object.getIntPropertyValue(mIndex);
+        }
+
+        /**
+         * Fast version of set() method that takes a primitive int value into the Property.
+         *
+         * @param object The Parallax object that owns this Property.
+         * @param value Int value of the Property.
+         */
+        public final void setValue(Parallax object, int value) {
+            object.setIntPropertyValue(mIndex, value);
+        }
+
+        /**
+         * Creates an {@link PropertyMarkerValue} object for the absolute marker value.
          *
          * @param absoluteValue The integer marker value.
-         * @return A new {@link IntPropertyMarkerValue} object.
+         * @return A new {@link PropertyMarkerValue} object.
          */
-        public final IntPropertyMarkerValue atAbsolute(int absoluteValue) {
+        public final PropertyMarkerValue atAbsolute(int absoluteValue) {
             return new IntPropertyMarkerValue(this, absoluteValue, 0f);
         }
 
         /**
-         * Creates an {@link IntPropertyMarkerValue} object for a fraction of
-         * {@link IntParallax#getMaxValue()}.
+         * Creates an {@link PropertyMarkerValue} object for the marker value representing
+         * {@link Parallax#getMaxValue()}.
+         *
+         * @return A new {@link PropertyMarkerValue} object.
+         */
+        public final PropertyMarkerValue atMax() {
+            return new IntPropertyMarkerValue(this, 0, 1f);
+        }
+
+        /**
+         * Creates an {@link PropertyMarkerValue} object for the marker value representing 0.
+         *
+         * @return A new {@link PropertyMarkerValue} object.
+         */
+        public final PropertyMarkerValue atMin() {
+            return new IntPropertyMarkerValue(this, 0);
+        }
+
+        /**
+         * Creates an {@link PropertyMarkerValue} object for a fraction of
+         * {@link Parallax#getMaxValue()}.
          *
          * @param fractionOfMaxValue 0 to 1 fraction to multiply with
-         *                                       {@link IntParallax#getMaxValue()} for
+         *                                       {@link Parallax#getMaxValue()} for
          *                                       the marker value.
-         * @return A new {@link IntPropertyMarkerValue} object.
+         * @return A new {@link PropertyMarkerValue} object.
          */
-        public final IntPropertyMarkerValue atFraction(float fractionOfMaxValue) {
+        public final PropertyMarkerValue atFraction(float fractionOfMaxValue) {
             return new IntPropertyMarkerValue(this, 0, fractionOfMaxValue);
         }
 
         /**
-         * Create an {@link IntPropertyMarkerValue} object by multiplying the fraction with
-         * {@link IntParallax#getMaxValue()} and adding offsetValue to it.
+         * Create an {@link PropertyMarkerValue} object by multiplying the fraction with
+         * {@link Parallax#getMaxValue()} and adding offsetValue to it.
          *
          * @param offsetValue                    An offset integer value to be added to marker
          *                                       value.
          * @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with
-         *                                       {@link IntParallax#getMaxValue()} for
+         *                                       {@link Parallax#getMaxValue()} for
          *                                       the marker value.
-         * @return A new {@link IntPropertyMarkerValue} object.
+         * @return A new {@link PropertyMarkerValue} object.
          */
-        public final IntPropertyMarkerValue at(int offsetValue,
-                                               float fractionOfMaxParentVisibleSize) {
+        public final PropertyMarkerValue at(int offsetValue,
+                float fractionOfMaxParentVisibleSize) {
             return new IntPropertyMarkerValue(this, offsetValue, fractionOfMaxParentVisibleSize);
         }
     }
 
     /**
-     * Parallax that manages a list of {@link IntProperty}. App may override this class with a
-     * specific {@link IntProperty} subclass.
-     *
-     * @param <IntPropertyT> Type of {@link IntProperty} or subclass.
-     */
-    public abstract static class IntParallax<IntPropertyT extends IntProperty>
-            extends Parallax<IntPropertyT> {
-
-        private int[] mValues = new int[4];
-
-        /**
-         * Get index based property value.
-         *
-         * @param index Index of the property.
-         * @return Value of the property.
-         */
-        public final int getPropertyValue(int index) {
-            return mValues[index];
-        }
-
-        /**
-         * Set index based property value.
-         *
-         * @param index Index of the property.
-         * @param value Value of the property.
-         */
-        public final void setPropertyValue(int index, int value) {
-            if (index >= mProperties.size()) {
-                throw new ArrayIndexOutOfBoundsException();
-            }
-            mValues[index] = value;
-        }
-
-        /**
-         * Return the max value, which is typically parent visible area, e.g. RecyclerView's height
-         * if we are tracking Y position of a child. The size can be used to calculate marker value
-         * using the provided fraction of IntPropertyMarkerValue.
-         *
-         * @return Max value of parallax.
-         * @see IntPropertyMarkerValue#IntPropertyMarkerValue(IntProperty, int, float)
-         */
-        public abstract int getMaxValue();
-
-        @Override
-        public final IntPropertyT addProperty(String name) {
-            int newPropertyIndex = mProperties.size();
-            IntPropertyT property = createProperty(name, newPropertyIndex);
-            mProperties.add(property);
-            int size = mValues.length;
-            if (size == newPropertyIndex) {
-                int[] newValues = new int[size * 2];
-                for (int i = 0; i < size; i++) {
-                    newValues[i] = mValues[i];
-                }
-                mValues = newValues;
-            }
-            mValues[newPropertyIndex] = IntProperty.UNKNOWN_AFTER;
-            return property;
-        }
-
-        @Override
-        public final void verifyProperties() throws IllegalStateException {
-            if (mProperties.size() < 2) {
-                return;
-            }
-            int last = mProperties.get(0).getIntValue(this);
-            for (int i = 1; i < mProperties.size(); i++) {
-                int v = mProperties.get(i).getIntValue(this);
-                if (v < last) {
-                    throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
-                                    + " smaller than Property[%d]\"%s\"",
-                            i, mProperties.get(i).getName(),
-                            i - 1, mProperties.get(i - 1).getName()));
-                } else if (last == IntProperty.UNKNOWN_BEFORE && v == IntProperty.UNKNOWN_AFTER) {
-                    throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
-                                    + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER",
-                            i - 1, mProperties.get(i - 1).getName(),
-                            i, mProperties.get(i).getName()));
-                }
-                last = v;
-            }
-        }
-
-    }
-
-    /**
      * Implementation of {@link PropertyMarkerValue} for {@link IntProperty}.
      */
-    public static class IntPropertyMarkerValue extends PropertyMarkerValue<IntProperty> {
+    static class IntPropertyMarkerValue extends PropertyMarkerValue<IntProperty> {
         private final int mValue;
         private final float mFactionOfMax;
 
-        public IntPropertyMarkerValue(IntProperty property, int value) {
+        IntPropertyMarkerValue(IntProperty property, int value) {
             this(property, value, 0f);
         }
 
-        public IntPropertyMarkerValue(IntProperty property, int value, float fractionOfMax) {
+        IntPropertyMarkerValue(IntProperty property, int value, float fractionOfMax) {
             super(property);
             mValue = value;
             mFactionOfMax = fractionOfMax;
@@ -283,7 +242,7 @@
         /**
          * @return The marker value of integer type.
          */
-        public final int getMarkerValue(IntParallax source) {
+        final int getMarkerValue(Parallax source) {
             return mFactionOfMax == 0 ? mValue : mValue + Math.round(source
                     .getMaxValue() * mFactionOfMax);
         }
@@ -291,10 +250,10 @@
 
     /**
      * FloatProperty provide access to an index based integer type property inside
-     * {@link FloatParallax}. The FloatProperty typically represents UI element position inside
-     * {@link FloatParallax}.
+     * {@link Parallax}. The FloatProperty typically represents UI element position inside
+     * {@link Parallax}.
      */
-    public static class FloatProperty extends Property<FloatParallax, Float> {
+    public static class FloatProperty extends Property<Parallax, Float> {
 
         /**
          * Property value is unknown and it's smaller than minimal value of Parallax. For
@@ -303,7 +262,7 @@
         public static final float UNKNOWN_BEFORE = -Float.MAX_VALUE;
 
         /**
-         * Property value is unknown and it's larger than {@link FloatParallax#getMaxValue()}. For
+         * Property value is unknown and it's larger than {@link Parallax#getMaxValue()}. For
          * example if a child is not created and after the last visible child of RecyclerView.
          */
         public static final float UNKNOWN_AFTER = Float.MAX_VALUE;
@@ -314,7 +273,7 @@
          * Constructor.
          *
          * @param name Name of this Property.
-         * @param index Index of this Property inside {@link FloatParallax}.
+         * @param index Index of this Property inside {@link Parallax}.
          */
         public FloatProperty(String name, int index) {
             super(Float.class, name);
@@ -322,168 +281,111 @@
         }
 
         @Override
-        public final Float get(FloatParallax object) {
-            return getFloatValue(object);
+        public final Float get(Parallax object) {
+            return object.getFloatPropertyValue(mIndex);
         }
 
         @Override
-        public final void set(FloatParallax object, Float value) {
-            setFloatValue(object, value);
-        }
-
-        final float getFloatValue(FloatParallax source) {
-            return source.getPropertyValue(mIndex);
-        }
-
-        final void setFloatValue(FloatParallax source, float value) {
-            source.setPropertyValue(mIndex, value);
+        public final void set(Parallax object, Float value) {
+            object.setFloatPropertyValue(mIndex, value);
         }
 
         /**
-         * @return Index of this Property in {@link FloatParallax}.
+         * @return Index of this Property in {@link Parallax}.
          */
         public final int getIndex() {
             return mIndex;
         }
 
         /**
-         * Creates an {@link FloatPropertyMarkerValue} object for the absolute marker value.
+         * Fast version of get() method that returns a primitive int value of the Property.
+         * @param object The Parallax object that owns this Property.
+         * @return Float value of the Property.
+         */
+        public final float getValue(Parallax object) {
+            return object.getFloatPropertyValue(mIndex);
+        }
+
+        /**
+         * Fast version of set() method that takes a primitive float value into the Property.
+         *
+         * @param object The Parallax object that owns this Property.
+         * @param value Float value of the Property.
+         */
+        public final void setValue(Parallax object, float value) {
+            object.setFloatPropertyValue(mIndex, value);
+        }
+
+        /**
+         * Creates an {@link PropertyMarkerValue} object for the absolute marker value.
          *
          * @param markerValue The float marker value.
-         * @return A new {@link FloatPropertyMarkerValue} object.
+         * @return A new {@link PropertyMarkerValue} object.
          */
-        public final FloatPropertyMarkerValue atAbsolute(float markerValue) {
+        public final PropertyMarkerValue atAbsolute(float markerValue) {
             return new FloatPropertyMarkerValue(this, markerValue, 0f);
         }
 
         /**
-         * Creates an {@link FloatPropertyMarkerValue} object for a fraction of
-         * {@link FloatParallax#getMaxValue()}.
+         * Creates an {@link PropertyMarkerValue} object for the marker value representing
+         * {@link Parallax#getMaxValue()}.
+         *
+         * @return A new {@link PropertyMarkerValue} object.
+         */
+        public final PropertyMarkerValue atMax() {
+            return new FloatPropertyMarkerValue(this, 0, 1f);
+        }
+
+        /**
+         * Creates an {@link PropertyMarkerValue} object for the marker value representing 0.
+         *
+         * @return A new {@link PropertyMarkerValue} object.
+         */
+        public final PropertyMarkerValue atMin() {
+            return new FloatPropertyMarkerValue(this, 0);
+        }
+
+        /**
+         * Creates an {@link PropertyMarkerValue} object for a fraction of
+         * {@link Parallax#getMaxValue()}.
          *
          * @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with
-         *                                       {@link FloatParallax#getMaxValue()} for
+         *                                       {@link Parallax#getMaxValue()} for
          *                                       the marker value.
-         * @return A new {@link FloatPropertyMarkerValue} object.
+         * @return A new {@link PropertyMarkerValue} object.
          */
-        public final FloatPropertyMarkerValue atFraction(float fractionOfMaxParentVisibleSize) {
+        public final PropertyMarkerValue atFraction(float fractionOfMaxParentVisibleSize) {
             return new FloatPropertyMarkerValue(this, 0, fractionOfMaxParentVisibleSize);
         }
 
         /**
-         * Create an {@link FloatPropertyMarkerValue} object by multiplying the fraction with
-         * {@link FloatParallax#getMaxValue()} and adding offsetValue to it.
+         * Create an {@link PropertyMarkerValue} object by multiplying the fraction with
+         * {@link Parallax#getMaxValue()} and adding offsetValue to it.
          *
          * @param offsetValue                    An offset float value to be added to marker value.
          * @param fractionOfMaxParentVisibleSize 0 to 1 fraction to multiply with
-         *                                       {@link FloatParallax#getMaxValue()} for
+         *                                       {@link Parallax#getMaxValue()} for
          *                                       the marker value.
-         * @return A new {@link FloatPropertyMarkerValue} object.
+         * @return A new {@link PropertyMarkerValue} object.
          */
-        public final FloatPropertyMarkerValue at(float offsetValue,
-                                                 float fractionOfMaxParentVisibleSize) {
+        public final PropertyMarkerValue at(float offsetValue,
+                float fractionOfMaxParentVisibleSize) {
             return new FloatPropertyMarkerValue(this, offsetValue, fractionOfMaxParentVisibleSize);
         }
     }
 
     /**
-     * Parallax that manages a list of {@link FloatProperty}. App may override this class with a
-     * specific {@link FloatProperty} subclass.
-     *
-     * @param <FloatPropertyT> Type of {@link FloatProperty} or subclass.
-     */
-    public abstract static class FloatParallax<FloatPropertyT extends FloatProperty> extends
-            Parallax<FloatPropertyT> {
-
-        private float[] mValues = new float[4];
-
-        /**
-         * Get index based property value.
-         *
-         * @param index Index of the property.
-         * @return Value of the property.
-         */
-        public final float getPropertyValue(int index) {
-            return mValues[index];
-        }
-
-        /**
-         * Set index based property value.
-         *
-         * @param index Index of the property.
-         * @param value Value of the property.
-         */
-        public final void setPropertyValue(int index, float value) {
-            if (index >= mProperties.size()) {
-                throw new ArrayIndexOutOfBoundsException();
-            }
-            mValues[index] = value;
-        }
-
-        /**
-         * Return the max value which is typically size of parent visible area, e.g. RecyclerView's
-         * height if we are tracking Y position of a child. The size can be used to calculate marker
-         * value using the provided fraction of FloatPropertyMarkerValue.
-         *
-         * @return Size of parent visible area.
-         * @see FloatPropertyMarkerValue#FloatPropertyMarkerValue(FloatProperty, float, float)
-         */
-        public abstract float getMaxValue();
-
-        @Override
-        public final FloatPropertyT addProperty(String name) {
-            int newPropertyIndex = mProperties.size();
-            FloatPropertyT property = createProperty(name, newPropertyIndex);
-            mProperties.add(property);
-            int size = mValues.length;
-            if (size == newPropertyIndex) {
-                float[] newValues = new float[size * 2];
-                for (int i = 0; i < size; i++) {
-                    newValues[i] = mValues[i];
-                }
-                mValues = newValues;
-            }
-            mValues[newPropertyIndex] = FloatProperty.UNKNOWN_AFTER;
-            return property;
-        }
-
-        @Override
-        public final void verifyProperties() throws IllegalStateException {
-            if (mProperties.size() < 2) {
-                return;
-            }
-            float last = mProperties.get(0).getFloatValue(this);
-            for (int i = 1; i < mProperties.size(); i++) {
-                float v = mProperties.get(i).getFloatValue(this);
-                if (v < last) {
-                    throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
-                                    + " smaller than Property[%d]\"%s\"",
-                            i, mProperties.get(i).getName(),
-                            i - 1, mProperties.get(i - 1).getName()));
-                } else if (last == FloatProperty.UNKNOWN_BEFORE && v
-                        == FloatProperty.UNKNOWN_AFTER) {
-                    throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
-                                    + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER",
-                            i - 1, mProperties.get(i - 1).getName(),
-                            i, mProperties.get(i).getName()));
-                }
-                last = v;
-            }
-        }
-
-    }
-
-    /**
      * Implementation of {@link PropertyMarkerValue} for {@link FloatProperty}.
      */
-    public static class FloatPropertyMarkerValue extends PropertyMarkerValue<FloatProperty> {
+    static class FloatPropertyMarkerValue extends PropertyMarkerValue<FloatProperty> {
         private final float mValue;
         private final float mFactionOfMax;
 
-        public FloatPropertyMarkerValue(FloatProperty property, float value) {
+        FloatPropertyMarkerValue(FloatProperty property, float value) {
             this(property, value, 0f);
         }
 
-        public FloatPropertyMarkerValue(FloatProperty property, float value, float fractionOfMax) {
+        FloatPropertyMarkerValue(FloatProperty property, float value, float fractionOfMax) {
             super(property);
             mValue = value;
             mFactionOfMax = fractionOfMax;
@@ -492,7 +394,7 @@
         /**
          * @return The marker value.
          */
-        public final float getMarkerValue(FloatParallax source) {
+        final float getMarkerValue(Parallax source) {
             return mFactionOfMax == 0 ? mValue : mValue + source.getMaxValue()
                     * mFactionOfMax;
         }
@@ -501,6 +403,156 @@
     final List<PropertyT> mProperties = new ArrayList<PropertyT>();
     final List<PropertyT> mPropertiesReadOnly = Collections.unmodifiableList(mProperties);
 
+    private int[] mValues = new int[4];
+    private float[] mFloatValues = new float[4];
+
+    private final List<ParallaxEffect> mEffects = new ArrayList<ParallaxEffect>(4);
+
+    /**
+     * Return the max value which is typically size of parent visible area, e.g. RecyclerView's
+     * height if we are tracking Y position of a child. The size can be used to calculate marker
+     * value using the provided fraction of FloatPropertyMarkerValue.
+     *
+     * @return Size of parent visible area.
+     * @see IntPropertyMarkerValue#IntPropertyMarkerValue(IntProperty, int, float)
+     * @see FloatPropertyMarkerValue#FloatPropertyMarkerValue(FloatProperty, float, float)
+     */
+    public abstract float getMaxValue();
+
+    /**
+     * Get index based property value.
+     *
+     * @param index Index of the property.
+     * @return Value of the property.
+     */
+    final int getIntPropertyValue(int index) {
+        return mValues[index];
+    }
+
+    /**
+     * Set index based property value.
+     *
+     * @param index Index of the property.
+     * @param value Value of the property.
+     */
+    final void setIntPropertyValue(int index, int value) {
+        if (index >= mProperties.size()) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        mValues[index] = value;
+    }
+
+    /**
+     * Add a new IntProperty in the Parallax object. App may override
+     * {@link #createProperty(String, int)}.
+     *
+     * @param name Name of the property.
+     * @return Newly created Property object.
+     * @see #createProperty(String, int)
+     */
+    public final PropertyT addProperty(String name) {
+        int newPropertyIndex = mProperties.size();
+        PropertyT property = createProperty(name, newPropertyIndex);
+        if (property instanceof IntProperty) {
+            int size = mValues.length;
+            if (size == newPropertyIndex) {
+                int[] newValues = new int[size * 2];
+                for (int i = 0; i < size; i++) {
+                    newValues[i] = mValues[i];
+                }
+                mValues = newValues;
+            }
+            mValues[newPropertyIndex] = IntProperty.UNKNOWN_AFTER;
+        } else if (property instanceof FloatProperty) {
+            int size = mFloatValues.length;
+            if (size == newPropertyIndex) {
+                float[] newValues = new float[size * 2];
+                for (int i = 0; i < size; i++) {
+                    newValues[i] = mFloatValues[i];
+                }
+                mFloatValues = newValues;
+            }
+            mFloatValues[newPropertyIndex] = FloatProperty.UNKNOWN_AFTER;
+        } else {
+            throw new IllegalArgumentException("Invalid Property type");
+        }
+        mProperties.add(property);
+        return property;
+    }
+
+    /**
+     * Verify sanity of property values, throws RuntimeException if fails. The property values
+     * must be in ascending order. UNKNOW_BEFORE and UNKNOWN_AFTER are not allowed to be next to
+     * each other.
+     */
+    void verifyIntProperties() throws IllegalStateException {
+        if (mProperties.size() < 2) {
+            return;
+        }
+        int last = getIntPropertyValue(0);
+        for (int i = 1; i < mProperties.size(); i++) {
+            int v = getIntPropertyValue(i);
+            if (v < last) {
+                throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
+                                + " smaller than Property[%d]\"%s\"",
+                        i, mProperties.get(i).getName(),
+                        i - 1, mProperties.get(i - 1).getName()));
+            } else if (last == IntProperty.UNKNOWN_BEFORE && v == IntProperty.UNKNOWN_AFTER) {
+                throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
+                                + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER",
+                        i - 1, mProperties.get(i - 1).getName(),
+                        i, mProperties.get(i).getName()));
+            }
+            last = v;
+        }
+    }
+
+    final void verifyFloatProperties() throws IllegalStateException {
+        if (mProperties.size() < 2) {
+            return;
+        }
+        float last = getFloatPropertyValue(0);
+        for (int i = 1; i < mProperties.size(); i++) {
+            float v = getFloatPropertyValue(i);
+            if (v < last) {
+                throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
+                                + " smaller than Property[%d]\"%s\"",
+                        i, mProperties.get(i).getName(),
+                        i - 1, mProperties.get(i - 1).getName()));
+            } else if (last == FloatProperty.UNKNOWN_BEFORE && v
+                    == FloatProperty.UNKNOWN_AFTER) {
+                throw new IllegalStateException(String.format("Parallax Property[%d]\"%s\" is"
+                                + " UNKNOWN_BEFORE and Property[%d]\"%s\" is UNKNOWN_AFTER",
+                        i - 1, mProperties.get(i - 1).getName(),
+                        i, mProperties.get(i).getName()));
+            }
+            last = v;
+        }
+    }
+
+    /**
+     * Get index based property value.
+     *
+     * @param index Index of the property.
+     * @return Value of the property.
+     */
+    final float getFloatPropertyValue(int index) {
+        return mFloatValues[index];
+    }
+
+    /**
+     * Set index based property value.
+     *
+     * @param index Index of the property.
+     * @param value Value of the property.
+     */
+    final void setFloatPropertyValue(int index, float value) {
+        if (index >= mProperties.size()) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+        mFloatValues[index] = value;
+    }
+
     /**
      * @return A unmodifiable list of properties.
      */
@@ -509,14 +561,6 @@
     }
 
     /**
-     * Add a new Property in the Parallax object.
-     *
-     * @param name Name of the property.
-     * @return Newly created Property.
-     */
-    public abstract PropertyT addProperty(String name);
-
-    /**
      * Create a new Property object. App does not directly call this method.  See
      * {@link #addProperty(String)}.
      *
@@ -526,13 +570,6 @@
     public abstract PropertyT createProperty(String name, int index);
 
     /**
-     * Verify sanity of property values, throws RuntimeException if fails. The property values
-     * must be in ascending order. UNKNOW_BEFORE and UNKNOWN_AFTER are not allowed to be next to
-     * each other.
-     */
-    public abstract void verifyProperties() throws IllegalStateException;
-
-    /**
      * Update property values and perform {@link ParallaxEffect}s. Subclass may override and call
      * super.updateValues() after updated properties values.
      */
@@ -544,16 +581,6 @@
     }
 
     /**
-     * Adds a {@link ParallaxEffect} object which defines rules to perform mapping to multiple
-     * {@link ParallaxTarget}s.
-     *
-     * @param effect A {@link ParallaxEffect} object.
-     */
-    public void addEffect(ParallaxEffect effect) {
-        mEffects.add(effect);
-    }
-
-    /**
      * Returns a list of {@link ParallaxEffect} object which defines rules to perform mapping to
      * multiple {@link ParallaxTarget}s.
      *
@@ -586,24 +613,16 @@
      * @param ranges A list of marker values that defines the ranges.
      * @return Newly created ParallaxEffect object.
      */
-    public ParallaxEffect addEffect(IntPropertyMarkerValue... ranges) {
-        IntEffect effect = new IntEffect();
+    public ParallaxEffect addEffect(PropertyMarkerValue... ranges) {
+        ParallaxEffect effect;
+        if (ranges[0].getProperty() instanceof IntProperty) {
+            effect = new IntEffect();
+        } else {
+            effect = new FloatEffect();
+        }
         effect.setPropertyRanges(ranges);
-        addEffect(effect);
+        mEffects.add(effect);
         return effect;
     }
 
-    /**
-     * Create a {@link ParallaxEffect} object that will track source variable changes within a
-     * provided set of ranges.
-     *
-     * @param ranges A list of marker values that defines the ranges.
-     * @return Newly created ParallaxEffect object.
-     */
-    public ParallaxEffect addEffect(FloatPropertyMarkerValue... ranges) {
-        FloatEffect effect = new FloatEffect();
-        effect.setPropertyRanges(ranges);
-        addEffect(effect);
-        return effect;
-    }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ParallaxEffect.java b/v17/leanback/src/android/support/v17/leanback/widget/ParallaxEffect.java
index 5760bdb..5c06e29 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ParallaxEffect.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ParallaxEffect.java
@@ -21,6 +21,7 @@
 import android.support.v17.leanback.widget.Parallax.FloatPropertyMarkerValue;
 import android.support.v17.leanback.widget.Parallax.IntProperty;
 import android.support.v17.leanback.widget.Parallax.PropertyMarkerValue;
+import android.util.Property;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -36,25 +37,30 @@
  * on, the fraction increases from 0 at beginning to 1 at the end. Then the fraction is passed on
  * to {@link ParallaxTarget#update(float)}.
  * <p>
- * ParallaxEffect has two concrete subclasses, {@link IntEffect} and {@link FloatEffect}.
+ * App use {@link Parallax#addEffect(PropertyMarkerValue...)} to create a ParallaxEffect.
  */
-public abstract class ParallaxEffect<ParallaxEffectT extends ParallaxEffect,
-        PropertyMarkerValueT extends Parallax.PropertyMarkerValue> {
+public abstract class ParallaxEffect {
 
-    final List<PropertyMarkerValueT> mMarkerValues = new ArrayList<PropertyMarkerValueT>(2);
+    final List<Parallax.PropertyMarkerValue> mMarkerValues = new ArrayList(2);
     final List<Float> mWeights = new ArrayList<Float>(2);
     final List<Float> mTotalWeights = new ArrayList<Float>(2);
     final List<ParallaxTarget> mTargets = new ArrayList<ParallaxTarget>(4);
 
     /**
+     * Only accessible from package
+     */
+    ParallaxEffect() {
+    }
+
+    /**
      * Returns the list of {@link PropertyMarkerValue}s, which represents the range of values that
      * source variables can take.
      *
      * @return A list of {@link Parallax.PropertyMarkerValue}s.
      * @see #performMapping(Parallax)
      */
-    public final List<PropertyMarkerValueT> getPropertyRanges() {
-        return  mMarkerValues;
+    public final List<Parallax.PropertyMarkerValue> getPropertyRanges() {
+        return mMarkerValues;
     }
 
     /**
@@ -75,9 +81,9 @@
      * @param markerValues A list of {@link PropertyMarkerValue}s.
      * @see #performMapping(Parallax)
      */
-    public final void setPropertyRanges(PropertyMarkerValueT... markerValues) {
+    public final void setPropertyRanges(Parallax.PropertyMarkerValue... markerValues) {
         mMarkerValues.clear();
-        for (PropertyMarkerValueT markerValue : markerValues) {
+        for (Parallax.PropertyMarkerValue markerValue : markerValues) {
             mMarkerValues.add(markerValue);
         }
     }
@@ -154,6 +160,23 @@
     }
 
     /**
+     * Creates a {@link ParallaxTarget} using direct mapping from source property into target
+     * property, the new {@link ParallaxTarget} will be added to its list of targets.
+     *
+     * @param targetObject Target object for property.
+     * @param targetProperty The target property that will receive values.
+     * @return This ParallaxEffect object, allowing calls to methods in this class to be chained.
+     * @param <T> Type of target object.
+     * @param <V> Type of target property value, either Integer or Float.
+     * @see ParallaxTarget#isDirectMapping()
+     */
+    public final <T, V extends Number> ParallaxEffect target(T targetObject,
+            Property<T, V> targetProperty) {
+        mTargets.add(new ParallaxTarget.DirectPropertyTarget(targetObject, targetProperty));
+        return this;
+    }
+
+    /**
      * Returns the list of {@link ParallaxTarget} objects.
      *
      * @return The list of {@link ParallaxTarget} objects.
@@ -177,10 +200,28 @@
         if (mMarkerValues.size() < 2) {
             return;
         }
-        source.verifyProperties();
-        float fraction = calculateFraction(source);
+        if (this instanceof IntEffect) {
+            source.verifyIntProperties();
+        } else {
+            source.verifyFloatProperties();
+        }
+        boolean fractionCalculated = false;
+        float fraction = 0;
+        Number directValue = null;
         for (int i = 0; i < mTargets.size(); i++) {
-            mTargets.get(i).update(fraction);
+            ParallaxTarget target = mTargets.get(i);
+            if (target.isDirectMapping()) {
+                if (directValue == null) {
+                    directValue = calculateDirectValue(source);
+                }
+                target.directUpdate(directValue);
+            } else {
+                if (!fractionCalculated) {
+                    fractionCalculated = true;
+                    fraction = calculateFraction(source);
+                }
+                target.update(fraction);
+            }
         }
     }
 
@@ -191,7 +232,15 @@
      *
      * @return Float value between 0 and 1.
      */
-    protected abstract float calculateFraction(Parallax source);
+    abstract float calculateFraction(Parallax source);
+
+    /**
+     * This method is expected to get the current value of the single {@link IntProperty} or
+     * {@link FloatProperty}.
+     *
+     * @return Current value of the single {@link IntProperty} or {@link FloatProperty}.
+     */
+    abstract Number calculateDirectValue(Parallax source);
 
     /**
      * When there are multiple ranges (aka three or more markerValues),  this method adjust the
@@ -226,21 +275,48 @@
     /**
      * Implementation of {@link ParallaxEffect} for integer type.
      */
-    public static final class IntEffect extends ParallaxEffect<IntEffect,
-            Parallax.IntPropertyMarkerValue> {
+    static final class IntEffect extends ParallaxEffect {
 
         @Override
-        protected float calculateFraction(Parallax s) {
-            Parallax.IntParallax source = (Parallax.IntParallax) s;
+        Number calculateDirectValue(Parallax source) {
+            if (mMarkerValues.size() != 2) {
+                throw new RuntimeException("Must use two marker values for direct mapping");
+            }
+            if (mMarkerValues.get(0).getProperty() != mMarkerValues.get(1).getProperty()) {
+                throw new RuntimeException(
+                        "Marker value must use same Property for direct mapping");
+            }
+            int value1 = ((Parallax.IntPropertyMarkerValue) mMarkerValues.get(0))
+                    .getMarkerValue(source);
+            int value2 = ((Parallax.IntPropertyMarkerValue) mMarkerValues.get(1))
+                    .getMarkerValue(source);
+            if (value1 > value2) {
+                int swapValue = value2;
+                value2 = value1;
+                value1 = swapValue;
+            }
+
+            Number currentValue = ((IntProperty) mMarkerValues.get(0).getProperty()).get(source);
+            if (currentValue.intValue() < value1) {
+                currentValue = value1;
+            } else if (currentValue.intValue() > value2) {
+                currentValue = value2;
+            }
+            return currentValue;
+        }
+
+        @Override
+        float calculateFraction(Parallax source) {
             int lastIndex = 0;
             int lastValue = 0;
             int lastMarkerValue = 0;
             // go through all markerValues, find first markerValue that current value is less than.
             for (int i = 0; i <  mMarkerValues.size(); i++) {
-                Parallax.IntPropertyMarkerValue k =  mMarkerValues.get(i);
+                Parallax.IntPropertyMarkerValue k =  (Parallax.IntPropertyMarkerValue)
+                        mMarkerValues.get(i);
                 int index = k.getProperty().getIndex();
                 int markerValue = k.getMarkerValue(source);
-                int currentValue = source.getPropertyValue(index);
+                int currentValue = source.getIntPropertyValue(index);
 
                 float fraction;
                 if (i == 0) {
@@ -294,21 +370,47 @@
     /**
      * Implementation of {@link ParallaxEffect} for float type.
      */
-    public static final class FloatEffect extends ParallaxEffect<FloatEffect,
-            Parallax.FloatPropertyMarkerValue> {
+    static final class FloatEffect extends ParallaxEffect {
 
         @Override
-        protected float calculateFraction(Parallax s) {
-            Parallax.FloatParallax source = (Parallax.FloatParallax) s;
+        Number calculateDirectValue(Parallax source) {
+            if (mMarkerValues.size() != 2) {
+                throw new RuntimeException("Must use two marker values for direct mapping");
+            }
+            if (mMarkerValues.get(0).getProperty() != mMarkerValues.get(1).getProperty()) {
+                throw new RuntimeException(
+                        "Marker value must use same Property for direct mapping");
+            }
+            float value1 = ((FloatPropertyMarkerValue) mMarkerValues.get(0))
+                    .getMarkerValue(source);
+            float value2 = ((FloatPropertyMarkerValue) mMarkerValues.get(1))
+                    .getMarkerValue(source);
+            if (value1 > value2) {
+                float swapValue = value2;
+                value2 = value1;
+                value1 = swapValue;
+            }
+
+            Number currentValue = ((FloatProperty) mMarkerValues.get(0).getProperty()).get(source);
+            if (currentValue.floatValue() < value1) {
+                currentValue = value1;
+            } else if (currentValue.floatValue() > value2) {
+                currentValue = value2;
+            }
+            return currentValue;
+        }
+
+        @Override
+        float calculateFraction(Parallax source) {
             int lastIndex = 0;
             float lastValue = 0;
             float lastMarkerValue = 0;
             // go through all markerValues, find first markerValue that current value is less than.
             for (int i = 0; i <  mMarkerValues.size(); i++) {
-                FloatPropertyMarkerValue k =  mMarkerValues.get(i);
+                FloatPropertyMarkerValue k = (FloatPropertyMarkerValue) mMarkerValues.get(i);
                 int index = k.getProperty().getIndex();
                 float markerValue = k.getMarkerValue(source);
-                float currentValue = source.getPropertyValue(index);
+                float currentValue = source.getFloatPropertyValue(index);
 
                 float fraction;
                 if (i == 0) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ParallaxTarget.java b/v17/leanback/src/android/support/v17/leanback/widget/ParallaxTarget.java
index 7020433..49783ab 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ParallaxTarget.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ParallaxTarget.java
@@ -18,32 +18,51 @@
 
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
+import android.util.Property;
 import android.view.animation.LinearInterpolator;
 
 /**
- * ParallaxTarget is responsible for updating the target through the {@link #update(float)} method.
- * {@link ParallaxEffect} transforms the values of {@link Parallax}, which represents the
- * current state of UI, into a float value between 0 and 1. That float value is passed into
- * {@link #update(float)} method.
+ * ParallaxTarget is responsible for updating the target through the {@link #update(float)} method
+ * or the {@link #directUpdate(Number)} method when {@link #isDirectMapping()} is true.
+ * When {@link #isDirectMapping()} is false, {@link ParallaxEffect} transforms the values of
+ * {@link Parallax}, which represents the current state of UI, into a float value between 0 and 1.
+ * That float value is passed into {@link #update(float)} method.
  */
 public abstract class ParallaxTarget {
 
     /**
      * Implementation class is supposed to update target with the provided fraction
      * (between 0 and 1). The fraction represents percentage of completed change (e.g. scroll) on
-     * target.
+     * target. Called only when {@link #isDirectMapping()} is false.
      *
      * @param fraction Fraction between 0 to 1.
+     * @see #isDirectMapping()
      */
-    public abstract void update(float fraction);
+    public void update(float fraction) {
+    }
 
     /**
-     * Returns the current fraction (between 0 and 1). The fraction represents percentage of
-     * completed change (e.g. scroll) on target.
+     * Returns true if the ParallaxTarget is directly mapping from source value,
+     * {@link #directUpdate(Number)} will be used to update value, otherwise update(fraction) will
+     * be called to update value. Default implementation returns false.
      *
-     * @return Current fraction value.
+     * @return True if direct mapping, false otherwise.
+     * @see #directUpdate(Number)
+     * @see #update(float)
      */
-    public abstract float getFraction();
+    public boolean isDirectMapping() {
+        return false;
+    }
+
+    /**
+     * Directly update the target using a float or int value. Called when {@link #isDirectMapping()}
+     * is true.
+     *
+     * @param value Either int or float value.
+     * @see #isDirectMapping()
+     */
+    public void directUpdate(Number value) {
+    }
 
     /**
      * PropertyValuesHolderTarget is an implementation of {@link ParallaxTarget} that uses
@@ -72,9 +91,42 @@
             mAnimator.setCurrentPlayTime((long) (PSEUDO_DURATION * fraction));
         }
 
+    }
+
+    /**
+     * DirectPropertyTarget is to support direct mapping into either Integer Property or Float
+     * Property. App uses convenient method {@link ParallaxEffect#target(Object, Property)} to
+     * add a direct mapping.
+     * @param <T> Type of target object.
+     * @param <V> Type of value, either Integer or Float.
+     */
+    public static final class DirectPropertyTarget<T extends Object, V extends Number>
+            extends ParallaxTarget {
+
+        Object mObject;
+        Property<T, V> mProperty;
+
+        /**
+         * @param targetObject Target object for perform Parallax
+         * @param property     Target property, either an Integer Property or a Float Property.
+         */
+        public DirectPropertyTarget(Object targetObject, Property<T, V> property) {
+            mObject = targetObject;
+            mProperty = property;
+        }
+
+        /**
+         * Returns true as DirectPropertyTarget receives a number to update Property in
+         * {@link #directUpdate(Number)}.
+         */
         @Override
-        public float getFraction() {
-            return mFraction;
+        public boolean isDirectMapping() {
+            return true;
+        }
+
+        @Override
+        public void directUpdate(Number value) {
+            mProperty.set((T) mObject, (V) value);
         }
     }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java
index 79d1407..01e9de3 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java
@@ -63,7 +63,6 @@
         StringBuilder mCurrentTimeStringBuilder = new StringBuilder();
         int mCurrentTimeMarginStart;
         int mTotalTimeMarginEnd;
-        final PersistentFocusWrapper mControlsFocusWrapper;
 
         ViewHolder(View rootView) {
             super(rootView);
@@ -91,7 +90,6 @@
                     ((MarginLayoutParams) mCurrentTime.getLayoutParams()).getMarginStart();
             mTotalTimeMarginEnd =
                     ((MarginLayoutParams) mTotalTime.getLayoutParams()).getMarginEnd();
-            mControlsFocusWrapper = (PersistentFocusWrapper) mControlBar.getParent();
         }
 
         void showMoreActions(boolean show) {
@@ -298,7 +296,6 @@
     }
 
     public void resetFocus(ViewHolder vh) {
-        vh.mControlsFocusWrapper.clearSelection();
         vh.mControlBar.requestFocus();
     }
 
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/RecyclerViewParallax.java b/v17/leanback/src/android/support/v17/leanback/widget/RecyclerViewParallax.java
index 20c40f9..7253d01 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RecyclerViewParallax.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RecyclerViewParallax.java
@@ -22,6 +22,7 @@
 
 import android.graphics.Rect;
 import android.support.v7.widget.RecyclerView;
+import android.util.Property;
 import android.view.View;
 
 /**
@@ -29,8 +30,7 @@
  * allows users to track position of specific views inside {@link RecyclerView} relative to
  * itself. @see {@link ChildPositionProperty} for details.
  */
-public class RecyclerViewParallax extends
-        Parallax.IntParallax<RecyclerViewParallax.ChildPositionProperty> {
+public class RecyclerViewParallax extends Parallax<RecyclerViewParallax.ChildPositionProperty> {
     RecyclerView mRecylerView;
     boolean mIsVertical;
 
@@ -41,6 +41,14 @@
         }
     };
 
+    View.OnLayoutChangeListener mOnLayoutChangeListener = new View.OnLayoutChangeListener() {
+        @Override
+        public void onLayoutChange(View view, int l, int t, int r, int b,
+                int oldL, int oldT, int oldR, int oldB) {
+            updateValues();
+        }
+    };
+
     /**
      * Subclass of {@link Parallax.IntProperty}. Using this Property, users can track a
      * RecylerView child's position inside recyclerview. i.e.
@@ -141,16 +149,16 @@
                     : recyclerView.findViewHolderForAdapterPosition(mAdapterPosition);
             if (viewHolder == null) {
                 if (recyclerView == null || recyclerView.getLayoutManager().getChildCount() == 0) {
-                    source.setPropertyValue(getIndex(), IntProperty.UNKNOWN_AFTER);
+                    source.setIntPropertyValue(getIndex(), IntProperty.UNKNOWN_AFTER);
                     return;
                 }
                 View firstChild = recyclerView.getLayoutManager().getChildAt(0);
                 ViewHolder vh = recyclerView.findContainingViewHolder(firstChild);
                 int firstPosition = vh.getAdapterPosition();
                 if (firstPosition < mAdapterPosition) {
-                    source.setPropertyValue(getIndex(), IntProperty.UNKNOWN_AFTER);
+                    source.setIntPropertyValue(getIndex(), IntProperty.UNKNOWN_AFTER);
                 } else {
-                    source.setPropertyValue(getIndex(), IntProperty.UNKNOWN_BEFORE);
+                    source.setIntPropertyValue(getIndex(), IntProperty.UNKNOWN_BEFORE);
                 }
             } else {
                 View trackingView = viewHolder.itemView.findViewById(mViewId);
@@ -165,16 +173,22 @@
                 // add up translation values in parent.
                 float tx = 0, ty = 0;
                 while (trackingView != recyclerView && trackingView != null) {
-                    tx += trackingView.getTranslationX();
-                    ty += trackingView.getTranslationY();
+                    // In RecyclerView dispatchLayout() it may call onScrolled(0) with a move
+                    // ItemAnimation just created. We don't have any way to track the ItemAnimation
+                    // update listener, and in ideal use case, the tracking view should not be
+                    // animated in RecyclerView. Do not apply translation value for this case.
+                    if (!(trackingView.getParent() == recyclerView && recyclerView.isAnimating())) {
+                        tx += trackingView.getTranslationX();
+                        ty += trackingView.getTranslationY();
+                    }
                     trackingView = (View) trackingView.getParent();
                 }
                 rect.offset((int) tx, (int) ty);
                 if (source.mIsVertical) {
-                    source.setPropertyValue(getIndex(), rect.top + mOffset
+                    source.setIntPropertyValue(getIndex(), rect.top + mOffset
                             + (int) (mFraction * rect.height()));
                 } else {
-                    source.setPropertyValue(getIndex(), rect.left + mOffset
+                    source.setIntPropertyValue(getIndex(), rect.left + mOffset
                             + (int) (mFraction * rect.width()));
                 }
             }
@@ -188,7 +202,7 @@
     }
 
     @Override
-    public int getMaxValue() {
+    public float getMaxValue() {
         if (mRecylerView == null) {
             return 0;
         }
@@ -205,6 +219,7 @@
         }
         if (mRecylerView != null) {
             mRecylerView.removeOnScrollListener(mOnScrollListener);
+            mRecylerView.removeOnLayoutChangeListener(mOnLayoutChangeListener);
         }
         mRecylerView = recyclerView;
         if (mRecylerView != null) {
@@ -212,6 +227,7 @@
                     .getProperties(mRecylerView.getContext(), null, 0, 0);
             mIsVertical = properties.orientation == RecyclerView.VERTICAL;
             mRecylerView.addOnScrollListener(mOnScrollListener);
+            mRecylerView.addOnLayoutChangeListener(mOnLayoutChangeListener);
         }
     }
 
@@ -221,8 +237,8 @@
      */
     @Override
     public void updateValues() {
-        for (ChildPositionProperty prop: getProperties()) {
-            prop.updateValue(RecyclerViewParallax.this);
+        for (Property prop: getProperties()) {
+            ((ChildPositionProperty) prop).updateValue(RecyclerViewParallax.this);
         }
         super.updateValues();
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/RowHeaderPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/RowHeaderPresenter.java
index 3556057..4bc00c6 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RowHeaderPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RowHeaderPresenter.java
@@ -213,6 +213,7 @@
         return space;
     }
 
+    @SuppressWarnings("ReferenceEquality")
     protected static float getFontDescent(TextView textView, Paint fontMeasurePaint) {
         if (fontMeasurePaint.getTextSize() != textView.getTextSize()) {
             fontMeasurePaint.setTextSize(textView.getTextSize());
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/TitleViewAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/TitleViewAdapter.java
index 7156be2..de9db4b 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/TitleViewAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/TitleViewAdapter.java
@@ -13,11 +13,7 @@
  */
 package android.support.v17.leanback.widget;
 
-import android.content.Context;
 import android.graphics.drawable.Drawable;
-import android.support.v17.leanback.R;
-import android.util.AttributeSet;
-import android.view.LayoutInflater;
 import android.view.View;
 
 /**
@@ -96,6 +92,10 @@
      * @param listener The listener to call when the search element is clicked.
      */
     public void setOnSearchClickedListener(View.OnClickListener listener) {
+        View view = getSearchAffordanceView();
+        if (view != null) {
+            view.setOnClickListener(listener);
+        }
     }
 
     /**
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/picker/TimePicker.java b/v17/leanback/src/android/support/v17/leanback/widget/picker/TimePicker.java
index a0452f5..90acddf 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/picker/TimePicker.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/picker/TimePicker.java
@@ -18,13 +18,15 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.os.Build;
+import android.support.annotation.IntRange;
 import android.support.v17.leanback.R;
 import android.text.TextUtils;
+import android.text.format.DateFormat;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
 
-import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Calendar;
@@ -35,15 +37,16 @@
  * <p>
  * This class is a widget for selecting time and displays it according to the formatting for the
  * current system locale. The time can be selected by hour, minute, and AM/PM picker columns.
- * The AM/PM mode is activated only when the 12 hour format is desired by setting
- * {@code is24HourFormat} attribute to false. Otherwise, TimePicker displays only two columns for a
- * 24 hour time format.
+ * The AM/PM mode is determined by either explicitly setting the current mode through
+ * {@link #setIs24Hour(boolean)} or the widget attribute {@code is24HourFormat} (true for 24-hour
+ * mode, false for 12-hour mode). Otherwise, TimePicker retrieves the mode based on the current
+ * context. In 24-hour mode, TimePicker displays only the hour and minute columns.
  * <p>
  * This widget can show the current time as the initial value if {@code useCurrentTime} is set to
- * true. Each individual time picker field can be set  set at any time by calling
- * {@link #setHour(int)}, {@link #setMinute(int)} using 24-hour time format. The time format can
- * also be changed at any time by calling {@link #setIs24Hour(boolean)}, and the AM/PM picker column
- * will be activated or deactivated according to the given format.
+ * true. Each individual time picker field can be set at any time by calling {@link #setHour(int)},
+ * {@link #setMinute(int)} using 24-hour time format. The time format can also be changed at any
+ * time by calling {@link #setIs24Hour(boolean)}, and the AM/PM picker column will be activated or
+ * deactivated accordingly.
  *
  * @attr ref R.styleable#lbTimePicker_is24HourFormat
  * @attr ref R.styleable#lbTimePicker_useCurrentTime
@@ -106,7 +109,8 @@
         mPickerView = (ViewGroup) findViewById(R.id.picker);
         final TypedArray attributesArray = context.obtainStyledAttributes(attrs,
                 R.styleable.lbTimePicker);
-        mIs24hFormat = attributesArray.getBoolean(R.styleable.lbTimePicker_is24HourFormat, false);
+        mIs24hFormat = attributesArray.getBoolean(R.styleable.lbTimePicker_is24HourFormat,
+                DateFormat.is24HourFormat(context));
         boolean useCurrentTime = attributesArray.getBoolean(R.styleable.lbTimePicker_useCurrentTime,
                 true);
 
@@ -155,11 +159,21 @@
      */
     private String getTimePickerFormat() {
         // Obtain the time format string per the current locale (e.g. h:mm a)
-        String hmaPattern  = ((SimpleDateFormat) DateFormat
-                .getTimeInstance(DateFormat.SHORT, mConstant.locale)).toPattern();
+        String hmaPattern;
+        if (Build.VERSION.SDK_INT >= 18) {
+            hmaPattern = DateFormat.getBestDateTimePattern(mConstant.locale, "hma");
+        } else {
+            // getTimeInstance is not very reliable and it may not include 'a' (for AM/PM)
+            // in the returned pattern string. In those cases, we assume that am/pm appears at the
+            // end of the fields. Need to find a more reliable way for API below 18.
+            hmaPattern  = ((SimpleDateFormat) java.text.DateFormat
+                    .getTimeInstance(java.text.DateFormat.FULL, mConstant.locale)).toPattern();
+        }
+
         boolean isRTL = TextUtils.getLayoutDirectionFromLocale(mConstant.locale) == View
                 .LAYOUT_DIRECTION_RTL;
-        boolean isAmPmAtEnd = hmaPattern.indexOf("a") > hmaPattern.indexOf("m");
+        boolean isAmPmAtEnd = (hmaPattern.indexOf('a') >= 0)
+                ? (hmaPattern.indexOf("a") > hmaPattern.indexOf("m")) : true;
         // Hour will always appear to the left of minutes regardless of layout direction.
         String timePickerFormat = isRTL ? "mh" : "hm";
 
@@ -242,7 +256,7 @@
      * @param hour the hour to set, in the range (0-23)
      * @see #getHour()
      */
-    public void setHour(int hour) {
+    public void setHour(@IntRange(from = 0, to = 23) int hour) {
         if (hour < 0 || hour > 23) {
             throw new IllegalArgumentException("hour: " + hour + " is not in [0-23] range in");
         }
@@ -286,7 +300,7 @@
      * @param minute the minute to set, in the range (0-59)
      * @see #getMinute()
      */
-    public void setMinute(int minute) {
+    public void setMinute(@IntRange(from = 0, to = 59) int minute) {
         if (mCurrentMinute == minute) {
             return;
         }
diff --git a/v17/leanback/tests/generatev4.py b/v17/leanback/tests/generatev4.py
index 34ace00..9e4f935 100755
--- a/v17/leanback/tests/generatev4.py
+++ b/v17/leanback/tests/generatev4.py
@@ -91,6 +91,7 @@
             line = line.replace('{}Fragment'.format(w), '{}SupportFragment'.format(w))
         for w in testcls:
             line = line.replace('SingleFragmentTestBase', 'SingleSupportFragmentTestBase')
+            line = line.replace('SingleFragmentTestActivity', 'SingleSupportFragmentTestActivity')
             line = line.replace('{}FragmentTestBase'.format(w), '{}SupportFragmentTestBase'.format(w))
             line = line.replace('{}FragmentTest'.format(w), '{}SupportFragmentTest'.format(w))
             line = line.replace('{}FragmentTestActivity'.format(w), '{}SupportFragmentTestActivity'.format(w))
@@ -99,7 +100,7 @@
         line = line.replace('android.app.Activity', 'android.support.v4.app.FragmentActivity')
 	line = line.replace('extends Activity', 'extends FragmentActivity')
 	line = line.replace('Activity.this.getFragmentManager', 'Activity.this.getSupportFragmentManager')
-	line = line.replace('mActivity.getFragmentManager', 'mActivity.getSupportFragmentManager')
+	line = line.replace('tivity.getFragmentManager', 'tivity.getSupportFragmentManager')
         outfile.write(line)
     file.close()
     outfile.close()
@@ -136,12 +137,12 @@
     line = line.replace('IntEffect', 'FloatEffect')
     line = line.replace('IntParallax', 'FloatParallax')
     line = line.replace('IntProperty', 'FloatProperty')
-    line = line.replace('IntValue', 'FloatValue')
     line = line.replace('intValue()', 'floatValue()')
-    line = line.replace('int getMaxValue', 'float getMaxValue')
     line = line.replace('int screenMax', 'float screenMax')
     line = line.replace('assertEquals((int)', 'assertFloatEquals((float)')
     line = line.replace('(int)', '(float)')
+    line = line.replace('int[', 'float[')
+    line = line.replace('Integer', 'Float');
     outfile.write(line)
 file.close()
 outfile.close()
@@ -156,9 +157,8 @@
     line = line.replace('ParallaxIntTest', 'ParallaxFloatTest')
     line = line.replace('IntParallax', 'FloatParallax')
     line = line.replace('IntProperty', 'FloatProperty')
-    line = line.replace('IntValue', 'FloatValue')
+    line = line.replace('verifyIntProperties', 'verifyFloatProperties')
     line = line.replace('intValue()', 'floatValue()')
-    line = line.replace('int getMaxValue', 'float getMaxValue')
     line = line.replace('int screenMax', 'float screenMax')
     line = line.replace('assertEquals((int)', 'assertFloatEquals((float)')
     line = line.replace('(int)', '(float)')
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 b70cc28..913edac 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
@@ -15,25 +15,31 @@
  */
 package android.support.v17.leanback.app;
 
-import static junit.framework.TestCase.assertFalse;
-
 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.animation.PropertyValuesHolder;
+import android.app.Fragment;
+import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
 import android.support.v17.leanback.media.MediaPlayerGlue;
 import android.support.v17.leanback.testutils.PollingCheck;
+import android.support.v17.leanback.transition.TransitionHelper;
+import android.support.v17.leanback.util.StateMachine;
 import android.support.v17.leanback.widget.DetailsParallax;
 import android.support.v17.leanback.widget.DetailsParallaxDrawable;
 import android.support.v17.leanback.widget.ParallaxTarget;
@@ -50,11 +56,16 @@
  * Unit tests for {@link DetailsFragment}.
  */
 @RunWith(JUnit4.class)
-@MediumTest
+@LargeTest
 public class DetailsFragmentTest extends SingleFragmentTestBase {
 
     static final int PARALLAX_VERTICAL_OFFSET = -300;
 
+    static int getCoverDrawableAlpha(DetailsFragmentBackgroundController controller) {
+        return ((FitWidthBitmapDrawable) controller.mParallaxDrawable.getCoverDrawable())
+                .getAlpha();
+    }
+
     public static class DetailsFragmentParallax extends DetailsTestFragment {
 
         private DetailsParallaxDrawable mParallaxDrawable;
@@ -105,12 +116,13 @@
 
     @Test
     public void parallaxSetupTest() {
-        launchAndWaitActivity(DetailsFragmentTest.DetailsFragmentParallax.class,
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsFragmentTest.DetailsFragmentParallax.class,
                 new SingleFragmentTestBase.Options().uiVisibility(
                         View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
 
         double delta = 0.0002;
-        DetailsParallax dpm = ((DetailsFragment) mActivity.getTestFragment()).getParallax();
+        DetailsParallax dpm = ((DetailsFragment) activity.getTestFragment()).getParallax();
 
         RecyclerViewParallax.ChildPositionProperty frameTop =
                 (RecyclerViewParallax.ChildPositionProperty) dpm.getOverviewRowTop();
@@ -126,12 +138,12 @@
 
     @Test
     public void parallaxTest() throws Throwable {
-        launchAndWaitActivity(DetailsFragmentParallax.class,
+        SingleFragmentTestActivity activity = launchAndWaitActivity(DetailsFragmentParallax.class,
                 new Options().uiVisibility(
                         View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
 
         final DetailsFragmentParallax detailsFragment =
-                (DetailsFragmentParallax) mActivity.getTestFragment();
+                (DetailsFragmentParallax) activity.getTestFragment();
         DetailsParallaxDrawable drawable =
                 detailsFragment.getParallaxDrawable();
         final FitWidthBitmapDrawable bitmapDrawable = (FitWidthBitmapDrawable)
@@ -151,8 +163,8 @@
         final int windowWidth = verticalGridView.getWidth();
         // make sure background manager attached to window is same size as VerticalGridView
         // i.e. no status bar.
-        assertEquals(windowHeight, mActivity.getWindow().getDecorView().getHeight());
-        assertEquals(windowWidth, mActivity.getWindow().getDecorView().getWidth());
+        assertEquals(windowHeight, activity.getWindow().getDecorView().getHeight());
+        assertEquals(windowWidth, activity.getWindow().getDecorView().getWidth());
 
         final View detailsFrame = verticalGridView.findViewById(R.id.details_frame);
 
@@ -225,8 +237,6 @@
         @Override
         public void onStart() {
             super.onStart();
-            setItem(new PhotoItem("Hello world", "Fake content goes here",
-                    android.support.v17.leanback.test.R.drawable.spiderman));
             Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
                     android.support.v17.leanback.test.R.drawable.spiderman);
             mDetailsBackground.setCoverBitmap(bitmap);
@@ -239,14 +249,34 @@
         }
     }
 
-    @Test
-    public void navigateBetweenRowsAndVideoUsingRequestFocus() throws Throwable {
-        launchAndWaitActivity(DetailsFragmentWithVideo.class,
+    public static class DetailsFragmentWithVideo1 extends DetailsFragmentWithVideo {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setItem(new PhotoItem("Hello world", "Fake content goes here",
+                    android.support.v17.leanback.test.R.drawable.spiderman));
+        }
+    }
+
+    public static class DetailsFragmentWithVideo2 extends DetailsFragmentWithVideo {
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            setItem(new PhotoItem("Hello world", "Fake content goes here",
+                    android.support.v17.leanback.test.R.drawable.spiderman));
+        }
+    }
+
+    private void navigateBetweenRowsAndVideoUsingRequestFocusInternal(Class cls)
+            throws Throwable {
+        SingleFragmentTestActivity activity = launchAndWaitActivity(cls,
                 new Options().uiVisibility(
                         View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
 
         final DetailsFragmentWithVideo detailsFragment =
-                (DetailsFragmentWithVideo) mActivity.getTestFragment();
+                (DetailsFragmentWithVideo) activity.getTestFragment();
         PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
@@ -261,7 +291,7 @@
         final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0);
         final int originalFirstRowTop = firstRow.getTop();
         assertTrue(firstRow.hasFocus());
-        assertTrue(firstRow.getTop() < screenHeight);
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
         assertTrue(detailsFragment.isShowingTitle());
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@@ -294,13 +324,23 @@
     }
 
     @Test
-    public void navigateBetweenRowsAndVideoUsingDPAD() throws Throwable {
-        launchAndWaitActivity(DetailsFragmentWithVideo.class,
+    public void navigateBetweenRowsAndVideoUsingRequestFocus1() throws Throwable {
+        navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsFragmentWithVideo1.class);
+    }
+
+    @Test
+    public void navigateBetweenRowsAndVideoUsingRequestFocus2() throws Throwable {
+        navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsFragmentWithVideo2.class);
+    }
+
+    private void navigateBetweenRowsAndVideoUsingDPADInternal(Class cls) throws Throwable {
+        SingleFragmentTestActivity activity = launchAndWaitActivity(cls,
                 new Options().uiVisibility(
                         View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
 
         final DetailsFragmentWithVideo detailsFragment =
-                (DetailsFragmentWithVideo) mActivity.getTestFragment();
+                (DetailsFragmentWithVideo) activity.getTestFragment();
+        // wait video playing
         PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
@@ -315,9 +355,10 @@
         final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0);
         final int originalFirstRowTop = firstRow.getTop();
         assertTrue(firstRow.hasFocus());
-        assertTrue(firstRow.getTop() < screenHeight);
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
         assertTrue(detailsFragment.isShowingTitle());
 
+        // navigate to video
         sendKeys(KeyEvent.KEYCODE_DPAD_UP);
         PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
             @Override
@@ -325,9 +366,17 @@
                 return firstRow.getTop() >= screenHeight;
             }
         });
-        assertFalse(detailsFragment.isShowingTitle());
 
-        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+        // wait auto hide play controls done:
+        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((PlaybackFragment) detailsFragment.mVideoFragment).mBgAlpha == 0;
+            }
+        });
+
+        // navigate to details
+        sendKeys(KeyEvent.KEYCODE_BACK);
         PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
@@ -338,11 +387,95 @@
     }
 
     @Test
+    public void navigateBetweenRowsAndVideoUsingDPAD1() throws Throwable {
+        navigateBetweenRowsAndVideoUsingDPADInternal(DetailsFragmentWithVideo1.class);
+    }
+
+    @Test
+    public void navigateBetweenRowsAndVideoUsingDPAD2() throws Throwable {
+        navigateBetweenRowsAndVideoUsingDPADInternal(DetailsFragmentWithVideo2.class);
+    }
+
+    public static class EmptyFragmentClass extends Fragment {
+        @Override
+        public void onStart() {
+            super.onStart();
+            getActivity().finish();
+        }
+    }
+
+    private void fragmentOnStartWithVideoInternal(Class cls) throws Throwable {
+        final SingleFragmentTestActivity activity = launchAndWaitActivity(cls,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+
+        final DetailsFragmentWithVideo detailsFragment =
+                (DetailsFragmentWithVideo) activity.getTestFragment();
+        // wait video playing
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mVideoFragment != null
+                        && detailsFragment.mVideoFragment.getView() != null
+                        && detailsFragment.mGlue.isMediaPlaying();
+            }
+        });
+
+        final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView()
+                .getHeight();
+        final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0);
+        final int originalFirstRowTop = firstRow.getTop();
+        assertTrue(firstRow.hasFocus());
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
+        assertTrue(detailsFragment.isShowingTitle());
+
+        // navigate to video
+        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return firstRow.getTop() >= screenHeight;
+            }
+        });
+
+        // start an empty activity
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        Intent intent = new Intent(activity, SingleFragmentTestActivity.class);
+                        intent.putExtra(SingleFragmentTestActivity.EXTRA_FRAGMENT_NAME,
+                                EmptyFragmentClass.class.getName());
+                        activity.startActivity(intent);
+                    }
+                }
+        );
+        PollingCheck.waitFor(2000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.isResumed();
+            }
+        });
+        assertTrue(detailsFragment.mVideoFragment.getView().hasFocus());
+    }
+
+    @Test
+    public void fragmentOnStartWithVideo1() throws Throwable {
+        fragmentOnStartWithVideoInternal(DetailsFragmentWithVideo1.class);
+    }
+
+    @Test
+    public void fragmentOnStartWithVideo2() throws Throwable {
+        fragmentOnStartWithVideoInternal(DetailsFragmentWithVideo2.class);
+    }
+
+    @Test
     public void navigateBetweenRowsAndTitle() throws Throwable {
-        launchAndWaitActivity(DetailsTestFragment.class, new Options().uiVisibility(
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsTestFragment.class, new Options().uiVisibility(
                 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
         final DetailsTestFragment detailsFragment =
-                (DetailsTestFragment) mActivity.getTestFragment();
+                (DetailsTestFragment) activity.getTestFragment();
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
@@ -370,7 +503,7 @@
 
         assertTrue(firstRow.hasFocus());
         assertTrue(detailsFragment.isShowingTitle());
-        assertTrue(firstRow.getTop() < screenHeight);
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
 
         sendKeys(KeyEvent.KEYCODE_DPAD_UP);
         PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
@@ -385,4 +518,599 @@
         assertEquals(originalFirstRowTop, firstRow.getTop());
     }
 
+    public static class DetailsFragmentWithNoVideo extends DetailsTestFragment {
+
+        final DetailsFragmentBackgroundController mDetailsBackground =
+                new DetailsFragmentBackgroundController(this);
+
+        public DetailsFragmentWithNoVideo() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+
+            setItem(new PhotoItem("Hello world", "Fake content goes here",
+                    android.support.v17.leanback.test.R.drawable.spiderman));
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void lateSetupVideo() {
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsFragmentWithNoVideo.class, new Options().uiVisibility(
+                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsFragmentWithNoVideo detailsFragment =
+                (DetailsFragmentWithNoVideo) activity.getTestFragment();
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+                        android.support.v17.leanback.test.R.drawable.spiderman));
+            }
+        });
+
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.getRowsFragment().getVerticalGridView().getChildCount() > 0;
+            }
+        });
+        final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0);
+        final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView()
+                .getHeight();
+
+        assertTrue(firstRow.hasFocus());
+        assertTrue(detailsFragment.isShowingTitle());
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
+
+        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+        assertTrue(firstRow.hasFocus());
+
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
+                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue.setArtist("A Googleer");
+                        glue.setTitle("Diving with Sharks");
+                        glue.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        // after setup Video Playback the DPAD up will navigate to Video Fragment.
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+                @Override
+                    public boolean canProceed() {
+                        return detailsFragment.mVideoFragment != null
+                                && detailsFragment.mVideoFragment.getView() != null;
+                }
+        });
+        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+        assertTrue(detailsFragment.mVideoFragment.getView().hasFocus());
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController
+                        .getPlaybackGlue()).isMediaPlaying();
+            }
+        });
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
+            }
+        });
+
+        // wait a little bit to replace with new Glue
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue2 = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2);
+                        glue2.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue2.setArtist("A Googleer");
+                        glue2.setTitle("Diving with Sharks");
+                        glue2.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        // test switchToRows() and switchToVideo()
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.mDetailsBackgroundController.switchToRows();
+                    }
+                }
+        );
+        assertTrue(detailsFragment.mRowsFragment.getView().hasFocus());
+        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.mDetailsBackgroundController.switchToVideo();
+                    }
+                }
+        );
+        assertTrue(detailsFragment.mVideoFragment.getView().hasFocus());
+        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
+    }
+
+    @Test
+    public void clearVideo() {
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsFragmentWithNoVideo.class, new Options().uiVisibility(
+                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsFragmentWithNoVideo detailsFragment =
+                (DetailsFragmentWithNoVideo) activity.getTestFragment();
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+                        android.support.v17.leanback.test.R.drawable.spiderman));
+            }
+        });
+
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.getRowsFragment().getVerticalGridView().getChildCount() > 0;
+            }
+        });
+        final View firstRow = detailsFragment.getRowsFragment().getVerticalGridView().getChildAt(0);
+        final int screenHeight = detailsFragment.getRowsFragment().getVerticalGridView()
+                .getHeight();
+
+        assertTrue(firstRow.hasFocus());
+        assertTrue(detailsFragment.isShowingTitle());
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
+
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
+                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue.setArtist("A Googleer");
+                        glue.setTitle("Diving with Sharks");
+                        glue.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController
+                        .getPlaybackGlue()).isMediaPlaying();
+            }
+        });
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
+            }
+        });
+
+        // wait a little bit then clear glue
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(null);
+                    }
+                }
+        );
+        // background should fade in upon clear playback
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 255 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
+            }
+        });
+    }
+
+    public static class DetailsFragmentWithNoItem extends DetailsTestFragment {
+
+        final DetailsFragmentBackgroundController mDetailsBackground =
+                new DetailsFragmentBackgroundController(this);
+
+        public DetailsFragmentWithNoItem() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void noInitialItem() {
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsFragmentWithNoItem.class, new Options().uiVisibility(
+                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsFragmentWithNoItem detailsFragment =
+                (DetailsFragmentWithNoItem) activity.getTestFragment();
+
+        final int recyclerViewHeight = detailsFragment.getRowsFragment().getVerticalGridView()
+                .getHeight();
+        assertTrue(recyclerViewHeight > 0);
+
+        assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
+        Drawable coverDrawable = detailsFragment.mDetailsBackgroundController.getCoverDrawable();
+        assertEquals(0, coverDrawable.getBounds().top);
+        assertEquals(recyclerViewHeight, coverDrawable.getBounds().bottom);
+        Drawable bottomDrawable = detailsFragment.mDetailsBackgroundController.getBottomDrawable();
+        assertEquals(recyclerViewHeight, bottomDrawable.getBounds().top);
+        assertEquals(recyclerViewHeight, bottomDrawable.getBounds().bottom);
+    }
+
+    public static class DetailsFragmentSwitchToVideoInOnCreate extends DetailsTestFragment {
+
+        final DetailsFragmentBackgroundController mDetailsBackground =
+                new DetailsFragmentBackgroundController(this);
+
+        public DetailsFragmentSwitchToVideoInOnCreate() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+            mDetailsBackground.switchToVideo();
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void switchToVideoInOnCreate() {
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsFragmentSwitchToVideoInOnCreate.class,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsFragmentSwitchToVideoInOnCreate detailsFragment =
+                (DetailsFragmentSwitchToVideoInOnCreate) activity.getTestFragment();
+
+        // the pending enter transition flag should be automatically cleared
+        assertEquals(StateMachine.STATUS_INVOKED,
+                detailsFragment.STATE_ENTER_TRANSITION_COMPLETE.getStatus());
+        assertNull(TransitionHelper.getEnterTransition(activity.getWindow()));
+        assertEquals(0, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
+        assertTrue(detailsFragment.getRowsFragment().getView().hasFocus());
+        //SystemClock.sleep(5000);
+        assertFalse(detailsFragment.isShowingTitle());
+
+        SystemClock.sleep(1000);
+        assertNull(detailsFragment.mVideoFragment);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
+                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue.setArtist("A Googleer");
+                        glue.setTitle("Diving with Sharks");
+                        glue.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+        // once the video fragment is created it would be immediately assigned focus
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mVideoFragment != null
+                        && detailsFragment.mVideoFragment.getView() != null
+                        && detailsFragment.mVideoFragment.getView().hasFocus();
+            }
+        });
+        // wait auto hide play controls done:
+        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((PlaybackFragment) detailsFragment.mVideoFragment).mBgAlpha == 0;
+            }
+        });
+
+        // switchToRows does nothing if there is no row
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.mDetailsBackgroundController.switchToRows();
+                    }
+                }
+        );
+        assertTrue(detailsFragment.mVideoFragment.getView().hasFocus());
+
+        // create item, it should be layout outside screen
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.setItem(new PhotoItem("Hello world",
+                                "Fake content goes here",
+                                android.support.v17.leanback.test.R.drawable.spiderman));
+                    }
+                }
+        );
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.getVerticalGridView().getChildCount() > 0
+                        && detailsFragment.getVerticalGridView().getChildAt(0).getTop()
+                        >= detailsFragment.getVerticalGridView().getHeight();
+            }
+        });
+
+        // pressing BACK will return to details row
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.getVerticalGridView().getChildAt(0).getTop()
+                        < (detailsFragment.getVerticalGridView().getHeight() * 0.7f);
+            }
+        });
+        assertTrue(detailsFragment.getVerticalGridView().getChildAt(0).hasFocus());
+    }
+
+    @Test
+    public void switchToVideoBackToQuit() {
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsFragmentSwitchToVideoInOnCreate.class,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsFragmentSwitchToVideoInOnCreate detailsFragment =
+                (DetailsFragmentSwitchToVideoInOnCreate) activity.getTestFragment();
+
+        // the pending enter transition flag should be automatically cleared
+        assertEquals(StateMachine.STATUS_INVOKED,
+                detailsFragment.STATE_ENTER_TRANSITION_COMPLETE.getStatus());
+        assertNull(TransitionHelper.getEnterTransition(activity.getWindow()));
+        assertEquals(0, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
+        assertTrue(detailsFragment.getRowsFragment().getView().hasFocus());
+        assertFalse(detailsFragment.isShowingTitle());
+
+        SystemClock.sleep(1000);
+        assertNull(detailsFragment.mVideoFragment);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
+                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue.setArtist("A Googleer");
+                        glue.setTitle("Diving with Sharks");
+                        glue.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+        // once the video fragment is created it would be immediately assigned focus
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mVideoFragment != null
+                        && detailsFragment.mVideoFragment.getView() != null
+                        && detailsFragment.mVideoFragment.getView().hasFocus();
+            }
+        });
+        // wait auto hide play controls done:
+        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((PlaybackFragment) detailsFragment.mVideoFragment).mBgAlpha == 0;
+            }
+        });
+
+        // before any details row is presented, pressing BACK will quit the activity
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        PollingCheck.waitFor(4000, new PollingCheck.ActivityDestroy(activity));
+    }
+
+    public static class DetailsFragmentSwitchToVideoAndPrepareEntranceTransition
+            extends DetailsTestFragment {
+
+        final DetailsFragmentBackgroundController mDetailsBackground =
+                new DetailsFragmentBackgroundController(this);
+
+        public DetailsFragmentSwitchToVideoAndPrepareEntranceTransition() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+            mDetailsBackground.switchToVideo();
+            prepareEntranceTransition();
+        }
+
+        @Override
+        public void onViewCreated(View view, Bundle savedInstanceState) {
+            super.onViewCreated(view, savedInstanceState);
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void switchToVideoInOnCreateAndPrepareEntranceTransition() {
+        SingleFragmentTestActivity activity = launchAndWaitActivity(
+                DetailsFragmentSwitchToVideoAndPrepareEntranceTransition.class,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsFragmentSwitchToVideoAndPrepareEntranceTransition detailsFragment =
+                (DetailsFragmentSwitchToVideoAndPrepareEntranceTransition)
+                        activity.getTestFragment();
+
+        assertEquals(StateMachine.STATUS_INVOKED,
+                detailsFragment.STATE_ENTRANCE_COMPLETE.getStatus());
+    }
+
+    public static class DetailsFragmentEntranceTransition
+            extends DetailsTestFragment {
+
+        final DetailsFragmentBackgroundController mDetailsBackground =
+                new DetailsFragmentBackgroundController(this);
+
+        public DetailsFragmentEntranceTransition() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+            prepareEntranceTransition();
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void entranceTransitionBlocksSwitchToVideo() {
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsFragmentEntranceTransition.class,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsFragmentEntranceTransition detailsFragment =
+                (DetailsFragmentEntranceTransition)
+                        activity.getTestFragment();
+
+        if (Build.VERSION.SDK_INT < 21) {
+            // when enter transition is not supported, mCanUseHost is immmediately true
+            assertTrue(detailsFragment.mDetailsBackgroundController.mCanUseHost);
+        } else {
+            // calling switchToVideo() between prepareEntranceTransition and entrance transition
+            // finishes will be ignored.
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    detailsFragment.mDetailsBackgroundController.switchToVideo();
+                }
+            });
+            assertFalse(detailsFragment.mDetailsBackgroundController.mCanUseHost);
+        }
+        assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+                        android.support.v17.leanback.test.R.drawable.spiderman));
+                detailsFragment.startEntranceTransition();
+            }
+        });
+        // once Entrance transition is finished, mCanUseHost will be true
+        // and we can switchToVideo and fade out the background.
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mDetailsBackgroundController.mCanUseHost;
+            }
+        });
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.mDetailsBackgroundController.switchToVideo();
+            }
+        });
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
+            }
+        });
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
index 3880a7c..39ab734 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/DetailsSupportFragmentTest.java
@@ -18,25 +18,31 @@
  */
 package android.support.v17.leanback.app;
 
-import static junit.framework.TestCase.assertFalse;
-
 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.animation.PropertyValuesHolder;
+import android.support.v4.app.Fragment;
+import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.graphics.FitWidthBitmapDrawable;
 import android.support.v17.leanback.media.MediaPlayerGlue;
 import android.support.v17.leanback.testutils.PollingCheck;
+import android.support.v17.leanback.transition.TransitionHelper;
+import android.support.v17.leanback.util.StateMachine;
 import android.support.v17.leanback.widget.DetailsParallax;
 import android.support.v17.leanback.widget.DetailsParallaxDrawable;
 import android.support.v17.leanback.widget.ParallaxTarget;
@@ -53,11 +59,16 @@
  * Unit tests for {@link DetailsSupportFragment}.
  */
 @RunWith(JUnit4.class)
-@MediumTest
+@LargeTest
 public class DetailsSupportFragmentTest extends SingleSupportFragmentTestBase {
 
     static final int PARALLAX_VERTICAL_OFFSET = -300;
 
+    static int getCoverDrawableAlpha(DetailsSupportFragmentBackgroundController controller) {
+        return ((FitWidthBitmapDrawable) controller.mParallaxDrawable.getCoverDrawable())
+                .getAlpha();
+    }
+
     public static class DetailsSupportFragmentParallax extends DetailsTestSupportFragment {
 
         private DetailsParallaxDrawable mParallaxDrawable;
@@ -108,12 +119,13 @@
 
     @Test
     public void parallaxSetupTest() {
-        launchAndWaitActivity(DetailsSupportFragmentTest.DetailsSupportFragmentParallax.class,
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsSupportFragmentTest.DetailsSupportFragmentParallax.class,
                 new SingleSupportFragmentTestBase.Options().uiVisibility(
                         View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
 
         double delta = 0.0002;
-        DetailsParallax dpm = ((DetailsSupportFragment) mActivity.getTestFragment()).getParallax();
+        DetailsParallax dpm = ((DetailsSupportFragment) activity.getTestFragment()).getParallax();
 
         RecyclerViewParallax.ChildPositionProperty frameTop =
                 (RecyclerViewParallax.ChildPositionProperty) dpm.getOverviewRowTop();
@@ -129,12 +141,12 @@
 
     @Test
     public void parallaxTest() throws Throwable {
-        launchAndWaitActivity(DetailsSupportFragmentParallax.class,
+        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(DetailsSupportFragmentParallax.class,
                 new Options().uiVisibility(
                         View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
 
         final DetailsSupportFragmentParallax detailsFragment =
-                (DetailsSupportFragmentParallax) mActivity.getTestFragment();
+                (DetailsSupportFragmentParallax) activity.getTestFragment();
         DetailsParallaxDrawable drawable =
                 detailsFragment.getParallaxDrawable();
         final FitWidthBitmapDrawable bitmapDrawable = (FitWidthBitmapDrawable)
@@ -154,8 +166,8 @@
         final int windowWidth = verticalGridView.getWidth();
         // make sure background manager attached to window is same size as VerticalGridView
         // i.e. no status bar.
-        assertEquals(windowHeight, mActivity.getWindow().getDecorView().getHeight());
-        assertEquals(windowWidth, mActivity.getWindow().getDecorView().getWidth());
+        assertEquals(windowHeight, activity.getWindow().getDecorView().getHeight());
+        assertEquals(windowWidth, activity.getWindow().getDecorView().getWidth());
 
         final View detailsFrame = verticalGridView.findViewById(R.id.details_frame);
 
@@ -228,8 +240,6 @@
         @Override
         public void onStart() {
             super.onStart();
-            setItem(new PhotoItem("Hello world", "Fake content goes here",
-                    android.support.v17.leanback.test.R.drawable.spiderman));
             Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
                     android.support.v17.leanback.test.R.drawable.spiderman);
             mDetailsBackground.setCoverBitmap(bitmap);
@@ -242,14 +252,34 @@
         }
     }
 
-    @Test
-    public void navigateBetweenRowsAndVideoUsingRequestFocus() throws Throwable {
-        launchAndWaitActivity(DetailsSupportFragmentWithVideo.class,
+    public static class DetailsSupportFragmentWithVideo1 extends DetailsSupportFragmentWithVideo {
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setItem(new PhotoItem("Hello world", "Fake content goes here",
+                    android.support.v17.leanback.test.R.drawable.spiderman));
+        }
+    }
+
+    public static class DetailsSupportFragmentWithVideo2 extends DetailsSupportFragmentWithVideo {
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            setItem(new PhotoItem("Hello world", "Fake content goes here",
+                    android.support.v17.leanback.test.R.drawable.spiderman));
+        }
+    }
+
+    private void navigateBetweenRowsAndVideoUsingRequestFocusInternal(Class cls)
+            throws Throwable {
+        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(cls,
                 new Options().uiVisibility(
                         View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
 
         final DetailsSupportFragmentWithVideo detailsFragment =
-                (DetailsSupportFragmentWithVideo) mActivity.getTestFragment();
+                (DetailsSupportFragmentWithVideo) activity.getTestFragment();
         PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
@@ -264,7 +294,7 @@
         final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
         final int originalFirstRowTop = firstRow.getTop();
         assertTrue(firstRow.hasFocus());
-        assertTrue(firstRow.getTop() < screenHeight);
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
         assertTrue(detailsFragment.isShowingTitle());
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@@ -297,13 +327,23 @@
     }
 
     @Test
-    public void navigateBetweenRowsAndVideoUsingDPAD() throws Throwable {
-        launchAndWaitActivity(DetailsSupportFragmentWithVideo.class,
+    public void navigateBetweenRowsAndVideoUsingRequestFocus1() throws Throwable {
+        navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsSupportFragmentWithVideo1.class);
+    }
+
+    @Test
+    public void navigateBetweenRowsAndVideoUsingRequestFocus2() throws Throwable {
+        navigateBetweenRowsAndVideoUsingRequestFocusInternal(DetailsSupportFragmentWithVideo2.class);
+    }
+
+    private void navigateBetweenRowsAndVideoUsingDPADInternal(Class cls) throws Throwable {
+        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(cls,
                 new Options().uiVisibility(
                         View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
 
         final DetailsSupportFragmentWithVideo detailsFragment =
-                (DetailsSupportFragmentWithVideo) mActivity.getTestFragment();
+                (DetailsSupportFragmentWithVideo) activity.getTestFragment();
+        // wait video playing
         PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
@@ -318,9 +358,10 @@
         final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
         final int originalFirstRowTop = firstRow.getTop();
         assertTrue(firstRow.hasFocus());
-        assertTrue(firstRow.getTop() < screenHeight);
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
         assertTrue(detailsFragment.isShowingTitle());
 
+        // navigate to video
         sendKeys(KeyEvent.KEYCODE_DPAD_UP);
         PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
             @Override
@@ -328,9 +369,17 @@
                 return firstRow.getTop() >= screenHeight;
             }
         });
-        assertFalse(detailsFragment.isShowingTitle());
 
-        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+        // wait auto hide play controls done:
+        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((PlaybackSupportFragment) detailsFragment.mVideoSupportFragment).mBgAlpha == 0;
+            }
+        });
+
+        // navigate to details
+        sendKeys(KeyEvent.KEYCODE_BACK);
         PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
@@ -341,11 +390,95 @@
     }
 
     @Test
+    public void navigateBetweenRowsAndVideoUsingDPAD1() throws Throwable {
+        navigateBetweenRowsAndVideoUsingDPADInternal(DetailsSupportFragmentWithVideo1.class);
+    }
+
+    @Test
+    public void navigateBetweenRowsAndVideoUsingDPAD2() throws Throwable {
+        navigateBetweenRowsAndVideoUsingDPADInternal(DetailsSupportFragmentWithVideo2.class);
+    }
+
+    public static class EmptyFragmentClass extends Fragment {
+        @Override
+        public void onStart() {
+            super.onStart();
+            getActivity().finish();
+        }
+    }
+
+    private void fragmentOnStartWithVideoInternal(Class cls) throws Throwable {
+        final SingleSupportFragmentTestActivity activity = launchAndWaitActivity(cls,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+
+        final DetailsSupportFragmentWithVideo detailsFragment =
+                (DetailsSupportFragmentWithVideo) activity.getTestFragment();
+        // wait video playing
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mVideoSupportFragment != null
+                        && detailsFragment.mVideoSupportFragment.getView() != null
+                        && detailsFragment.mGlue.isMediaPlaying();
+            }
+        });
+
+        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
+                .getHeight();
+        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
+        final int originalFirstRowTop = firstRow.getTop();
+        assertTrue(firstRow.hasFocus());
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
+        assertTrue(detailsFragment.isShowingTitle());
+
+        // navigate to video
+        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return firstRow.getTop() >= screenHeight;
+            }
+        });
+
+        // start an empty activity
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        Intent intent = new Intent(activity, SingleSupportFragmentTestActivity.class);
+                        intent.putExtra(SingleSupportFragmentTestActivity.EXTRA_FRAGMENT_NAME,
+                                EmptyFragmentClass.class.getName());
+                        activity.startActivity(intent);
+                    }
+                }
+        );
+        PollingCheck.waitFor(2000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.isResumed();
+            }
+        });
+        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
+    }
+
+    @Test
+    public void fragmentOnStartWithVideo1() throws Throwable {
+        fragmentOnStartWithVideoInternal(DetailsSupportFragmentWithVideo1.class);
+    }
+
+    @Test
+    public void fragmentOnStartWithVideo2() throws Throwable {
+        fragmentOnStartWithVideoInternal(DetailsSupportFragmentWithVideo2.class);
+    }
+
+    @Test
     public void navigateBetweenRowsAndTitle() throws Throwable {
-        launchAndWaitActivity(DetailsTestSupportFragment.class, new Options().uiVisibility(
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsTestSupportFragment.class, new Options().uiVisibility(
                 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
         final DetailsTestSupportFragment detailsFragment =
-                (DetailsTestSupportFragment) mActivity.getTestFragment();
+                (DetailsTestSupportFragment) activity.getTestFragment();
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
@@ -373,7 +506,7 @@
 
         assertTrue(firstRow.hasFocus());
         assertTrue(detailsFragment.isShowingTitle());
-        assertTrue(firstRow.getTop() < screenHeight);
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
 
         sendKeys(KeyEvent.KEYCODE_DPAD_UP);
         PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
@@ -388,4 +521,599 @@
         assertEquals(originalFirstRowTop, firstRow.getTop());
     }
 
+    public static class DetailsSupportFragmentWithNoVideo extends DetailsTestSupportFragment {
+
+        final DetailsSupportFragmentBackgroundController mDetailsBackground =
+                new DetailsSupportFragmentBackgroundController(this);
+
+        public DetailsSupportFragmentWithNoVideo() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+
+            setItem(new PhotoItem("Hello world", "Fake content goes here",
+                    android.support.v17.leanback.test.R.drawable.spiderman));
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void lateSetupVideo() {
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(
+                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsSupportFragmentWithNoVideo detailsFragment =
+                (DetailsSupportFragmentWithNoVideo) activity.getTestFragment();
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+                        android.support.v17.leanback.test.R.drawable.spiderman));
+            }
+        });
+
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildCount() > 0;
+            }
+        });
+        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
+        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
+                .getHeight();
+
+        assertTrue(firstRow.hasFocus());
+        assertTrue(detailsFragment.isShowingTitle());
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
+
+        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+        assertTrue(firstRow.hasFocus());
+
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
+                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue.setArtist("A Googleer");
+                        glue.setTitle("Diving with Sharks");
+                        glue.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        // after setup Video Playback the DPAD up will navigate to Video Fragment.
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+                @Override
+                    public boolean canProceed() {
+                        return detailsFragment.mVideoSupportFragment != null
+                                && detailsFragment.mVideoSupportFragment.getView() != null;
+                }
+        });
+        sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController
+                        .getPlaybackGlue()).isMediaPlaying();
+            }
+        });
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
+            }
+        });
+
+        // wait a little bit to replace with new Glue
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue2 = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue2);
+                        glue2.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue2.setArtist("A Googleer");
+                        glue2.setTitle("Diving with Sharks");
+                        glue2.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        // test switchToRows() and switchToVideo()
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.mDetailsBackgroundController.switchToRows();
+                    }
+                }
+        );
+        assertTrue(detailsFragment.mRowsSupportFragment.getView().hasFocus());
+        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.mDetailsBackgroundController.switchToVideo();
+                    }
+                }
+        );
+        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
+        PollingCheck.waitFor(new PollingCheck.ViewStableOnScreen(firstRow));
+    }
+
+    @Test
+    public void clearVideo() {
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsSupportFragmentWithNoVideo.class, new Options().uiVisibility(
+                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsSupportFragmentWithNoVideo detailsFragment =
+                (DetailsSupportFragmentWithNoVideo) activity.getTestFragment();
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+                        android.support.v17.leanback.test.R.drawable.spiderman));
+            }
+        });
+
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildCount() > 0;
+            }
+        });
+        final View firstRow = detailsFragment.getRowsSupportFragment().getVerticalGridView().getChildAt(0);
+        final int screenHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
+                .getHeight();
+
+        assertTrue(firstRow.hasFocus());
+        assertTrue(detailsFragment.isShowingTitle());
+        assertTrue(firstRow.getTop() > 0 && firstRow.getTop() < screenHeight);
+
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
+                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue.setArtist("A Googleer");
+                        glue.setTitle("Diving with Sharks");
+                        glue.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((MediaPlayerGlue) detailsFragment.mDetailsBackgroundController
+                        .getPlaybackGlue()).isMediaPlaying();
+            }
+        });
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
+            }
+        });
+
+        // wait a little bit then clear glue
+        SystemClock.sleep(1000);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(null);
+                    }
+                }
+        );
+        // background should fade in upon clear playback
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 255 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
+            }
+        });
+    }
+
+    public static class DetailsSupportFragmentWithNoItem extends DetailsTestSupportFragment {
+
+        final DetailsSupportFragmentBackgroundController mDetailsBackground =
+                new DetailsSupportFragmentBackgroundController(this);
+
+        public DetailsSupportFragmentWithNoItem() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void noInitialItem() {
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsSupportFragmentWithNoItem.class, new Options().uiVisibility(
+                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsSupportFragmentWithNoItem detailsFragment =
+                (DetailsSupportFragmentWithNoItem) activity.getTestFragment();
+
+        final int recyclerViewHeight = detailsFragment.getRowsSupportFragment().getVerticalGridView()
+                .getHeight();
+        assertTrue(recyclerViewHeight > 0);
+
+        assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
+        Drawable coverDrawable = detailsFragment.mDetailsBackgroundController.getCoverDrawable();
+        assertEquals(0, coverDrawable.getBounds().top);
+        assertEquals(recyclerViewHeight, coverDrawable.getBounds().bottom);
+        Drawable bottomDrawable = detailsFragment.mDetailsBackgroundController.getBottomDrawable();
+        assertEquals(recyclerViewHeight, bottomDrawable.getBounds().top);
+        assertEquals(recyclerViewHeight, bottomDrawable.getBounds().bottom);
+    }
+
+    public static class DetailsSupportFragmentSwitchToVideoInOnCreate extends DetailsTestSupportFragment {
+
+        final DetailsSupportFragmentBackgroundController mDetailsBackground =
+                new DetailsSupportFragmentBackgroundController(this);
+
+        public DetailsSupportFragmentSwitchToVideoInOnCreate() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+            mDetailsBackground.switchToVideo();
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void switchToVideoInOnCreate() {
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsSupportFragmentSwitchToVideoInOnCreate.class,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsSupportFragmentSwitchToVideoInOnCreate detailsFragment =
+                (DetailsSupportFragmentSwitchToVideoInOnCreate) activity.getTestFragment();
+
+        // the pending enter transition flag should be automatically cleared
+        assertEquals(StateMachine.STATUS_INVOKED,
+                detailsFragment.STATE_ENTER_TRANSITION_COMPLETE.getStatus());
+        assertNull(TransitionHelper.getEnterTransition(activity.getWindow()));
+        assertEquals(0, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
+        assertTrue(detailsFragment.getRowsSupportFragment().getView().hasFocus());
+        //SystemClock.sleep(5000);
+        assertFalse(detailsFragment.isShowingTitle());
+
+        SystemClock.sleep(1000);
+        assertNull(detailsFragment.mVideoSupportFragment);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
+                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue.setArtist("A Googleer");
+                        glue.setTitle("Diving with Sharks");
+                        glue.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+        // once the video fragment is created it would be immediately assigned focus
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mVideoSupportFragment != null
+                        && detailsFragment.mVideoSupportFragment.getView() != null
+                        && detailsFragment.mVideoSupportFragment.getView().hasFocus();
+            }
+        });
+        // wait auto hide play controls done:
+        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((PlaybackSupportFragment) detailsFragment.mVideoSupportFragment).mBgAlpha == 0;
+            }
+        });
+
+        // switchToRows does nothing if there is no row
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.mDetailsBackgroundController.switchToRows();
+                    }
+                }
+        );
+        assertTrue(detailsFragment.mVideoSupportFragment.getView().hasFocus());
+
+        // create item, it should be layout outside screen
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        detailsFragment.setItem(new PhotoItem("Hello world",
+                                "Fake content goes here",
+                                android.support.v17.leanback.test.R.drawable.spiderman));
+                    }
+                }
+        );
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.getVerticalGridView().getChildCount() > 0
+                        && detailsFragment.getVerticalGridView().getChildAt(0).getTop()
+                        >= detailsFragment.getVerticalGridView().getHeight();
+            }
+        });
+
+        // pressing BACK will return to details row
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.getVerticalGridView().getChildAt(0).getTop()
+                        < (detailsFragment.getVerticalGridView().getHeight() * 0.7f);
+            }
+        });
+        assertTrue(detailsFragment.getVerticalGridView().getChildAt(0).hasFocus());
+    }
+
+    @Test
+    public void switchToVideoBackToQuit() {
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsSupportFragmentSwitchToVideoInOnCreate.class,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsSupportFragmentSwitchToVideoInOnCreate detailsFragment =
+                (DetailsSupportFragmentSwitchToVideoInOnCreate) activity.getTestFragment();
+
+        // the pending enter transition flag should be automatically cleared
+        assertEquals(StateMachine.STATUS_INVOKED,
+                detailsFragment.STATE_ENTER_TRANSITION_COMPLETE.getStatus());
+        assertNull(TransitionHelper.getEnterTransition(activity.getWindow()));
+        assertEquals(0, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
+        assertTrue(detailsFragment.getRowsSupportFragment().getView().hasFocus());
+        assertFalse(detailsFragment.isShowingTitle());
+
+        SystemClock.sleep(1000);
+        assertNull(detailsFragment.mVideoSupportFragment);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        final MediaPlayerGlue glue = new MediaPlayerGlue(activity);
+                        detailsFragment.mDetailsBackgroundController.setupVideoPlayback(glue);
+                        glue.setMode(MediaPlayerGlue.REPEAT_ALL);
+                        glue.setArtist("A Googleer");
+                        glue.setTitle("Diving with Sharks");
+                        glue.setMediaSource(Uri.parse(
+                                "android.resource://android.support.v17.leanback.test/raw/video"));
+                    }
+                }
+        );
+        // once the video fragment is created it would be immediately assigned focus
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mVideoSupportFragment != null
+                        && detailsFragment.mVideoSupportFragment.getView() != null
+                        && detailsFragment.mVideoSupportFragment.getView().hasFocus();
+            }
+        });
+        // wait auto hide play controls done:
+        PollingCheck.waitFor(8000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return ((PlaybackSupportFragment) detailsFragment.mVideoSupportFragment).mBgAlpha == 0;
+            }
+        });
+
+        // before any details row is presented, pressing BACK will quit the activity
+        sendKeys(KeyEvent.KEYCODE_BACK);
+        PollingCheck.waitFor(4000, new PollingCheck.ActivityDestroy(activity));
+    }
+
+    public static class DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition
+            extends DetailsTestSupportFragment {
+
+        final DetailsSupportFragmentBackgroundController mDetailsBackground =
+                new DetailsSupportFragmentBackgroundController(this);
+
+        public DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+            mDetailsBackground.switchToVideo();
+            prepareEntranceTransition();
+        }
+
+        @Override
+        public void onViewCreated(View view, Bundle savedInstanceState) {
+            super.onViewCreated(view, savedInstanceState);
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void switchToVideoInOnCreateAndPrepareEntranceTransition() {
+        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(
+                DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition.class,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition detailsFragment =
+                (DetailsSupportFragmentSwitchToVideoAndPrepareEntranceTransition)
+                        activity.getTestFragment();
+
+        assertEquals(StateMachine.STATUS_INVOKED,
+                detailsFragment.STATE_ENTRANCE_COMPLETE.getStatus());
+    }
+
+    public static class DetailsSupportFragmentEntranceTransition
+            extends DetailsTestSupportFragment {
+
+        final DetailsSupportFragmentBackgroundController mDetailsBackground =
+                new DetailsSupportFragmentBackgroundController(this);
+
+        public DetailsSupportFragmentEntranceTransition() {
+            mTimeToLoadOverviewRow = mTimeToLoadRelatedRow = 100;
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mDetailsBackground.enableParallax();
+            prepareEntranceTransition();
+        }
+
+        @Override
+        public void onStart() {
+            super.onStart();
+            Bitmap bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
+                    android.support.v17.leanback.test.R.drawable.spiderman);
+            mDetailsBackground.setCoverBitmap(bitmap);
+        }
+
+        @Override
+        public void onStop() {
+            mDetailsBackground.setCoverBitmap(null);
+            super.onStop();
+        }
+    }
+
+    @Test
+    public void entranceTransitionBlocksSwitchToVideo() {
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(DetailsSupportFragmentEntranceTransition.class,
+                new Options().uiVisibility(
+                        View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN), 0);
+        final DetailsSupportFragmentEntranceTransition detailsFragment =
+                (DetailsSupportFragmentEntranceTransition)
+                        activity.getTestFragment();
+
+        if (Build.VERSION.SDK_INT < 21) {
+            // when enter transition is not supported, mCanUseHost is immmediately true
+            assertTrue(detailsFragment.mDetailsBackgroundController.mCanUseHost);
+        } else {
+            // calling switchToVideo() between prepareEntranceTransition and entrance transition
+            // finishes will be ignored.
+            InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                    detailsFragment.mDetailsBackgroundController.switchToVideo();
+                }
+            });
+            assertFalse(detailsFragment.mDetailsBackgroundController.mCanUseHost);
+        }
+        assertEquals(255, getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController));
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.setItem(new PhotoItem("Hello world", "Fake content goes here",
+                        android.support.v17.leanback.test.R.drawable.spiderman));
+                detailsFragment.startEntranceTransition();
+            }
+        });
+        // once Entrance transition is finished, mCanUseHost will be true
+        // and we can switchToVideo and fade out the background.
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return detailsFragment.mDetailsBackgroundController.mCanUseHost;
+            }
+        });
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                detailsFragment.mDetailsBackgroundController.switchToVideo();
+            }
+        });
+        PollingCheck.waitFor(4000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 0 == getCoverDrawableAlpha(detailsFragment.mDetailsBackgroundController);
+            }
+        });
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/HeadersFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/HeadersFragmentTest.java
index 7b64e0b..9dd8a49 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/HeadersFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/HeadersFragmentTest.java
@@ -59,9 +59,9 @@
 
     @Test
     public void defaultScale() {
-        launchAndWaitActivity(F_defaultScale.class, 1000);
+        SingleFragmentTestActivity activity = launchAndWaitActivity(F_defaultScale.class, 1000);
 
-        final VerticalGridView gridView = ((HeadersFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((HeadersFragment) activity.getTestFragment())
                 .getVerticalGridView();
         ItemBridgeAdapter.ViewHolder vh = (ItemBridgeAdapter.ViewHolder)
                 gridView.findViewHolderForAdapterPosition(0);
@@ -87,9 +87,9 @@
 
     @Test
     public void disableScale() {
-        launchAndWaitActivity(F_disableScale.class, 1000);
+        SingleFragmentTestActivity activity = launchAndWaitActivity(F_disableScale.class, 1000);
 
-        final VerticalGridView gridView = ((HeadersFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((HeadersFragment) activity.getTestFragment())
                 .getVerticalGridView();
         ItemBridgeAdapter.ViewHolder vh = (ItemBridgeAdapter.ViewHolder)
                 gridView.findViewHolderForAdapterPosition(0);
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/HeadersSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/HeadersSupportFragmentTest.java
index f545572..b8f7cc8 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/HeadersSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/HeadersSupportFragmentTest.java
@@ -62,9 +62,9 @@
 
     @Test
     public void defaultScale() {
-        launchAndWaitActivity(F_defaultScale.class, 1000);
+        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(F_defaultScale.class, 1000);
 
-        final VerticalGridView gridView = ((HeadersSupportFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((HeadersSupportFragment) activity.getTestFragment())
                 .getVerticalGridView();
         ItemBridgeAdapter.ViewHolder vh = (ItemBridgeAdapter.ViewHolder)
                 gridView.findViewHolderForAdapterPosition(0);
@@ -90,9 +90,9 @@
 
     @Test
     public void disableScale() {
-        launchAndWaitActivity(F_disableScale.class, 1000);
+        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(F_disableScale.class, 1000);
 
-        final VerticalGridView gridView = ((HeadersSupportFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((HeadersSupportFragment) activity.getTestFragment())
                 .getVerticalGridView();
         ItemBridgeAdapter.ViewHolder vh = (ItemBridgeAdapter.ViewHolder)
                 gridView.findViewHolderForAdapterPosition(0);
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
index 326d2be..70c8795 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlGlueTest.java
@@ -597,9 +597,53 @@
         playbackGlue.createControlsRowAndPresenter();
         // after a controls row is created, onRowChanged() call back is called once
         assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
+        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
         playbackGlue.notifyMetaDataChanged();
         // onMetaDataChanged() calls updateRowMetadata which ends up calling
         // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
         assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
+        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
     }
+
+
+    @Test
+    public void testWithoutValidMedia() throws Exception {
+        final PlaybackOverlayFragment[] fragmentResult = new
+                PlaybackOverlayFragment[1];
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                fragmentResult[0] = new PlaybackOverlayFragment();
+            }
+        });
+        final boolean[] hasValidMedia = new boolean[] {false};
+        PlaybackOverlayFragment fragment = fragmentResult[0];
+        PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
+                new int[]{
+                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
+                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1,
+                        PlaybackControlGlue.PLAYBACK_SPEED_FAST_L2
+                }) {
+            @Override
+            public boolean hasValidMedia() {
+                return hasValidMedia[0];
+            }
+        };
+
+        // before any controls row is created the count is zero
+        assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
+        playbackGlue.createControlsRowAndPresenter();
+        // after a controls row is created, onRowChanged() call back is called once
+        assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
+        // enven hasValidMedia() is false, we should still have three buttons.
+        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
+
+        hasValidMedia[0] = true;
+        playbackGlue.notifyMetaDataChanged();
+        // onMetaDataChanged() calls updateRowMetadata which ends up calling
+        // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
+        assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
+        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
index 944c1f7..37f5754 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackControlSupportGlueTest.java
@@ -600,9 +600,53 @@
         playbackGlue.createControlsRowAndPresenter();
         // after a controls row is created, onRowChanged() call back is called once
         assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
+        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
         playbackGlue.notifyMetaDataChanged();
         // onMetaDataChanged() calls updateRowMetadata which ends up calling
         // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
         assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
+        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
     }
+
+
+    @Test
+    public void testWithoutValidMedia() throws Exception {
+        final PlaybackOverlaySupportFragment[] fragmentResult = new
+                PlaybackOverlaySupportFragment[1];
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                fragmentResult[0] = new PlaybackOverlaySupportFragment();
+            }
+        });
+        final boolean[] hasValidMedia = new boolean[] {false};
+        PlaybackOverlaySupportFragment fragment = fragmentResult[0];
+        PlayControlGlueImpl playbackGlue = new PlayControlGlueImpl(context, fragment,
+                new int[]{
+                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L0,
+                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L1,
+                        PlaybackControlSupportGlue.PLAYBACK_SPEED_FAST_L2
+                }) {
+            @Override
+            public boolean hasValidMedia() {
+                return hasValidMedia[0];
+            }
+        };
+
+        // before any controls row is created the count is zero
+        assertEquals(playbackGlue.getOnRowChangedCallCount(), 0);
+        playbackGlue.createControlsRowAndPresenter();
+        // after a controls row is created, onRowChanged() call back is called once
+        assertEquals(playbackGlue.getOnRowChangedCallCount(), 1);
+        // enven hasValidMedia() is false, we should still have three buttons.
+        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
+
+        hasValidMedia[0] = true;
+        playbackGlue.notifyMetaDataChanged();
+        // onMetaDataChanged() calls updateRowMetadata which ends up calling
+        // notifyPlaybackRowChanged on the old host and finally onRowChanged on the glue.
+        assertEquals(playbackGlue.getOnRowChangedCallCount(), 2);
+        assertEquals(3, playbackGlue.getControlsRow().getPrimaryActionsAdapter().size());
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackFragmentTest.java
index 2fcf3ed..7824e63 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackFragmentTest.java
@@ -15,6 +15,8 @@
  */
 package android.support.v17.leanback.app;
 
+import static junit.framework.Assert.assertEquals;
+
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
@@ -22,20 +24,25 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.media.PlaybackControlGlue;
 import android.support.v17.leanback.media.PlaybackGlue;
 import android.support.v17.leanback.testutils.PollingCheck;
+import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.OnItemViewClickedListener;
 import android.support.v17.leanback.widget.OnItemViewSelectedListener;
 import android.support.v17.leanback.widget.PlaybackControlsRow;
+import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
 import android.support.v17.leanback.widget.Presenter;
 import android.support.v17.leanback.widget.Row;
 import android.support.v17.leanback.widget.RowPresenter;
 import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
 import android.view.KeyEvent;
+import android.view.View;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -51,18 +58,19 @@
 
     @Test
     public void testDetachCalledWhenDestroyFragment() throws Throwable {
-        launchAndWaitActivity(PlaybackTestFragment.class, 1000);
-        PlaybackTestFragment fragment = (PlaybackTestFragment) mActivity.getTestFragment();
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackTestFragment.class, 1000);
+        final PlaybackTestFragment fragment = (PlaybackTestFragment) activity.getTestFragment();
         PlaybackGlue glue = fragment.getGlue();
         activityTestRule.runOnUiThread(new Runnable() {
             public void run() {
-                mActivity.finish();
+                activity.finish();
             }
         });
         PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
-                return mActivity.isDestroyed();
+                return fragment.mDestroyCalled;
             }
         });
         assertNull(glue.getHost());
@@ -70,8 +78,9 @@
 
     @Test
     public void testSelectedListener() throws Throwable {
-        launchAndWaitActivity(PlaybackTestFragment.class, 1000);
-        PlaybackTestFragment fragment = (PlaybackTestFragment) mActivity.getTestFragment();
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackTestFragment.class, 1000);
+        PlaybackTestFragment fragment = (PlaybackTestFragment) activity.getTestFragment();
 
         assertTrue(fragment.getView().hasFocus());
 
@@ -105,7 +114,6 @@
         verify(selectedListener, times(0)).onItemSelected(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(selectedListener, times(1)).onItemSelected(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -113,7 +121,6 @@
         assertSame("The selected action should be rewind", rewind, itemCaptor.getValue());
 
         sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(selectedListener, times(2)).onItemSelected(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -124,7 +131,7 @@
         ListRow listRow0 = (ListRow) fragment.getAdapter().get(1);
 
         sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
-        Thread.sleep(TRANSITION_LENGTH);
+        waitForScrollIdle(fragment.getVerticalGridView());
         verify(selectedListener, times(3)).onItemSelected(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same list row should be passed to the listener", listRow0,
@@ -139,8 +146,9 @@
 
     @Test
     public void testClickedListener() throws Throwable {
-        launchAndWaitActivity(PlaybackTestFragment.class, 1000);
-        PlaybackTestFragment fragment = (PlaybackTestFragment) mActivity.getTestFragment();
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackTestFragment.class, 1000);
+        PlaybackTestFragment fragment = (PlaybackTestFragment) activity.getTestFragment();
 
         assertTrue(fragment.getView().hasFocus());
 
@@ -173,7 +181,6 @@
         verify(clickedListener, times(0)).onItemClicked(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(1)).onItemClicked(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -181,11 +188,9 @@
         assertSame("The clicked action should be playPause", playPause, itemCaptor.getValue());
 
         sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(1)).onItemClicked(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(2)).onItemClicked(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -193,11 +198,9 @@
         assertSame("The clicked action should be rewind", rewind, itemCaptor.getValue());
 
         sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(2)).onItemClicked(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(3)).onItemClicked(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -208,11 +211,10 @@
         ListRow listRow0 = (ListRow) fragment.getAdapter().get(1);
 
         sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
-        Thread.sleep(TRANSITION_LENGTH);
+        waitForScrollIdle(fragment.getVerticalGridView());
         verify(clickedListener, times(3)).onItemClicked(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(4)).onItemClicked(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same list row should be passed to the listener", listRow0,
@@ -223,4 +225,142 @@
                 listRowItemPassed);
     }
 
+    @Test
+    public void alignmentRowToBottom() throws Throwable {
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackTestFragment.class, 1000);
+        final PlaybackTestFragment fragment = (PlaybackTestFragment) activity.getTestFragment();
+
+        assertTrue(fragment.getAdapter().size() > 2);
+
+        View playRow = fragment.getVerticalGridView().getChildAt(0);
+        assertTrue(playRow.hasFocus());
+        assertEquals(playRow.getResources().getDimensionPixelSize(
+                android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+
+        activityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                fragment.getVerticalGridView().setSelectedPositionSmooth(
+                        fragment.getAdapter().size() - 1);
+            }
+        });
+        waitForScrollIdle(fragment.getVerticalGridView());
+
+        View lastRow = fragment.getVerticalGridView().getChildAt(
+                fragment.getVerticalGridView().getChildCount() - 1);
+        assertEquals(fragment.getAdapter().size() - 1,
+                fragment.getVerticalGridView().getChildAdapterPosition(lastRow));
+        assertTrue(lastRow.hasFocus());
+        assertEquals(lastRow.getResources().getDimensionPixelSize(
+                android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - lastRow.getBottom());
+    }
+
+    public static class PurePlaybackFragment extends PlaybackFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setFadingEnabled(false);
+            PlaybackControlsRow row = new PlaybackControlsRow();
+            SparseArrayObjectAdapter primaryAdapter = new SparseArrayObjectAdapter(
+                    new ControlButtonPresenterSelector());
+            primaryAdapter.set(0, new PlaybackControlsRow.SkipPreviousAction(getActivity()));
+            primaryAdapter.set(1, new PlaybackControlsRow.PlayPauseAction(getActivity()));
+            primaryAdapter.set(2, new PlaybackControlsRow.SkipNextAction(getActivity()));
+            row.setPrimaryActionsAdapter(primaryAdapter);
+            row.setSecondaryActionsAdapter(null);
+            setPlaybackRow(row);
+            setPlaybackRowPresenter(new PlaybackControlsRowPresenter());
+        }
+    }
+
+    @Test
+    public void setupRowAndPresenterWithoutGlue() {
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(PurePlaybackFragment.class, 1000);
+        final PurePlaybackFragment fragment = (PurePlaybackFragment)
+                activity.getTestFragment();
+
+        assertTrue(fragment.getAdapter().size() == 1);
+        View playRow = fragment.getVerticalGridView().getChildAt(0);
+        assertTrue(playRow.hasFocus());
+        assertEquals(playRow.getResources().getDimensionPixelSize(
+                android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+    }
+
+    public static class ControlGlueFragment extends PlaybackFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            int[] ffspeeds = new int[] {PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
+                    PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1};
+            PlaybackGlue glue = new PlaybackControlGlue(
+                    getActivity(), ffspeeds) {
+                @Override
+                public boolean hasValidMedia() {
+                    return true;
+                }
+
+                @Override
+                public boolean isMediaPlaying() {
+                    return false;
+                }
+
+                @Override
+                public CharSequence getMediaTitle() {
+                    return "Title";
+                }
+
+                @Override
+                public CharSequence getMediaSubtitle() {
+                    return "SubTitle";
+                }
+
+                @Override
+                public int getMediaDuration() {
+                    return 100;
+                }
+
+                @Override
+                public Drawable getMediaArt() {
+                    return null;
+                }
+
+                @Override
+                public long getSupportedActions() {
+                    return PlaybackControlGlue.ACTION_PLAY_PAUSE;
+                }
+
+                @Override
+                public int getCurrentSpeedId() {
+                    return PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
+                }
+
+                @Override
+                public int getCurrentPosition() {
+                    return 50;
+                }
+            };
+            glue.setHost(new PlaybackFragmentGlueHost(this));
+        }
+    }
+
+    @Test
+    public void setupWithControlGlue() throws Throwable {
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(ControlGlueFragment.class, 1000);
+        final ControlGlueFragment fragment = (ControlGlueFragment)
+                activity.getTestFragment();
+
+        assertTrue(fragment.getAdapter().size() == 1);
+
+        View playRow = fragment.getVerticalGridView().getChildAt(0);
+        assertTrue(playRow.hasFocus());
+        assertEquals(playRow.getResources().getDimensionPixelSize(
+                android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+    }
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
index dfc3458..dca53de 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayFragmentTest.java
@@ -15,12 +15,15 @@
  */
 package android.support.v17.leanback.app;
 
+import static junit.framework.Assert.assertEquals;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.test.R;
+import android.view.View;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -31,13 +34,49 @@
 
     @Test
     public void workaroundVideoViewStealFocus() {
-        launchAndWaitActivity(PlaybackOverlayTestFragment.class,
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackOverlayTestFragment.class,
                 new Options().activityLayoutId(R.layout.playback_controls_with_video), 0);
         PlaybackOverlayTestFragment fragment = (PlaybackOverlayTestFragment)
-                mActivity.getTestFragment();
+                activity.getTestFragment();
 
-        assertFalse(mActivity.findViewById(R.id.videoView).hasFocus());
+        assertFalse(activity.findViewById(R.id.videoView).hasFocus());
         assertTrue(fragment.getView().hasFocus());
     }
 
+    @Test
+    public void alignmentRowToBottom() throws Throwable {
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackOverlayTestFragment.class,
+                new Options().activityLayoutId(R.layout.playback_controls_with_video), 0);
+        final PlaybackOverlayTestFragment fragment = (PlaybackOverlayTestFragment)
+                activity.getTestFragment();
+
+        assertTrue(fragment.getAdapter().size() > 2);
+
+        View playRow = fragment.getVerticalGridView().getChildAt(0);
+        assertTrue(playRow.hasFocus());
+        assertEquals(playRow.getResources().getDimensionPixelSize(
+                R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+
+        activityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                fragment.getVerticalGridView().setSelectedPositionSmooth(
+                        fragment.getAdapter().size() - 1);
+            }
+        });
+        waitForScrollIdle(fragment.getVerticalGridView());
+
+        View lastRow = fragment.getVerticalGridView().getChildAt(
+                fragment.getVerticalGridView().getChildCount() - 1);
+        assertEquals(fragment.getAdapter().size() - 1,
+                fragment.getVerticalGridView().getChildAdapterPosition(lastRow));
+        assertTrue(lastRow.hasFocus());
+        assertEquals(lastRow.getResources().getDimensionPixelSize(
+                R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - lastRow.getBottom());
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
index e5dbe08..4fdea79 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackOverlayTestFragment.java
@@ -22,6 +22,7 @@
 import android.support.v17.leanback.test.R;
 import android.support.v17.leanback.widget.Action;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
 import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
 import android.support.v17.leanback.widget.HeaderItem;
 import android.support.v17.leanback.widget.ListRow;
@@ -62,7 +63,6 @@
 
     private PlaybackControlHelper mGlue;
     private PlaybackControlsRowPresenter mPlaybackControlsRowPresenter;
-    private ListRowPresenter mListRowPresenter;
 
     private OnItemViewClickedListener mOnItemViewClickedListener = new OnItemViewClickedListener() {
         @Override
@@ -135,19 +135,11 @@
 
         mPlaybackControlsRowPresenter = mGlue.createControlsRowAndPresenter();
         mPlaybackControlsRowPresenter.setSecondaryActionsHidden(SECONDARY_HIDDEN);
-        mListRowPresenter = new ListRowPresenter();
+        ClassPresenterSelector selector = new ClassPresenterSelector();
+        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
+        selector.addClassPresenter(PlaybackControlsRow.class, mPlaybackControlsRowPresenter);
 
-        setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
-            @Override
-            public Presenter getPresenter(Object object) {
-                if (object instanceof PlaybackControlsRow) {
-                    return mPlaybackControlsRowPresenter;
-                } else if (object instanceof ListRow) {
-                    return mListRowPresenter;
-                }
-                throw new IllegalArgumentException("Unhandled object: " + object);
-            }
-        }));
+        setAdapter(new SparseArrayObjectAdapter(selector));
 
         // Add the controls row
         getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackSupportFragmentTest.java
index d33e3ef..7b8fb8e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackSupportFragmentTest.java
@@ -18,6 +18,8 @@
  */
 package android.support.v17.leanback.app;
 
+import static junit.framework.Assert.assertEquals;
+
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
@@ -25,20 +27,25 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
 import android.support.test.filters.MediumTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.support.v17.leanback.media.PlaybackControlGlue;
 import android.support.v17.leanback.media.PlaybackGlue;
 import android.support.v17.leanback.testutils.PollingCheck;
+import android.support.v17.leanback.widget.ControlButtonPresenterSelector;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.OnItemViewClickedListener;
 import android.support.v17.leanback.widget.OnItemViewSelectedListener;
 import android.support.v17.leanback.widget.PlaybackControlsRow;
+import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
 import android.support.v17.leanback.widget.Presenter;
 import android.support.v17.leanback.widget.Row;
 import android.support.v17.leanback.widget.RowPresenter;
 import android.support.v17.leanback.widget.SparseArrayObjectAdapter;
 import android.view.KeyEvent;
+import android.view.View;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -54,18 +61,19 @@
 
     @Test
     public void testDetachCalledWhenDestroyFragment() throws Throwable {
-        launchAndWaitActivity(PlaybackTestSupportFragment.class, 1000);
-        PlaybackTestSupportFragment fragment = (PlaybackTestSupportFragment) mActivity.getTestFragment();
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackTestSupportFragment.class, 1000);
+        final PlaybackTestSupportFragment fragment = (PlaybackTestSupportFragment) activity.getTestFragment();
         PlaybackGlue glue = fragment.getGlue();
         activityTestRule.runOnUiThread(new Runnable() {
             public void run() {
-                mActivity.finish();
+                activity.finish();
             }
         });
         PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
-                return mActivity.isDestroyed();
+                return fragment.mDestroyCalled;
             }
         });
         assertNull(glue.getHost());
@@ -73,8 +81,9 @@
 
     @Test
     public void testSelectedListener() throws Throwable {
-        launchAndWaitActivity(PlaybackTestSupportFragment.class, 1000);
-        PlaybackTestSupportFragment fragment = (PlaybackTestSupportFragment) mActivity.getTestFragment();
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackTestSupportFragment.class, 1000);
+        PlaybackTestSupportFragment fragment = (PlaybackTestSupportFragment) activity.getTestFragment();
 
         assertTrue(fragment.getView().hasFocus());
 
@@ -108,7 +117,6 @@
         verify(selectedListener, times(0)).onItemSelected(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(selectedListener, times(1)).onItemSelected(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -116,7 +124,6 @@
         assertSame("The selected action should be rewind", rewind, itemCaptor.getValue());
 
         sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(selectedListener, times(2)).onItemSelected(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -127,7 +134,7 @@
         ListRow listRow0 = (ListRow) fragment.getAdapter().get(1);
 
         sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
-        Thread.sleep(TRANSITION_LENGTH);
+        waitForScrollIdle(fragment.getVerticalGridView());
         verify(selectedListener, times(3)).onItemSelected(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same list row should be passed to the listener", listRow0,
@@ -142,8 +149,9 @@
 
     @Test
     public void testClickedListener() throws Throwable {
-        launchAndWaitActivity(PlaybackTestSupportFragment.class, 1000);
-        PlaybackTestSupportFragment fragment = (PlaybackTestSupportFragment) mActivity.getTestFragment();
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackTestSupportFragment.class, 1000);
+        PlaybackTestSupportFragment fragment = (PlaybackTestSupportFragment) activity.getTestFragment();
 
         assertTrue(fragment.getView().hasFocus());
 
@@ -176,7 +184,6 @@
         verify(clickedListener, times(0)).onItemClicked(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(1)).onItemClicked(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -184,11 +191,9 @@
         assertSame("The clicked action should be playPause", playPause, itemCaptor.getValue());
 
         sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(1)).onItemClicked(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(2)).onItemClicked(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -196,11 +201,9 @@
         assertSame("The clicked action should be rewind", rewind, itemCaptor.getValue());
 
         sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(2)).onItemClicked(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(3)).onItemClicked(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same controls row should be passed to the listener", controlsRow,
@@ -211,11 +214,10 @@
         ListRow listRow0 = (ListRow) fragment.getAdapter().get(1);
 
         sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
-        Thread.sleep(TRANSITION_LENGTH);
+        waitForScrollIdle(fragment.getVerticalGridView());
         verify(clickedListener, times(3)).onItemClicked(any(Presenter.ViewHolder.class),
                 any(Object.class), any(RowPresenter.ViewHolder.class), any(Row.class));
         sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
-        Thread.sleep(TRANSITION_LENGTH);
         verify(clickedListener, times(4)).onItemClicked(itemVHCaptor.capture(),
                 itemCaptor.capture(), rowVHCaptor.capture(), rowCaptor.capture());
         assertSame("Same list row should be passed to the listener", listRow0,
@@ -226,4 +228,142 @@
                 listRowItemPassed);
     }
 
+    @Test
+    public void alignmentRowToBottom() throws Throwable {
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(PlaybackTestSupportFragment.class, 1000);
+        final PlaybackTestSupportFragment fragment = (PlaybackTestSupportFragment) activity.getTestFragment();
+
+        assertTrue(fragment.getAdapter().size() > 2);
+
+        View playRow = fragment.getVerticalGridView().getChildAt(0);
+        assertTrue(playRow.hasFocus());
+        assertEquals(playRow.getResources().getDimensionPixelSize(
+                android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+
+        activityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                fragment.getVerticalGridView().setSelectedPositionSmooth(
+                        fragment.getAdapter().size() - 1);
+            }
+        });
+        waitForScrollIdle(fragment.getVerticalGridView());
+
+        View lastRow = fragment.getVerticalGridView().getChildAt(
+                fragment.getVerticalGridView().getChildCount() - 1);
+        assertEquals(fragment.getAdapter().size() - 1,
+                fragment.getVerticalGridView().getChildAdapterPosition(lastRow));
+        assertTrue(lastRow.hasFocus());
+        assertEquals(lastRow.getResources().getDimensionPixelSize(
+                android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - lastRow.getBottom());
+    }
+
+    public static class PurePlaybackSupportFragment extends PlaybackSupportFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setFadingEnabled(false);
+            PlaybackControlsRow row = new PlaybackControlsRow();
+            SparseArrayObjectAdapter primaryAdapter = new SparseArrayObjectAdapter(
+                    new ControlButtonPresenterSelector());
+            primaryAdapter.set(0, new PlaybackControlsRow.SkipPreviousAction(getActivity()));
+            primaryAdapter.set(1, new PlaybackControlsRow.PlayPauseAction(getActivity()));
+            primaryAdapter.set(2, new PlaybackControlsRow.SkipNextAction(getActivity()));
+            row.setPrimaryActionsAdapter(primaryAdapter);
+            row.setSecondaryActionsAdapter(null);
+            setPlaybackRow(row);
+            setPlaybackRowPresenter(new PlaybackControlsRowPresenter());
+        }
+    }
+
+    @Test
+    public void setupRowAndPresenterWithoutGlue() {
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(PurePlaybackSupportFragment.class, 1000);
+        final PurePlaybackSupportFragment fragment = (PurePlaybackSupportFragment)
+                activity.getTestFragment();
+
+        assertTrue(fragment.getAdapter().size() == 1);
+        View playRow = fragment.getVerticalGridView().getChildAt(0);
+        assertTrue(playRow.hasFocus());
+        assertEquals(playRow.getResources().getDimensionPixelSize(
+                android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+    }
+
+    public static class ControlGlueFragment extends PlaybackSupportFragment {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            int[] ffspeeds = new int[] {PlaybackControlGlue.PLAYBACK_SPEED_FAST_L0,
+                    PlaybackControlGlue.PLAYBACK_SPEED_FAST_L1};
+            PlaybackGlue glue = new PlaybackControlGlue(
+                    getActivity(), ffspeeds) {
+                @Override
+                public boolean hasValidMedia() {
+                    return true;
+                }
+
+                @Override
+                public boolean isMediaPlaying() {
+                    return false;
+                }
+
+                @Override
+                public CharSequence getMediaTitle() {
+                    return "Title";
+                }
+
+                @Override
+                public CharSequence getMediaSubtitle() {
+                    return "SubTitle";
+                }
+
+                @Override
+                public int getMediaDuration() {
+                    return 100;
+                }
+
+                @Override
+                public Drawable getMediaArt() {
+                    return null;
+                }
+
+                @Override
+                public long getSupportedActions() {
+                    return PlaybackControlGlue.ACTION_PLAY_PAUSE;
+                }
+
+                @Override
+                public int getCurrentSpeedId() {
+                    return PlaybackControlGlue.PLAYBACK_SPEED_PAUSED;
+                }
+
+                @Override
+                public int getCurrentPosition() {
+                    return 50;
+                }
+            };
+            glue.setHost(new PlaybackSupportFragmentGlueHost(this));
+        }
+    }
+
+    @Test
+    public void setupWithControlGlue() throws Throwable {
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(ControlGlueFragment.class, 1000);
+        final ControlGlueFragment fragment = (ControlGlueFragment)
+                activity.getTestFragment();
+
+        assertTrue(fragment.getAdapter().size() == 1);
+
+        View playRow = fragment.getVerticalGridView().getChildAt(0);
+        assertTrue(playRow.hasFocus());
+        assertEquals(playRow.getResources().getDimensionPixelSize(
+                android.support.v17.leanback.test.R.dimen.lb_playback_controls_padding_bottom),
+                fragment.getVerticalGridView().getHeight() - playRow.getBottom());
+    }
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestFragment.java
index f9fd33f..2ca92da 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestFragment.java
@@ -23,6 +23,7 @@
 import android.support.v17.leanback.test.R;
 import android.support.v17.leanback.widget.Action;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
 import android.support.v17.leanback.widget.HeaderItem;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.ListRowPresenter;
@@ -46,8 +47,6 @@
      */
     private static final int BACKGROUND_TYPE = PlaybackFragment.BG_LIGHT;
 
-    private static final int ROW_CONTROLS = 0;
-
     /**
      * Change this to select hidden
      */
@@ -59,7 +58,7 @@
     private static final int RELATED_CONTENT_ROWS = 3;
 
     private android.support.v17.leanback.media.PlaybackControlGlue mGlue;
-    private ListRowPresenter mListRowPresenter;
+    boolean mDestroyCalled;
 
     public SparseArrayObjectAdapter getAdapter() {
         return (SparseArrayObjectAdapter) super.getAdapter();
@@ -74,6 +73,12 @@
     };
 
     @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mDestroyCalled = true;
+    }
+
+    @Override
     public void onCreate(Bundle savedInstanceState) {
         Log.i(TAG, "onCreate");
         super.onCreate(savedInstanceState);
@@ -112,23 +117,10 @@
         };
 
         mGlue.setHost(new PlaybackFragmentGlueHost(this));
-       //  mGlue.setOnI
-        mListRowPresenter = new ListRowPresenter();
+        ClassPresenterSelector selector = new ClassPresenterSelector();
+        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
 
-        setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
-            @Override
-            public Presenter getPresenter(Object object) {
-                if (object instanceof PlaybackControlsRow) {
-                    return mGlue.getControlsRowPresenter();
-                } else if (object instanceof ListRow) {
-                    return mListRowPresenter;
-                }
-                throw new IllegalArgumentException("Unhandled object: " + object);
-            }
-        }));
-
-        // Add the controls row
-        getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+        setAdapter(new SparseArrayObjectAdapter(selector));
 
         // Add related content rows
         for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
@@ -136,7 +128,7 @@
             listRowAdapter.add("Some related content");
             listRowAdapter.add("Other related content");
             HeaderItem header = new HeaderItem(i, "Row " + i);
-            getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
+            getAdapter().set(1 + i, new ListRow(header, listRowAdapter));
         }
     }
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestSupportFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestSupportFragment.java
index 0973fe1..1655b76 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestSupportFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/PlaybackTestSupportFragment.java
@@ -26,6 +26,7 @@
 import android.support.v17.leanback.test.R;
 import android.support.v17.leanback.widget.Action;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.ClassPresenterSelector;
 import android.support.v17.leanback.widget.HeaderItem;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.ListRowPresenter;
@@ -49,8 +50,6 @@
      */
     private static final int BACKGROUND_TYPE = PlaybackSupportFragment.BG_LIGHT;
 
-    private static final int ROW_CONTROLS = 0;
-
     /**
      * Change this to select hidden
      */
@@ -62,7 +61,7 @@
     private static final int RELATED_CONTENT_ROWS = 3;
 
     private android.support.v17.leanback.media.PlaybackControlGlue mGlue;
-    private ListRowPresenter mListRowPresenter;
+    boolean mDestroyCalled;
 
     public SparseArrayObjectAdapter getAdapter() {
         return (SparseArrayObjectAdapter) super.getAdapter();
@@ -77,6 +76,12 @@
     };
 
     @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mDestroyCalled = true;
+    }
+
+    @Override
     public void onCreate(Bundle savedInstanceState) {
         Log.i(TAG, "onCreate");
         super.onCreate(savedInstanceState);
@@ -115,23 +120,10 @@
         };
 
         mGlue.setHost(new PlaybackSupportFragmentGlueHost(this));
-       //  mGlue.setOnI
-        mListRowPresenter = new ListRowPresenter();
+        ClassPresenterSelector selector = new ClassPresenterSelector();
+        selector.addClassPresenter(ListRow.class, new ListRowPresenter());
 
-        setAdapter(new SparseArrayObjectAdapter(new PresenterSelector() {
-            @Override
-            public Presenter getPresenter(Object object) {
-                if (object instanceof PlaybackControlsRow) {
-                    return mGlue.getControlsRowPresenter();
-                } else if (object instanceof ListRow) {
-                    return mListRowPresenter;
-                }
-                throw new IllegalArgumentException("Unhandled object: " + object);
-            }
-        }));
-
-        // Add the controls row
-        getAdapter().set(ROW_CONTROLS, mGlue.getControlsRow());
+        setAdapter(new SparseArrayObjectAdapter(selector));
 
         // Add related content rows
         for (int i = 0; i < RELATED_CONTENT_ROWS; ++i) {
@@ -139,7 +131,7 @@
             listRowAdapter.add("Some related content");
             listRowAdapter.add("Other related content");
             HeaderItem header = new HeaderItem(i, "Row " + i);
-            getAdapter().set(ROW_CONTROLS + 1 + i, new ListRow(header, listRowAdapter));
+            getAdapter().set(1 + i, new ListRow(header, listRowAdapter));
         }
     }
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/RowsFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/RowsFragmentTest.java
index 193203e..a9bece0 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/RowsFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/RowsFragmentTest.java
@@ -17,6 +17,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.Rect;
@@ -29,8 +30,13 @@
 import android.support.v17.leanback.testutils.PollingCheck;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
 import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ItemBridgeAdapter;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.RowPresenter;
 import android.support.v17.leanback.widget.VerticalGridView;
 import android.view.KeyEvent;
 import android.view.View;
@@ -78,11 +84,11 @@
 
     @Test
     public void defaultAlignment() throws InterruptedException {
-        launchAndWaitActivity(F_defaultAlignment.class, 1000);
+        SingleFragmentTestActivity activity = launchAndWaitActivity(F_defaultAlignment.class, 1000);
 
         final Rect rect = new Rect();
 
-        final VerticalGridView gridView = ((RowsFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((RowsFragment) activity.getTestFragment())
                 .getVerticalGridView();
         View row0 = gridView.findViewHolderForAdapterPosition(0).itemView;
         rect.set(0, 0, row0.getWidth(), row0.getHeight());
@@ -123,9 +129,10 @@
 
     @Test
     public void selectBeforeSetAdapter() throws InterruptedException {
-        launchAndWaitActivity(F_selectBeforeSetAdapter.class, 2000);
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(F_selectBeforeSetAdapter.class, 2000);
 
-        final VerticalGridView gridView = ((RowsFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((RowsFragment) activity.getTestFragment())
                 .getVerticalGridView();
         assertEquals(7, gridView.getSelectedPosition());
         assertNotNull(gridView.findViewHolderForAdapterPosition(7));
@@ -156,9 +163,10 @@
 
     @Test
     public void selectBeforeAddData() throws InterruptedException {
-        launchAndWaitActivity(F_selectBeforeAddData.class, 2000);
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(F_selectBeforeAddData.class, 2000);
 
-        final VerticalGridView gridView = ((RowsFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((RowsFragment) activity.getTestFragment())
                 .getVerticalGridView();
         assertEquals(7, gridView.getSelectedPosition());
         assertNotNull(gridView.findViewHolderForAdapterPosition(7));
@@ -183,9 +191,10 @@
 
     @Test
     public void selectAfterAddData() throws InterruptedException {
-        launchAndWaitActivity(F_selectAfterAddData.class, 2000);
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(F_selectAfterAddData.class, 2000);
 
-        final VerticalGridView gridView = ((RowsFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((RowsFragment) activity.getTestFragment())
                 .getVerticalGridView();
         assertEquals(7, gridView.getSelectedPosition());
         assertNotNull(gridView.findViewHolderForAdapterPosition(7));
@@ -213,12 +222,13 @@
 
     @Test
     public void restoreSelection() {
-        launchAndWaitActivity(F_restoreSelection.class, 1000);
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(F_restoreSelection.class, 1000);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
                 new Runnable() {
                     public void run() {
-                        mActivity.recreate();
+                        activity.recreate();
                     }
                 }
         );
@@ -232,4 +242,58 @@
         assertNotNull(gridView.findViewHolderForAdapterPosition(7));
 
     }
+
+    public static class F_ListRowWithOnClick extends RowsFragment {
+        Presenter.ViewHolder mLastClickedItemViewHolder;
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setOnItemViewClickedListener(new OnItemViewClickedListener() {
+                @Override
+                public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+                        RowPresenter.ViewHolder rowViewHolder, Row row) {
+                    mLastClickedItemViewHolder = itemViewHolder;
+                }
+            });
+            ListRowPresenter lrp = new ListRowPresenter();
+            ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
+            setAdapter(adapter);
+            loadData(adapter, 10, 1);
+        }
+    }
+
+    @Test
+    public void prefetchChildItemsBeforeAttach() throws Throwable {
+        SingleFragmentTestActivity activity =
+                launchAndWaitActivity(F_ListRowWithOnClick.class, 1000);
+
+        F_ListRowWithOnClick fragment = (F_ListRowWithOnClick) activity.getTestFragment();
+        final VerticalGridView gridView = fragment.getVerticalGridView();
+        View lastRow = gridView.getChildAt(gridView.getChildCount() - 1);
+        final int lastRowPos = gridView.getChildAdapterPosition(lastRow);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    public void run() {
+                        gridView.setSelectedPositionSmooth(lastRowPos);
+                    }
+                }
+        );
+        waitForScrollIdle(gridView);
+        ItemBridgeAdapter.ViewHolder prefetchedBridgeVh = (ItemBridgeAdapter.ViewHolder)
+                gridView.findViewHolderForAdapterPosition(lastRowPos + 1);
+        RowPresenter prefetchedRowPresenter = (RowPresenter) prefetchedBridgeVh.getPresenter();
+        final ListRowPresenter.ViewHolder prefetchedListRowVh = (ListRowPresenter.ViewHolder)
+                prefetchedRowPresenter.getRowViewHolder(prefetchedBridgeVh.getViewHolder());
+
+        fragment.mLastClickedItemViewHolder = null;
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    public void run() {
+                        prefetchedListRowVh.getItemViewHolder(0).view.performClick();
+                    }
+                }
+        );
+        assertSame(prefetchedListRowVh.getItemViewHolder(0), fragment.mLastClickedItemViewHolder);
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/RowsSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/RowsSupportFragmentTest.java
index 70ddbac..a33c92e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/RowsSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/RowsSupportFragmentTest.java
@@ -20,6 +20,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import android.graphics.Rect;
@@ -32,8 +33,13 @@
 import android.support.v17.leanback.testutils.PollingCheck;
 import android.support.v17.leanback.widget.ArrayObjectAdapter;
 import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ItemBridgeAdapter;
 import android.support.v17.leanback.widget.ListRow;
 import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.RowPresenter;
 import android.support.v17.leanback.widget.VerticalGridView;
 import android.view.KeyEvent;
 import android.view.View;
@@ -81,11 +87,11 @@
 
     @Test
     public void defaultAlignment() throws InterruptedException {
-        launchAndWaitActivity(F_defaultAlignment.class, 1000);
+        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(F_defaultAlignment.class, 1000);
 
         final Rect rect = new Rect();
 
-        final VerticalGridView gridView = ((RowsSupportFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((RowsSupportFragment) activity.getTestFragment())
                 .getVerticalGridView();
         View row0 = gridView.findViewHolderForAdapterPosition(0).itemView;
         rect.set(0, 0, row0.getWidth(), row0.getHeight());
@@ -126,9 +132,10 @@
 
     @Test
     public void selectBeforeSetAdapter() throws InterruptedException {
-        launchAndWaitActivity(F_selectBeforeSetAdapter.class, 2000);
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(F_selectBeforeSetAdapter.class, 2000);
 
-        final VerticalGridView gridView = ((RowsSupportFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((RowsSupportFragment) activity.getTestFragment())
                 .getVerticalGridView();
         assertEquals(7, gridView.getSelectedPosition());
         assertNotNull(gridView.findViewHolderForAdapterPosition(7));
@@ -159,9 +166,10 @@
 
     @Test
     public void selectBeforeAddData() throws InterruptedException {
-        launchAndWaitActivity(F_selectBeforeAddData.class, 2000);
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(F_selectBeforeAddData.class, 2000);
 
-        final VerticalGridView gridView = ((RowsSupportFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((RowsSupportFragment) activity.getTestFragment())
                 .getVerticalGridView();
         assertEquals(7, gridView.getSelectedPosition());
         assertNotNull(gridView.findViewHolderForAdapterPosition(7));
@@ -186,9 +194,10 @@
 
     @Test
     public void selectAfterAddData() throws InterruptedException {
-        launchAndWaitActivity(F_selectAfterAddData.class, 2000);
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(F_selectAfterAddData.class, 2000);
 
-        final VerticalGridView gridView = ((RowsSupportFragment) mActivity.getTestFragment())
+        final VerticalGridView gridView = ((RowsSupportFragment) activity.getTestFragment())
                 .getVerticalGridView();
         assertEquals(7, gridView.getSelectedPosition());
         assertNotNull(gridView.findViewHolderForAdapterPosition(7));
@@ -216,12 +225,13 @@
 
     @Test
     public void restoreSelection() {
-        launchAndWaitActivity(F_restoreSelection.class, 1000);
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(F_restoreSelection.class, 1000);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(
                 new Runnable() {
                     public void run() {
-                        mActivity.recreate();
+                        activity.recreate();
                     }
                 }
         );
@@ -235,4 +245,58 @@
         assertNotNull(gridView.findViewHolderForAdapterPosition(7));
 
     }
+
+    public static class F_ListRowWithOnClick extends RowsSupportFragment {
+        Presenter.ViewHolder mLastClickedItemViewHolder;
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            setOnItemViewClickedListener(new OnItemViewClickedListener() {
+                @Override
+                public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
+                        RowPresenter.ViewHolder rowViewHolder, Row row) {
+                    mLastClickedItemViewHolder = itemViewHolder;
+                }
+            });
+            ListRowPresenter lrp = new ListRowPresenter();
+            ArrayObjectAdapter adapter = new ArrayObjectAdapter(lrp);
+            setAdapter(adapter);
+            loadData(adapter, 10, 1);
+        }
+    }
+
+    @Test
+    public void prefetchChildItemsBeforeAttach() throws Throwable {
+        SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(F_ListRowWithOnClick.class, 1000);
+
+        F_ListRowWithOnClick fragment = (F_ListRowWithOnClick) activity.getTestFragment();
+        final VerticalGridView gridView = fragment.getVerticalGridView();
+        View lastRow = gridView.getChildAt(gridView.getChildCount() - 1);
+        final int lastRowPos = gridView.getChildAdapterPosition(lastRow);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    public void run() {
+                        gridView.setSelectedPositionSmooth(lastRowPos);
+                    }
+                }
+        );
+        waitForScrollIdle(gridView);
+        ItemBridgeAdapter.ViewHolder prefetchedBridgeVh = (ItemBridgeAdapter.ViewHolder)
+                gridView.findViewHolderForAdapterPosition(lastRowPos + 1);
+        RowPresenter prefetchedRowPresenter = (RowPresenter) prefetchedBridgeVh.getPresenter();
+        final ListRowPresenter.ViewHolder prefetchedListRowVh = (ListRowPresenter.ViewHolder)
+                prefetchedRowPresenter.getRowViewHolder(prefetchedBridgeVh.getViewHolder());
+
+        fragment.mLastClickedItemViewHolder = null;
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    public void run() {
+                        prefetchedListRowVh.getItemViewHolder(0).view.performClick();
+                    }
+                }
+        );
+        assertSame(prefetchedListRowVh.getItemViewHolder(0), fragment.mLastClickedItemViewHolder);
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestActivity.java b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestActivity.java
index d17811b..6047a1e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestActivity.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestActivity.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v17.leanback.test.R;
+import android.util.Log;
 
 public class SingleFragmentTestActivity extends Activity {
 
@@ -32,10 +33,12 @@
     public static final String EXTRA_ACTIVITY_LAYOUT = "activityLayout";
 
     public static final String EXTRA_UI_VISIBILITY = "uiVisibility";
+    private static final String TAG = "TestActivity";
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        Log.d(TAG, "onCreate " + this);
         Intent intent = getIntent();
 
         final int uiOptions = intent.getIntExtra(EXTRA_UI_VISIBILITY, 0);
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestBase.java b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestBase.java
index fd1f922..b26d92d 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestBase.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleFragmentTestBase.java
@@ -19,13 +19,15 @@
 import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
+import android.support.v7.widget.RecyclerView;
 
-import org.junit.After;
 import org.junit.Rule;
 import org.junit.rules.TestName;
 
 public class SingleFragmentTestBase {
 
+    private static final long WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS = 60000;
+
     @Rule
     public TestName mUnitTestName = new TestName();
 
@@ -33,20 +35,6 @@
     public ActivityTestRule<SingleFragmentTestActivity> activityTestRule =
             new ActivityTestRule<>(SingleFragmentTestActivity.class, false, false);
 
-    protected SingleFragmentTestActivity mActivity;
-
-    @After
-    public void afterTest() throws Throwable {
-        activityTestRule.runOnUiThread(new Runnable() {
-            public void run() {
-                if (mActivity != null) {
-                    mActivity.finish();
-                    mActivity = null;
-                }
-            }
-        });
-    }
-
     public void sendKeys(int ...keys) {
         for (int i = 0; i < keys.length; i++) {
             InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(keys[i]);
@@ -84,21 +72,48 @@
         }
     }
 
-    public void launchAndWaitActivity(Class fragmentClass, long waitTimeMs) {
-        launchAndWaitActivity(fragmentClass.getName(), null, waitTimeMs);
+    public SingleFragmentTestActivity launchAndWaitActivity(Class fragmentClass, long waitTimeMs) {
+        return launchAndWaitActivity(fragmentClass.getName(), null, waitTimeMs);
     }
 
-    public void launchAndWaitActivity(Class fragmentClass, Options options, long waitTimeMs) {
-        launchAndWaitActivity(fragmentClass.getName(), options, waitTimeMs);
+    public SingleFragmentTestActivity launchAndWaitActivity(Class fragmentClass, Options options,
+            long waitTimeMs) {
+        return launchAndWaitActivity(fragmentClass.getName(), options, waitTimeMs);
     }
 
-    public void launchAndWaitActivity(String firstFragmentName, Options options, long waitTimeMs) {
+    public SingleFragmentTestActivity launchAndWaitActivity(String firstFragmentName,
+            Options options, long waitTimeMs) {
         Intent intent = new Intent();
         intent.putExtra(SingleFragmentTestActivity.EXTRA_FRAGMENT_NAME, firstFragmentName);
         if (options != null) {
             options.collect(intent);
         }
-        mActivity = activityTestRule.launchActivity(intent);
+        SingleFragmentTestActivity activity = activityTestRule.launchActivity(intent);
         SystemClock.sleep(waitTimeMs);
+        return activity;
     }
+
+    protected void waitForScrollIdle(RecyclerView recyclerView) throws Throwable {
+        waitForScrollIdle(recyclerView, null);
+    }
+
+    protected void waitForScrollIdle(RecyclerView recyclerView, Runnable verify) throws Throwable {
+        Thread.sleep(100);
+        int total = 0;
+        while (recyclerView.getLayoutManager().isSmoothScrolling()
+                || recyclerView.getScrollState() != recyclerView.SCROLL_STATE_IDLE) {
+            if ((total += 100) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
+                throw new RuntimeException("waitForScrollIdle Timeout");
+            }
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException ex) {
+                break;
+            }
+            if (verify != null) {
+                activityTestRule.runOnUiThread(verify);
+            }
+        }
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestActivity.java b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestActivity.java
index 911a32e..0fc3183 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestActivity.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestActivity.java
@@ -24,6 +24,7 @@
 import android.content.Intent;
 import android.os.Bundle;
 import android.support.v17.leanback.test.R;
+import android.util.Log;
 
 public class SingleSupportFragmentTestActivity extends FragmentActivity {
 
@@ -35,10 +36,12 @@
     public static final String EXTRA_ACTIVITY_LAYOUT = "activityLayout";
 
     public static final String EXTRA_UI_VISIBILITY = "uiVisibility";
+    private static final String TAG = "TestActivity";
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        Log.d(TAG, "onCreate " + this);
         Intent intent = getIntent();
 
         final int uiOptions = intent.getIntExtra(EXTRA_UI_VISIBILITY, 0);
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestBase.java b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestBase.java
index a7cb793..6c00923 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestBase.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/SingleSupportFragmentTestBase.java
@@ -22,13 +22,15 @@
 import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
+import android.support.v7.widget.RecyclerView;
 
-import org.junit.After;
 import org.junit.Rule;
 import org.junit.rules.TestName;
 
 public class SingleSupportFragmentTestBase {
 
+    private static final long WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS = 60000;
+
     @Rule
     public TestName mUnitTestName = new TestName();
 
@@ -36,20 +38,6 @@
     public ActivityTestRule<SingleSupportFragmentTestActivity> activityTestRule =
             new ActivityTestRule<>(SingleSupportFragmentTestActivity.class, false, false);
 
-    protected SingleSupportFragmentTestActivity mActivity;
-
-    @After
-    public void afterTest() throws Throwable {
-        activityTestRule.runOnUiThread(new Runnable() {
-            public void run() {
-                if (mActivity != null) {
-                    mActivity.finish();
-                    mActivity = null;
-                }
-            }
-        });
-    }
-
     public void sendKeys(int ...keys) {
         for (int i = 0; i < keys.length; i++) {
             InstrumentationRegistry.getInstrumentation().sendKeyDownUpSync(keys[i]);
@@ -87,21 +75,48 @@
         }
     }
 
-    public void launchAndWaitActivity(Class fragmentClass, long waitTimeMs) {
-        launchAndWaitActivity(fragmentClass.getName(), null, waitTimeMs);
+    public SingleSupportFragmentTestActivity launchAndWaitActivity(Class fragmentClass, long waitTimeMs) {
+        return launchAndWaitActivity(fragmentClass.getName(), null, waitTimeMs);
     }
 
-    public void launchAndWaitActivity(Class fragmentClass, Options options, long waitTimeMs) {
-        launchAndWaitActivity(fragmentClass.getName(), options, waitTimeMs);
+    public SingleSupportFragmentTestActivity launchAndWaitActivity(Class fragmentClass, Options options,
+            long waitTimeMs) {
+        return launchAndWaitActivity(fragmentClass.getName(), options, waitTimeMs);
     }
 
-    public void launchAndWaitActivity(String firstFragmentName, Options options, long waitTimeMs) {
+    public SingleSupportFragmentTestActivity launchAndWaitActivity(String firstFragmentName,
+            Options options, long waitTimeMs) {
         Intent intent = new Intent();
         intent.putExtra(SingleSupportFragmentTestActivity.EXTRA_FRAGMENT_NAME, firstFragmentName);
         if (options != null) {
             options.collect(intent);
         }
-        mActivity = activityTestRule.launchActivity(intent);
+        SingleSupportFragmentTestActivity activity = activityTestRule.launchActivity(intent);
         SystemClock.sleep(waitTimeMs);
+        return activity;
     }
+
+    protected void waitForScrollIdle(RecyclerView recyclerView) throws Throwable {
+        waitForScrollIdle(recyclerView, null);
+    }
+
+    protected void waitForScrollIdle(RecyclerView recyclerView, Runnable verify) throws Throwable {
+        Thread.sleep(100);
+        int total = 0;
+        while (recyclerView.getLayoutManager().isSmoothScrolling()
+                || recyclerView.getScrollState() != recyclerView.SCROLL_STATE_IDLE) {
+            if ((total += 100) >= WAIT_FOR_SCROLL_IDLE_TIMEOUT_MS) {
+                throw new RuntimeException("waitForScrollIdle Timeout");
+            }
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException ex) {
+                break;
+            }
+            if (verify != null) {
+                activityTestRule.runOnUiThread(verify);
+            }
+        }
+    }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/VerticalGridFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/VerticalGridFragmentTest.java
index 5c4f4fd..6e49b65 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/VerticalGridFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/VerticalGridFragmentTest.java
@@ -47,21 +47,21 @@
 
     @Test
     public void immediateRemoveFragment() throws Throwable {
-        launchAndWaitActivity(GridFragment.class, 500);
+        final SingleFragmentTestActivity activity = launchAndWaitActivity(GridFragment.class, 500);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             public void run() {
                 GridFragment f = new GridFragment();
-                mActivity.getFragmentManager().beginTransaction()
+                activity.getFragmentManager().beginTransaction()
                         .replace(android.R.id.content, f, null).commit();
                 f.startEntranceTransition();
-                mActivity.getFragmentManager().beginTransaction()
+                activity.getFragmentManager().beginTransaction()
                         .replace(android.R.id.content, new Fragment(), null).commit();
             }
         });
 
         Thread.sleep(1000);
-        mActivity.finish();
+        activity.finish();
     }
 
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/VerticalGridSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/VerticalGridSupportFragmentTest.java
index 8b58c33..e531528 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/VerticalGridSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/VerticalGridSupportFragmentTest.java
@@ -50,21 +50,21 @@
 
     @Test
     public void immediateRemoveFragment() throws Throwable {
-        launchAndWaitActivity(GridFragment.class, 500);
+        final SingleSupportFragmentTestActivity activity = launchAndWaitActivity(GridFragment.class, 500);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             public void run() {
                 GridFragment f = new GridFragment();
-                mActivity.getSupportFragmentManager().beginTransaction()
+                activity.getSupportFragmentManager().beginTransaction()
                         .replace(android.R.id.content, f, null).commit();
                 f.startEntranceTransition();
-                mActivity.getSupportFragmentManager().beginTransaction()
+                activity.getSupportFragmentManager().beginTransaction()
                         .replace(android.R.id.content, new Fragment(), null).commit();
             }
         });
 
         Thread.sleep(1000);
-        mActivity.finish();
+        activity.finish();
     }
 
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/VideoFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/VideoFragmentTest.java
index 5c8c89e..f15521a 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/VideoFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/VideoFragmentTest.java
@@ -75,16 +75,17 @@
 
     @Test
     public void setSurfaceViewCallbackBeforeCreate() {
-        launchAndWaitActivity(Fragment_setSurfaceViewCallbackBeforeCreate.class, 1000);
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(Fragment_setSurfaceViewCallbackBeforeCreate.class, 1000);
         Fragment_setSurfaceViewCallbackBeforeCreate fragment1 =
-                (Fragment_setSurfaceViewCallbackBeforeCreate) mActivity.getTestFragment();
+                (Fragment_setSurfaceViewCallbackBeforeCreate) activity.getTestFragment();
         assertNotNull(fragment1);
         assertTrue(fragment1.mSurfaceCreated);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                mActivity.getFragmentManager().beginTransaction()
+                activity.getFragmentManager().beginTransaction()
                         .replace(R.id.main_frame, new Fragment_setSurfaceViewCallbackBeforeCreate())
                         .commitAllowingStateLoss();
             }
@@ -94,7 +95,7 @@
         assertFalse(fragment1.mSurfaceCreated);
 
         Fragment_setSurfaceViewCallbackBeforeCreate fragment2 =
-                (Fragment_setSurfaceViewCallbackBeforeCreate) mActivity.getTestFragment();
+                (Fragment_setSurfaceViewCallbackBeforeCreate) activity.getTestFragment();
         assertNotNull(fragment2);
         assertTrue(fragment2.mSurfaceCreated);
         assertNotSame(fragment1, fragment2);
@@ -102,8 +103,8 @@
 
     @Test
     public void setSurfaceViewCallbackAfterCreate() {
-        launchAndWaitActivity(VideoFragment.class, 1000);
-        VideoFragment fragment = (VideoFragment) mActivity.getTestFragment();
+        SingleFragmentTestActivity activity = launchAndWaitActivity(VideoFragment.class, 1000);
+        VideoFragment fragment = (VideoFragment) activity.getTestFragment();
 
         assertNotNull(fragment);
 
@@ -194,9 +195,10 @@
 
     @Test
     public void mediaPlayerGlueInVideoFragment() {
-        launchAndWaitActivity(Fragment_withVideoPlayer.class, 1000);
+        final SingleFragmentTestActivity activity =
+                launchAndWaitActivity(Fragment_withVideoPlayer.class, 1000);
         final Fragment_withVideoPlayer fragment = (Fragment_withVideoPlayer)
-                mActivity.getTestFragment();
+                activity.getTestFragment();
 
         PollingCheck.waitFor(5000, new PollingCheck.PollingCheckCondition() {
             @Override
@@ -214,7 +216,7 @@
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                mActivity.recreate();
+                activity.recreate();
             }
         });
 
@@ -235,7 +237,7 @@
         assertEquals(0, fragment.mGlueDetachedFromHost);
         assertEquals(1, fragment.mGlueOnReadyForPlaybackCalled);
 
-        mActivity.finish();
+        activity.finish();
         PollingCheck.waitFor(5000, new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/VideoSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/VideoSupportFragmentTest.java
index dff3c0c..8bca7fc 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/VideoSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/VideoSupportFragmentTest.java
@@ -78,16 +78,17 @@
 
     @Test
     public void setSurfaceViewCallbackBeforeCreate() {
-        launchAndWaitActivity(Fragment_setSurfaceViewCallbackBeforeCreate.class, 1000);
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(Fragment_setSurfaceViewCallbackBeforeCreate.class, 1000);
         Fragment_setSurfaceViewCallbackBeforeCreate fragment1 =
-                (Fragment_setSurfaceViewCallbackBeforeCreate) mActivity.getTestFragment();
+                (Fragment_setSurfaceViewCallbackBeforeCreate) activity.getTestFragment();
         assertNotNull(fragment1);
         assertTrue(fragment1.mSurfaceCreated);
 
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                mActivity.getSupportFragmentManager().beginTransaction()
+                activity.getSupportFragmentManager().beginTransaction()
                         .replace(R.id.main_frame, new Fragment_setSurfaceViewCallbackBeforeCreate())
                         .commitAllowingStateLoss();
             }
@@ -97,7 +98,7 @@
         assertFalse(fragment1.mSurfaceCreated);
 
         Fragment_setSurfaceViewCallbackBeforeCreate fragment2 =
-                (Fragment_setSurfaceViewCallbackBeforeCreate) mActivity.getTestFragment();
+                (Fragment_setSurfaceViewCallbackBeforeCreate) activity.getTestFragment();
         assertNotNull(fragment2);
         assertTrue(fragment2.mSurfaceCreated);
         assertNotSame(fragment1, fragment2);
@@ -105,8 +106,8 @@
 
     @Test
     public void setSurfaceViewCallbackAfterCreate() {
-        launchAndWaitActivity(VideoSupportFragment.class, 1000);
-        VideoSupportFragment fragment = (VideoSupportFragment) mActivity.getTestFragment();
+        SingleSupportFragmentTestActivity activity = launchAndWaitActivity(VideoSupportFragment.class, 1000);
+        VideoSupportFragment fragment = (VideoSupportFragment) activity.getTestFragment();
 
         assertNotNull(fragment);
 
@@ -197,9 +198,10 @@
 
     @Test
     public void mediaPlayerGlueInVideoSupportFragment() {
-        launchAndWaitActivity(Fragment_withVideoPlayer.class, 1000);
+        final SingleSupportFragmentTestActivity activity =
+                launchAndWaitActivity(Fragment_withVideoPlayer.class, 1000);
         final Fragment_withVideoPlayer fragment = (Fragment_withVideoPlayer)
-                mActivity.getTestFragment();
+                activity.getTestFragment();
 
         PollingCheck.waitFor(5000, new PollingCheck.PollingCheckCondition() {
             @Override
@@ -217,7 +219,7 @@
         InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
-                mActivity.recreate();
+                activity.recreate();
             }
         });
 
@@ -238,7 +240,7 @@
         assertEquals(0, fragment.mGlueDetachedFromHost);
         assertEquals(1, fragment.mGlueOnReadyForPlaybackCalled);
 
-        mActivity.finish();
+        activity.finish();
         PollingCheck.waitFor(5000, new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/graphics/CompositeDrawableTest.java b/v17/leanback/tests/java/android/support/v17/leanback/graphics/CompositeDrawableTest.java
index 132013a..df2c94c 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/graphics/CompositeDrawableTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/graphics/CompositeDrawableTest.java
@@ -28,6 +28,7 @@
 import android.support.test.filters.SdkSuppress;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.support.v17.leanback.graphics.BoundsRule.ValueRule;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -68,7 +69,7 @@
 
         // inherit from parent
         parentDrawable.addChildDrawable(drawable);
-        parentDrawable.getChildAt(0).getBoundsRule().bottom = BoundsRule.inheritFromParent(
+        parentDrawable.getChildAt(0).getBoundsRule().bottom = ValueRule.inheritFromParent(
                 fraction);
         parentDrawable.updateBounds(bounds);
 
@@ -79,7 +80,7 @@
 
         // absolute value
         drawable.setBounds(bounds);
-        parentDrawable.getChildAt(0).getBoundsRule().bottom = BoundsRule.absoluteValue(200);
+        parentDrawable.getChildAt(0).getBoundsRule().bottom = ValueRule.absoluteValue(200);
         parentDrawable.updateBounds(bounds);
 
         adjustedBounds = drawable.getBounds();
@@ -89,7 +90,7 @@
 
         // inherit with offset
         parentDrawable.getChildAt(0).getBoundsRule().bottom =
-                BoundsRule.inheritFromParentWithOffset(fraction, 100);
+                ValueRule.inheritFromParentWithOffset(fraction, 100);
         parentDrawable.updateBounds(bounds);
 
         adjustedBounds = drawable.getBounds();
@@ -100,7 +101,7 @@
         // inherit from parent 2
         bounds = new Rect(100, 200, WIDTH, HEIGHT);
         parentDrawable.getChildAt(0).getBoundsRule().bottom =
-                BoundsRule.inheritFromParent(fraction);
+                ValueRule.inheritFromParent(fraction);
         parentDrawable.updateBounds(bounds);
 
         adjustedBounds = drawable.getBounds();
@@ -124,8 +125,8 @@
 
         // inherit from parent
         BoundsRule boundsRule = parentDrawable.getChildAt(0).getBoundsRule();
-        boundsRule.top = BoundsRule.absoluteValue(-200);
-        boundsRule.bottom = BoundsRule.inheritFromParent(fraction);
+        boundsRule.top = ValueRule.absoluteValue(-200);
+        boundsRule.bottom = ValueRule.inheritFromParent(fraction);
         parentDrawable.getChildAt(0).getBoundsRule().top.setAbsoluteValue(-100);
 
         parentDrawable.updateBounds(bounds);
@@ -133,21 +134,32 @@
         Rect adjustedBounds = drawable.getBounds();
         Rect expectedBounds = new Rect(bounds);
         expectedBounds.top = -100;
-        expectedBounds.bottom = bounds.top + (int) (HEIGHT * fraction);
+        expectedBounds.bottom = (int) (HEIGHT * fraction);
         assertEquals(expectedBounds, adjustedBounds);
 
         // inherit from parent with offset
-        boundsRule.bottom = BoundsRule.absoluteValue(HEIGHT);
+        boundsRule.bottom = ValueRule.inheritFromParentWithOffset(1f, -100);
 
         parentDrawable.updateBounds(bounds);
 
         adjustedBounds = drawable.getBounds();
         expectedBounds = new Rect(bounds);
         expectedBounds.top = -100;
-        expectedBounds.bottom = HEIGHT;
+        expectedBounds.bottom = HEIGHT - 100;
+        assertEquals(expectedBounds, adjustedBounds);
+
+        // using property would change type:
+        CompositeDrawable.ChildDrawable.BOTTOM_ABSOLUTE.set(parentDrawable.getChildAt(0), 0);
+        CompositeDrawable.ChildDrawable.BOTTOM_FRACTION.set(parentDrawable.getChildAt(0), 0.5f);
+        parentDrawable.updateBounds(bounds);
+        adjustedBounds = drawable.getBounds();
+        expectedBounds = new Rect(bounds);
+        expectedBounds.top = -100;
+        expectedBounds.bottom = (int) (0.5f * HEIGHT);
         assertEquals(expectedBounds, adjustedBounds);
     }
 
+
     @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     public void constantState() {
@@ -184,7 +196,7 @@
         FitWidthBitmapDrawable child = new FitWidthBitmapDrawable();
         parent.addChildDrawable(child);
         parent.getChildAt(0).getBoundsRule().bottom =
-                BoundsRule.inheritFromParentWithOffset(.5f, 100);
+                ValueRule.inheritFromParentWithOffset(.5f, 100);
 
         CompositeDrawable.ChildDrawable newChild = new CompositeDrawable.ChildDrawable(
                 parent.getChildAt(0),
@@ -201,7 +213,7 @@
         FitWidthBitmapDrawable child = new FitWidthBitmapDrawable();
         parent.addChildDrawable(child);
         parent.getChildAt(0).getBoundsRule().bottom =
-                BoundsRule.inheritFromParentWithOffset(.5f, 100);
+                ValueRule.inheritFromParentWithOffset(.5f, 100);
 
         CompositeDrawable newDrawable = (CompositeDrawable) parent.getConstantState().newDrawable();
 
@@ -215,4 +227,5 @@
         assertEquals(parent.getChildAt(0).getBoundsRule().bottom.getFraction(),
                 newChild.getBoundsRule().bottom.getFraction(), delta);
     }
+
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackControlGlueTest.java b/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackControlGlueTest.java
new file mode 100644
index 0000000..a041c53
--- /dev/null
+++ b/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackControlGlueTest.java
@@ -0,0 +1,190 @@
+/*
+ * 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.v17.leanback.media;
+
+import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.times;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.support.test.InstrumentationRegistry;
+import android.support.v17.leanback.widget.PlaybackControlsRow;
+import android.support.v17.leanback.widget.PlaybackControlsRowPresenter;
+import android.support.v17.leanback.widget.PlaybackRowPresenter;
+import android.support.v17.leanback.widget.RowPresenter;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+
+public class PlaybackControlGlueTest {
+
+    public static class PlaybackControlGlueImpl extends PlaybackControlGlue {
+
+        public PlaybackControlGlueImpl(Context context) {
+            super(context, new int[] {PLAYBACK_SPEED_FAST_L0, PLAYBACK_SPEED_FAST_L1});
+        }
+
+        @Override
+        public boolean hasValidMedia() {
+            return true;
+        }
+
+        @Override
+        public boolean isMediaPlaying() {
+            return false;
+        }
+
+        @Override
+        public CharSequence getMediaTitle() {
+            return null;
+        }
+
+        @Override
+        public CharSequence getMediaSubtitle() {
+            return null;
+        }
+
+        @Override
+        public int getMediaDuration() {
+            return 0;
+        }
+
+        @Override
+        public Drawable getMediaArt() {
+            return null;
+        }
+
+        @Override
+        public long getSupportedActions() {
+            return 0;
+        }
+
+        @Override
+        public int getCurrentSpeedId() {
+            return 0;
+        }
+
+        @Override
+        public int getCurrentPosition() {
+            return 0;
+        }
+    }
+
+    Context mContext;
+    PlaybackControlGlue mGlue;
+
+    @Test
+    public void usingDefaultRowAndPresenter() {
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mGlue = Mockito.spy(new PlaybackControlGlueImpl(mContext));
+            }
+        });
+        PlaybackGlueHostImpl host = new PlaybackGlueHostImpl();
+
+        mGlue.setHost(host);
+        Mockito.verify(mGlue, times(1)).onAttachedToHost(host);
+        assertSame(mGlue, host.mGlue);
+        assertSame(host, mGlue.getHost());
+        assertTrue(host.mPlaybackRowPresenter instanceof PlaybackControlsRowPresenter);
+        assertTrue(host.mRow instanceof PlaybackControlsRow);
+
+    }
+    @Test
+    public void customRowPresenter() {
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mGlue = Mockito.spy(new PlaybackControlGlueImpl(mContext));
+            }
+        });
+        PlaybackRowPresenter presenter = new PlaybackRowPresenter() {
+            @Override
+            protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
+                return new RowPresenter.ViewHolder(new LinearLayout(parent.getContext()));
+            }
+        };
+        mGlue.setPlaybackRowPresenter(presenter);
+        PlaybackGlueHostImpl host = new PlaybackGlueHostImpl();
+
+        mGlue.setHost(host);
+        Mockito.verify(mGlue, times(1)).onAttachedToHost(host);
+        assertSame(mGlue, host.mGlue);
+        assertSame(host, mGlue.getHost());
+        assertSame(host.mPlaybackRowPresenter, presenter);
+        assertTrue(host.mRow instanceof PlaybackControlsRow);
+
+    }
+
+    @Test
+    public void customControlsRow() {
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mGlue = Mockito.spy(new PlaybackControlGlueImpl(mContext));
+            }
+        });
+        PlaybackControlsRow row = new PlaybackControlsRow(mContext);
+        mGlue.setControlsRow(row);
+        PlaybackGlueHostImpl host = new PlaybackGlueHostImpl();
+
+        mGlue.setHost(host);
+        Mockito.verify(mGlue, times(1)).onAttachedToHost(host);
+        assertSame(mGlue, host.mGlue);
+        assertSame(host, mGlue.getHost());
+        assertTrue(host.mPlaybackRowPresenter instanceof PlaybackControlsRowPresenter);
+        assertSame(host.mRow, row);
+
+    }
+
+    @Test
+    public void customRowAndPresenter() {
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mGlue = Mockito.spy(new PlaybackControlGlueImpl(mContext));
+            }
+        });
+        PlaybackControlsRow row = new PlaybackControlsRow(mContext);
+        mGlue.setControlsRow(row);
+        PlaybackRowPresenter presenter = new PlaybackRowPresenter() {
+            @Override
+            protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) {
+                return new RowPresenter.ViewHolder(new LinearLayout(parent.getContext()));
+            }
+        };
+        mGlue.setPlaybackRowPresenter(presenter);
+        PlaybackGlueHostImpl host = new PlaybackGlueHostImpl();
+
+        mGlue.setHost(host);
+        Mockito.verify(mGlue, times(1)).onAttachedToHost(host);
+        assertSame(mGlue, host.mGlue);
+        assertSame(host, mGlue.getHost());
+        assertSame(host.mPlaybackRowPresenter, presenter);
+        assertSame(host.mRow, row);
+
+    }
+}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackGlueHostImpl.java b/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackGlueHostImpl.java
index 199ab3e..2c9aa43 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackGlueHostImpl.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/media/PlaybackGlueHostImpl.java
@@ -15,12 +15,17 @@
  */
 package android.support.v17.leanback.media;
 
+import android.support.v17.leanback.widget.PlaybackRowPresenter;
+import android.support.v17.leanback.widget.Row;
+
 /**
  * Fake PlaybackGlueHost used by test.
  */
 public class PlaybackGlueHostImpl extends PlaybackGlueHost {
 
     HostCallback mHostCallback;
+    Row mRow;
+    PlaybackRowPresenter mPlaybackRowPresenter;
 
     @Override
     public void setHostCallback(HostCallback callback) {
@@ -56,4 +61,14 @@
             mHostCallback.onHostDestroy();
         }
     }
+
+    @Override
+    public void setPlaybackRow(Row row) {
+        mRow = row;
+    }
+
+    @Override
+    public void setPlaybackRowPresenter(PlaybackRowPresenter presenter) {
+        mPlaybackRowPresenter = presenter;
+    }
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ControlBarTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ControlBarTest.java
new file mode 100644
index 0000000..ea5b400
--- /dev/null
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ControlBarTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.v17.leanback.widget;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertSame;
+import static junit.framework.Assert.assertTrue;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+
+public class ControlBarTest {
+
+    @Test
+    public void defaultFocus() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        final ControlBar bar = new ControlBar(context, null);
+        final TextView v1 = new Button(context);
+        bar.addView(v1, 100, 100);
+        final TextView v2 = new Button(context);
+        bar.addView(v2, 100, 100);
+        final TextView v3 = new Button(context);
+        bar.addView(v3, 100, 100);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        bar.requestFocus(View.FOCUS_DOWN);
+                    }
+                }
+        );
+        assertTrue(v2.hasFocus());
+    }
+
+    @Test
+    public void persistFocus() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        final LinearLayout rootView = new LinearLayout(context);
+        final ControlBar bar = new ControlBar(context, null);
+        rootView.addView(bar, 800, 100);
+        final Button barSibling = new Button(context);
+        rootView.addView(barSibling, 100, 100);
+        final TextView v1 = new Button(context);
+        bar.addView(v1, 100, 100);
+        final TextView v2 = new Button(context);
+        bar.addView(v2, 100, 100);
+        final TextView v3 = new Button(context);
+        bar.addView(v3, 100, 100);
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        v3.requestFocus(View.FOCUS_DOWN);
+                    }
+                }
+        );
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        barSibling.requestFocus();
+                    }
+                }
+        );
+        assertFalse(bar.hasFocus());
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        bar.requestFocus(View.FOCUS_RIGHT);
+                    }
+                }
+        );
+        assertTrue(v3.hasFocus());
+    }
+
+    @Test
+    public void getFocusables() {
+        Context context = InstrumentationRegistry.getTargetContext();
+        final LinearLayout rootView = new LinearLayout(context);
+        final ControlBar bar = new ControlBar(context, null);
+        rootView.addView(bar, 800, 100);
+        final Button barSibling = new Button(context);
+        rootView.addView(barSibling, 100, 100);
+        final TextView v1 = new Button(context);
+        bar.addView(v1, 100, 100);
+        final TextView v2 = new Button(context);
+        bar.addView(v2, 100, 100);
+        final TextView v3 = new Button(context);
+        bar.addView(v3, 100, 100);
+
+        ArrayList<View> focusables = new ArrayList();
+        bar.addFocusables(focusables, View.FOCUS_DOWN);
+        assertEquals(1, focusables.size());
+        assertSame(focusables.get(0), v2);
+        focusables.clear();
+        bar.addFocusables(focusables, View.FOCUS_UP);
+        assertEquals(1, focusables.size());
+        assertSame(focusables.get(0), v2);
+        focusables.clear();
+        bar.addFocusables(focusables, View.FOCUS_LEFT);
+        assertEquals(3, focusables.size());
+        focusables.clear();
+        bar.addFocusables(focusables, View.FOCUS_RIGHT);
+        assertEquals(3, focusables.size());
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        v3.requestFocus(View.FOCUS_DOWN);
+                    }
+                }
+        );
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        barSibling.requestFocus();
+                    }
+                }
+        );
+        assertFalse(bar.hasFocus());
+        focusables.clear();
+        bar.addFocusables(focusables, View.FOCUS_DOWN);
+        assertEquals(1, focusables.size());
+        assertSame(focusables.get(0), v3);
+        focusables.clear();
+        bar.addFocusables(focusables, View.FOCUS_UP);
+        assertEquals(1, focusables.size());
+        assertSame(focusables.get(0), v3);
+        focusables.clear();
+        bar.addFocusables(focusables, View.FOCUS_LEFT);
+        assertEquals(3, focusables.size());
+        focusables.clear();
+        bar.addFocusables(focusables, View.FOCUS_RIGHT);
+        assertEquals(3, focusables.size());
+
+    }
+}
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridActivity.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridActivity.java
index 6678101..f6bdf68 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridActivity.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridActivity.java
@@ -50,6 +50,7 @@
     public static final String EXTRA_UPDATE_SIZE = "updateSize";
     public static final String EXTRA_LAYOUT_MARGINS = "layoutMargins";
     public static final String EXTRA_NINEPATCH_SHADOW = "NINEPATCH_SHADOW";
+    public static final String EXTRA_HAS_STABLE_IDS = "hasStableIds";
 
     /**
      * Class that implements GridWidgetTest.ViewTypeProvider for creating different
@@ -89,6 +90,7 @@
     GridWidgetTest.ItemAlignmentFacetProvider mAlignmentViewTypeProvider;
     AdapterListener mAdapterListener;
     boolean mUpdateSize = true;
+    boolean mHasStableIds;
 
     int[] mGridViewLayoutSize;
     BaseGridView mGridView;
@@ -133,6 +135,7 @@
         mUpdateSize = intent.getBooleanExtra(EXTRA_UPDATE_SIZE, true);
         mSecondarySizeZero = intent.getBooleanExtra(EXTRA_SECONDARY_SIZE_ZERO, false);
         mItemLengths = intent.getIntArrayExtra(EXTRA_ITEMS);
+        mHasStableIds = intent.getBooleanExtra(EXTRA_HAS_STABLE_IDS, false);
         mItemFocusables = intent.getBooleanArrayExtra(EXTRA_ITEMS_FOCUSABLE);
         mLayoutMargins = intent.getIntArrayExtra(EXTRA_LAYOUT_MARGINS);
         String alignmentClass = intent.getStringExtra(EXTRA_ITEMALIGNMENTPROVIDER_CLASS);
@@ -166,6 +169,7 @@
         if (DEBUG) Log.v(TAG, "onCreate " + this);
 
         RecyclerView.Adapter adapter = new MyAdapter();
+        adapter.setHasStableIds(mHasStableIds);
 
         View view = createView();
         if (mItemLengths == null) {
@@ -260,12 +264,16 @@
     }
 
     int[] removeItems(int index, int length) {
+        return removeItems(index, length, true);
+    }
+
+    int[] removeItems(int index, int length, boolean notify) {
         int[] removed = new int[length];
         System.arraycopy(mItemLengths, index, removed, 0, length);
         System.arraycopy(mItemLengths, index + length, mItemLengths, index,
                 mNumItems - index - length);
         mNumItems -= length;
-        if (mGridView.getAdapter() != null) {
+        if (mGridView.getAdapter() != null && notify) {
             mGridView.getAdapter().notifyItemRangeRemoved(index, length);
         }
         return removed;
@@ -278,6 +286,13 @@
     }
 
 
+    void changeItem(int position, int itemValue) {
+        mItemLengths[position] = itemValue;
+        if (mGridView.getAdapter() != null) {
+            mGridView.getAdapter().notifyItemChanged(position);
+        }
+    }
+
     void addItems(int index, int[] items) {
         int length = items.length;
         if (mItemLengths.length < mNumItems + length) {
@@ -430,6 +445,11 @@
             return mNumItems;
         }
 
+        @Override
+        public long getItemId(int position) {
+            if (!mHasStableIds) return -1;
+            return position;
+        }
     }
 
     void updateSize(View view, int position) {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetPrefetchTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetPrefetchTest.java
index 4b075ea..fcb264e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetPrefetchTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridWidgetPrefetchTest.java
@@ -248,11 +248,11 @@
         view.setAdapter(createBoxAdapter());
 
         // check default
-        assertEquals(4, view.getInitialItemPrefetchCount());
+        assertEquals(4, view.getInitialPrefetchItemCount());
 
         // check setter behavior
         view.setInitialPrefetchItemCount(0);
-        assertEquals(0, view.getInitialItemPrefetchCount());
+        assertEquals(0, view.getInitialPrefetchItemCount());
 
         // check positions fetched, relative to focus
         view.scrollToPosition(2);
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 7dab382..0195ef7 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
@@ -785,6 +785,73 @@
     }
 
     @Test
+    public void testAddLastItemHorizontal() throws Throwable {
+
+        Intent intent = new Intent();
+        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
+                R.layout.horizontal_linear);
+        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
+        initActivity(intent);
+        mOrientation = BaseGridView.HORIZONTAL;
+        mNumRows = 1;
+
+        mActivityTestRule.runOnUiThread(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        mGridView.setSelectedPositionSmooth(49);
+                    }
+                }
+        );
+        waitForScrollIdle(mVerifyLayout);
+        performAndWaitForAnimation(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.addItems(50, new int[]{150});
+            }
+        });
+
+        // assert new added item aligned to right edge
+        assertEquals(mGridView.getWidth() - mGridView.getPaddingRight(),
+                mGridView.getLayoutManager().findViewByPosition(50).getRight());
+    }
+
+    @Test
+    public void testAddMultipleLastItemsHorizontal() throws Throwable {
+
+        Intent intent = new Intent();
+        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
+                R.layout.horizontal_linear);
+        intent.putExtra(GridActivity.EXTRA_NUM_ITEMS, 50);
+        initActivity(intent);
+        mOrientation = BaseGridView.HORIZONTAL;
+        mNumRows = 1;
+
+        mActivityTestRule.runOnUiThread(
+                new Runnable() {
+                    @Override
+                    public void run() {
+                        mGridView.setWindowAlignment(BaseGridView.WINDOW_ALIGN_BOTH_EDGE);
+                        mGridView.setWindowAlignmentOffsetPercent(50);
+                        mGridView.setSelectedPositionSmooth(49);
+                    }
+                }
+        );
+        waitForScrollIdle(mVerifyLayout);
+        performAndWaitForAnimation(new Runnable() {
+            @Override
+            public void run() {
+                mActivity.addItems(50, new int[]{150, 150, 150, 150, 150, 150, 150, 150, 150,
+                        150, 150, 150, 150, 150});
+            }
+        });
+
+        // The focused item will be at center of window
+        View view = mGridView.getLayoutManager().findViewByPosition(49);
+        assertEquals(mGridView.getWidth() / 2, (view.getLeft() + view.getRight()) / 2);
+    }
+
+    @Test
     public void testItemAddRemoveHorizontal() throws Throwable {
 
         Intent intent = new Intent();
@@ -2988,8 +3055,28 @@
         assertTrue(selectedPosition2 < selectedPosition1);
     }
 
+    void slideInAndWaitIdle() throws Throwable {
+        slideInAndWaitIdle(5000);
+    }
+
+    void slideInAndWaitIdle(long timeout) throws Throwable {
+        // animateIn() would reset position
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                mGridView.animateIn();
+            }
+        });
+        PollingCheck.waitFor(timeout, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return !mGridView.getLayoutManager().isSmoothScrolling()
+                        && mGridView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE;
+            }
+        });
+    }
+
     @Test
-    public void testAnimateOutResetByScrollTo() throws Throwable {
+    public void testAnimateOutBlockScrollTo() throws Throwable {
         Intent intent = new Intent();
         intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
                 R.layout.vertical_linear_with_button_onleft);
@@ -3012,12 +3099,14 @@
                 mGridView.animateOut();
             }
         });
+        // wait until sliding out.
         PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() {
             @Override
             public boolean canProceed() {
                 return mGridView.getChildAt(0).getTop() > mGridView.getPaddingTop();
             }
         });
+        // scrollToPosition() should not affect slideOut status
         mActivityTestRule.runOnUiThread(new Runnable() {
             public void run() {
                 mGridView.scrollToPosition(0);
@@ -3029,13 +3118,180 @@
                 return mGridView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE;
             }
         });
+        assertTrue("First view slided Out", mGridView.getChildAt(0).getTop()
+                >= mGridView.getHeight());
 
+        slideInAndWaitIdle();
         assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
                 mGridView.getChildAt(0).getTop());
     }
 
     @Test
-    public void testAnimateOutResetByFocusChange() throws Throwable {
+    public void testAnimateOutBlockSmoothScrolling() throws Throwable {
+        Intent intent = new Intent();
+        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
+                R.layout.vertical_linear_with_button_onleft);
+        int[] items = new int[30];
+        for (int i = 0; i < items.length; i++) {
+            items[i] = 300;
+        }
+        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
+        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
+        mOrientation = BaseGridView.VERTICAL;
+        mNumRows = 1;
+
+        initActivity(intent);
+
+        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
+                mGridView.getChildAt(0).getTop());
+
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                mGridView.animateOut();
+            }
+        });
+        // wait until sliding out.
+        PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return mGridView.getChildAt(0).getTop() > mGridView.getPaddingTop();
+            }
+        });
+        // smoothScrollToPosition() should not affect slideOut status
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                mGridView.smoothScrollToPosition(29);
+            }
+        });
+        PollingCheck.waitFor(10000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return mGridView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE;
+            }
+        });
+        assertTrue("First view slided Out", mGridView.getChildAt(0).getTop()
+                >= mGridView.getHeight());
+
+        slideInAndWaitIdle();
+        View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+        assertSame("Scrolled to last child",
+                mGridView.findViewHolderForAdapterPosition(29).itemView, lastChild);
+    }
+
+    @Test
+    public void testAnimateOutBlockLongScrollTo() throws Throwable {
+        Intent intent = new Intent();
+        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
+                R.layout.vertical_linear_with_button_onleft);
+        int[] items = new int[30];
+        for (int i = 0; i < items.length; i++) {
+            items[i] = 300;
+        }
+        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
+        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
+        mOrientation = BaseGridView.VERTICAL;
+        mNumRows = 1;
+
+        initActivity(intent);
+
+        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
+                mGridView.getChildAt(0).getTop());
+
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                mGridView.animateOut();
+            }
+        });
+        // wait until sliding out.
+        PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return mGridView.getChildAt(0).getTop() > mGridView.getPaddingTop();
+            }
+        });
+        // smoothScrollToPosition() should not affect slideOut status
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                mGridView.scrollToPosition(29);
+            }
+        });
+        PollingCheck.waitFor(10000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return mGridView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE;
+            }
+        });
+        assertTrue("First view slided Out", mGridView.getChildAt(0).getTop()
+                >= mGridView.getHeight());
+
+        slideInAndWaitIdle();
+        View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+        assertSame("Scrolled to last child",
+                mGridView.findViewHolderForAdapterPosition(29).itemView, lastChild);
+    }
+
+    @Test
+    public void testAnimateOutBlockLayout() throws Throwable {
+        Intent intent = new Intent();
+        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
+                R.layout.vertical_linear_with_button_onleft);
+        int[] items = new int[100];
+        for (int i = 0; i < items.length; i++) {
+            items[i] = 300;
+        }
+        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
+        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
+        mOrientation = BaseGridView.VERTICAL;
+        mNumRows = 1;
+
+        initActivity(intent);
+
+        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
+                mGridView.getChildAt(0).getTop());
+
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                mGridView.animateOut();
+            }
+        });
+        // wait until sliding out.
+        PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return mGridView.getChildAt(0).getTop() > mGridView.getPaddingTop();
+            }
+        });
+        // change adapter should not affect slideOut status
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.changeItem(0, 200);
+            }
+        });
+        PollingCheck.waitFor(new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return mGridView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE;
+            }
+        });
+        assertTrue("First view slided Out", mGridView.getChildAt(0).getTop()
+                >= mGridView.getHeight());
+        assertEquals("onLayout suppressed during slide out", 300,
+                mGridView.getChildAt(0).getHeight());
+
+        slideInAndWaitIdle();
+        assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
+                mGridView.getChildAt(0).getTop());
+        // size of item should be updated immediately after slide in animation finishes:
+        PollingCheck.waitFor(1000, new PollingCheck.PollingCheckCondition() {
+            @Override
+            public boolean canProceed() {
+                return 200 == mGridView.getChildAt(0).getHeight();
+            }
+        });
+    }
+
+    @Test
+    public void testAnimateOutBlockFocusChange() throws Throwable {
         Intent intent = new Intent();
         intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
                 R.layout.vertical_linear_with_button_onleft);
@@ -3077,13 +3333,16 @@
                 return mGridView.getScrollState() == RecyclerView.SCROLL_STATE_IDLE;
             }
         });
+        assertTrue("First view slided Out", mGridView.getChildAt(0).getTop()
+                >= mGridView.getHeight());
 
+        slideInAndWaitIdle();
         assertEquals("First view is aligned with padding top", mGridView.getPaddingTop(),
                 mGridView.getChildAt(0).getTop());
     }
 
     @Test
-    public void testHorizontalAnimateOutResetByScrollTo() throws Throwable {
+    public void testHorizontalAnimateOutBlockScrollTo() throws Throwable {
         Intent intent = new Intent();
         intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
                 R.layout.horizontal_linear);
@@ -3124,8 +3383,13 @@
             }
         });
 
+        assertTrue("First view is slided out", mGridView.getChildAt(0).getLeft()
+                > mGridView.getWidth());
+
+        slideInAndWaitIdle();
         assertEquals("First view is aligned with padding left", mGridView.getPaddingLeft(),
                 mGridView.getChildAt(0).getLeft());
+
     }
 
     @Test
@@ -3172,9 +3436,87 @@
             }
         });
 
+        assertTrue("First view is slided out", mGridView.getChildAt(0).getRight() < 0);
+
+        slideInAndWaitIdle();
         assertEquals("First view is aligned with padding right",
                 mGridView.getWidth() - mGridView.getPaddingRight(),
                 mGridView.getChildAt(0).getRight());
     }
 
+    @Test
+    public void testSmoothScrollerOutRange() throws Throwable {
+        Intent intent = new Intent();
+        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID,
+                R.layout.vertical_linear_with_button_onleft);
+        intent.putExtra(GridActivity.EXTRA_REQUEST_FOCUS_ONLAYOUT, true);
+        int[] items = new int[30];
+        for (int i = 0; i < items.length; i++) {
+            items[i] = 680;
+        }
+        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
+        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
+        mOrientation = BaseGridView.VERTICAL;
+        mNumRows = 1;
+
+        initActivity(intent);
+
+        final View button = mActivity.findViewById(R.id.button);
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                button.requestFocus();
+            }
+        });
+
+        mGridView.setSelectedPositionSmooth(0);
+        waitForScrollIdle(mVerifyLayout);
+
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            public void run() {
+                mGridView.setSelectedPositionSmooth(120);
+            }
+        });
+        waitForScrollIdle(mVerifyLayout);
+        assertTrue(button.hasFocus());
+        int key;
+        if (mGridView.getLayoutDirection() == ViewGroup.LAYOUT_DIRECTION_RTL) {
+            key = KeyEvent.KEYCODE_DPAD_LEFT;
+        } else {
+            key = KeyEvent.KEYCODE_DPAD_RIGHT;
+        }
+        sendKey(key);
+        // the GridView should has focus in its children
+        assertTrue(mGridView.hasFocus());
+        assertFalse(mGridView.isFocused());
+        assertEquals(29, mGridView.getSelectedPosition());
+    }
+
+    @Test
+    public void testRemoveLastItemWithStableId() throws Throwable {
+        Intent intent = new Intent();
+        intent.putExtra(GridActivity.EXTRA_LAYOUT_RESOURCE_ID, R.layout.vertical_linear);
+        intent.putExtra(GridActivity.EXTRA_HAS_STABLE_IDS, true);
+        int[] items = new int[1];
+        for (int i = 0; i < items.length; i++) {
+            items[i] = 680;
+        }
+        intent.putExtra(GridActivity.EXTRA_ITEMS, items);
+        intent.putExtra(GridActivity.EXTRA_STAGGERED, false);
+        mOrientation = BaseGridView.VERTICAL;
+        mNumRows = 1;
+
+        initActivity(intent);
+
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mGridView.getItemAnimator().setRemoveDuration(2000);
+                mActivity.removeItems(0, 1, false);
+                mGridView.getAdapter().notifyDataSetChanged();
+            }
+        });
+        Thread.sleep(500);
+        assertEquals(-1, mGridView.getSelectedPosition());
+    }
 }
+
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatEffectTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatEffectTest.java
index 0c98e7d..6d49c0e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatEffectTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatEffectTest.java
@@ -19,11 +19,14 @@
 
 package android.support.v17.leanback.widget;
 
+import static junit.framework.Assert.assertEquals;
+
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.Property;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -36,15 +39,19 @@
 @SmallTest
 public class ParallaxFloatEffectTest {
 
-    Parallax.FloatParallax mSource;
+    Parallax<Parallax.FloatProperty> mSource;
     int mScreenMax;
     ParallaxEffect.FloatEffect mEffect;
     @Mock ParallaxTarget mTarget;
 
+    static void assertFloatEquals(float expected, float actual) {
+        org.junit.Assert.assertEquals((double) expected, (double) actual, 0.0001d);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mSource = new Parallax.FloatParallax<Parallax.FloatProperty>() {
+        mSource = new Parallax<Parallax.FloatProperty>() {
 
             public float getMaxValue() {
                 return mScreenMax;
@@ -67,55 +74,55 @@
         mEffect.target(mTarget);
 
         // start
-        var1.setFloatValue(mSource, 540);
+        var1.setValue(mSource, 540);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // 25% complete
-        var1.setFloatValue(mSource, 405);
+        var1.setValue(mSource, 405);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0.25f);
         Mockito.reset(mTarget);
 
         // middle
-        var1.setFloatValue(mSource, 270);
+        var1.setValue(mSource, 270);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(.5f);
         Mockito.reset(mTarget);
 
         // 75% complete
-        var1.setFloatValue(mSource, 135);
+        var1.setValue(mSource, 135);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0.75f);
         Mockito.reset(mTarget);
 
         // end
-        var1.setFloatValue(mSource, 0);
+        var1.setValue(mSource, 0);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // after end
-        var1.setFloatValue(mSource, -1000);
+        var1.setValue(mSource, -1000);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // before start
-        var1.setFloatValue(mSource, 1000);
+        var1.setValue(mSource, 1000);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // unknown_before
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_after
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
@@ -128,7 +135,7 @@
 
         mEffect.setPropertyRanges(var1.atAbsolute(540), var1.atAbsolute(550));
         mEffect.target(mTarget);
-        var1.setFloatValue(mSource, 0);
+        var1.setValue(mSource, 0);
         mEffect.performMapping(mSource);
     }
 
@@ -142,95 +149,137 @@
         mEffect.target(mTarget);
 
         // start
-        var1.setFloatValue(mSource, 540);
-        var2.setFloatValue(mSource, 840);
+        var1.setValue(mSource, 540);
+        var2.setValue(mSource, 840);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // middle
-        var1.setFloatValue(mSource, 390);
-        var2.setFloatValue(mSource, 690);
+        var1.setValue(mSource, 390);
+        var2.setValue(mSource, 690);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(.5f);
         Mockito.reset(mTarget);
 
         // end
-        var1.setFloatValue(mSource, 240);
-        var2.setFloatValue(mSource, 540);
+        var1.setValue(mSource, 240);
+        var2.setValue(mSource, 540);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // after end
-        var1.setFloatValue(mSource, 200);
-        var2.setFloatValue(mSource, 500);
+        var1.setValue(mSource, 200);
+        var2.setValue(mSource, 500);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // before start
-        var1.setFloatValue(mSource, 1000);
-        var2.setFloatValue(mSource, 1300);
+        var1.setValue(mSource, 1000);
+        var2.setValue(mSource, 1300);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // unknown_before
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
-        var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_before
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
-        var2.setFloatValue(mSource, -1000);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, -1000);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_after
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
-        var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+        var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // unknown_after
-        var1.setFloatValue(mSource, 1000);
-        var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, 1000);
+        var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // unknown_before and less
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
-        var2.setFloatValue(mSource, 500);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, 500);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_before and hit second
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
-        var2.setFloatValue(mSource, 540);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, 540);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_before with estimation
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
-        var2.setFloatValue(mSource, 1080);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, 1080);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0.5f);
         Mockito.reset(mTarget);
 
         // unknown_after with estimation
-        var1.setFloatValue(mSource, 0);
-        var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, 0);
+        var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0.5f);
         Mockito.reset(mTarget);
     }
 
+    @Test
+    public void testDirectMapping() {
+        mScreenMax = 1080;
+        Parallax.FloatProperty var1 = mSource.addProperty("var1");
+
+        mEffect.setPropertyRanges(var1.atAbsolute((float) 540.45), var1.atAbsolute((float) 0.22));
+        Object object = new Object();
+        final float[] properValue = new float[1];
+        Property<Object, Float> property = new Property<Object, Float>(Float.class, "attr") {
+            @Override
+            public void set(Object object, Float value) {
+                properValue[0] = value;
+            }
+
+            @Override
+            public Float get(Object o) {
+                return properValue[0];
+            }
+        };
+        mTarget = new ParallaxTarget.DirectPropertyTarget<>(object, property);
+        mEffect.target(mTarget);
+
+        var1.setValue(mSource, (float) 540.45);
+        mEffect.performMapping(mSource);
+        assertFloatEquals((float) 540.45, properValue[0]);
+
+        var1.setValue(mSource, (float) 405.85);
+        mEffect.performMapping(mSource);
+        assertFloatEquals((float) 405.85, properValue[0]);
+
+        var1.setValue(mSource, 2000);
+        mEffect.performMapping(mSource);
+        assertFloatEquals((float) 540.45, properValue[0]);
+
+        var1.setValue(mSource, (float) 0.22);
+        mEffect.performMapping(mSource);
+        assertFloatEquals((float) 0.22, properValue[0]);
+
+        var1.setValue(mSource, (float) 0.12);
+        mEffect.performMapping(mSource);
+        assertFloatEquals((float) 0.22, properValue[0]);
+    }
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatTest.java
index a2b00b9..a83cca2 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxFloatTest.java
@@ -32,7 +32,7 @@
 @SmallTest
 public class ParallaxFloatTest {
 
-    Parallax.FloatParallax mSource;
+    Parallax<Parallax.FloatProperty> mSource;
     int mScreenMax;
 
     static void assertFloatEquals(float expected, float actual) {
@@ -41,7 +41,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mSource = new Parallax.FloatParallax<Parallax.FloatProperty>() {
+        mSource = new Parallax<Parallax.FloatProperty>() {
 
             public float getMaxValue() {
                 return mScreenMax;
@@ -58,8 +58,8 @@
     public void testVariable() {
         mScreenMax = 1080;
         Parallax.FloatProperty var1 = mSource.addProperty("var1");
-        var1.setFloatValue(mSource, 54);
-        assertFloatEquals((float) 54, var1.getFloatValue(mSource));
+        var1.setValue(mSource, 54);
+        assertFloatEquals((float) 54, var1.getValue(mSource));
         assertEquals(var1.getName(), "var1");
         var1.set(mSource, (float) 2000);
         assertFloatEquals((float) 2000, var1.get(mSource).floatValue());
@@ -70,7 +70,8 @@
         mScreenMax = 1080;
         Parallax.FloatProperty var1 = mSource.addProperty("var1");
 
-        Parallax.FloatPropertyMarkerValue keyValue = var1.atAbsolute(1000);
+        Parallax.FloatPropertyMarkerValue keyValue = (Parallax.FloatPropertyMarkerValue)
+                var1.atAbsolute(1000);
         assertSame(keyValue.getProperty(), var1);
         assertFloatEquals((float) 1000, keyValue.getMarkerValue(mSource));
     }
@@ -80,7 +81,8 @@
         mScreenMax = 1080;
         Parallax.FloatProperty var1 = mSource.addProperty("var1");
 
-        Parallax.FloatPropertyMarkerValue keyValue = var1.at(0, 0.5f);
+        Parallax.FloatPropertyMarkerValue keyValue = (Parallax.FloatPropertyMarkerValue)
+                var1.at(0, 0.5f);
         assertSame(keyValue.getProperty(), var1);
         assertFloatEquals((float) 540, keyValue.getMarkerValue(mSource));
     }
@@ -90,11 +92,13 @@
         mScreenMax = 1080;
         Parallax.FloatProperty var1 = mSource.addProperty("var1");
 
-        Parallax.FloatPropertyMarkerValue keyValue = var1.at(-100, 0.5f);
+        Parallax.FloatPropertyMarkerValue keyValue = (Parallax.FloatPropertyMarkerValue)
+                var1.at(-100, 0.5f);
         assertSame(keyValue.getProperty(), var1);
         assertFloatEquals((float) 440, keyValue.getMarkerValue(mSource));
 
-        Parallax.FloatPropertyMarkerValue keyValue2 = var1.at(100, 0.5f);
+        Parallax.FloatPropertyMarkerValue keyValue2 = (Parallax.FloatPropertyMarkerValue)
+                var1.at(100, 0.5f);
         assertSame(keyValue2.getProperty(), var1);
         assertFloatEquals((float) 640, keyValue2.getMarkerValue(mSource));
     }
@@ -104,10 +108,10 @@
         Parallax.FloatProperty var1 = mSource.addProperty("var1");
         Parallax.FloatProperty var2 = mSource.addProperty("var2");
 
-        var1.setFloatValue(mSource, (float) 500);
-        var2.setFloatValue(mSource, (float) 499);
+        var1.setValue(mSource, (float) 500);
+        var2.setValue(mSource, (float) 499);
 
-        mSource.verifyProperties();
+        mSource.verifyFloatProperties();
     }
 
     @Test(expected = IllegalStateException.class)
@@ -115,10 +119,10 @@
         Parallax.FloatProperty var1 = mSource.addProperty("var1");
         Parallax.FloatProperty var2 = mSource.addProperty("var2");
 
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
-        var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
 
-        mSource.verifyProperties();
+        mSource.verifyFloatProperties();
     }
 
     @Test
@@ -126,19 +130,19 @@
         Parallax.FloatProperty var1 = mSource.addProperty("var1");
         Parallax.FloatProperty var2 = mSource.addProperty("var2");
 
-        var1.setFloatValue(mSource, (float) 499);
-        var2.setFloatValue(mSource, (float) 500);
+        var1.setValue(mSource, (float) 499);
+        var2.setValue(mSource, (float) 500);
 
-        mSource.verifyProperties();
+        mSource.verifyFloatProperties();
 
-        var1.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
-        var2.setFloatValue(mSource, (float) 500);
+        var1.setValue(mSource, Parallax.FloatProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, (float) 500);
 
-        mSource.verifyProperties();
+        mSource.verifyFloatProperties();
 
-        var1.setFloatValue(mSource, (float) 499);
-        var2.setFloatValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, (float) 499);
+        var2.setValue(mSource, Parallax.FloatProperty.UNKNOWN_AFTER);
 
-        mSource.verifyProperties();
+        mSource.verifyFloatProperties();
     }
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntEffectTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntEffectTest.java
index 02b3f69..cf15fa8 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntEffectTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntEffectTest.java
@@ -16,11 +16,14 @@
 
 package android.support.v17.leanback.widget;
 
+import static junit.framework.Assert.assertEquals;
+
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.util.Property;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -33,17 +36,21 @@
 @SmallTest
 public class ParallaxIntEffectTest {
 
-    Parallax.IntParallax mSource;
+    Parallax<Parallax.IntProperty> mSource;
     int mScreenMax;
     ParallaxEffect.IntEffect mEffect;
     @Mock ParallaxTarget mTarget;
 
+    static void assertFloatEquals(float expected, float actual) {
+        org.junit.Assert.assertEquals((double) expected, (double) actual, 0.0001d);
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        mSource = new Parallax.IntParallax<Parallax.IntProperty>() {
+        mSource = new Parallax<Parallax.IntProperty>() {
 
-            public int getMaxValue() {
+            public float getMaxValue() {
                 return mScreenMax;
             }
 
@@ -64,55 +71,55 @@
         mEffect.target(mTarget);
 
         // start
-        var1.setIntValue(mSource, 540);
+        var1.setValue(mSource, 540);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // 25% complete
-        var1.setIntValue(mSource, 405);
+        var1.setValue(mSource, 405);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0.25f);
         Mockito.reset(mTarget);
 
         // middle
-        var1.setIntValue(mSource, 270);
+        var1.setValue(mSource, 270);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(.5f);
         Mockito.reset(mTarget);
 
         // 75% complete
-        var1.setIntValue(mSource, 135);
+        var1.setValue(mSource, 135);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0.75f);
         Mockito.reset(mTarget);
 
         // end
-        var1.setIntValue(mSource, 0);
+        var1.setValue(mSource, 0);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // after end
-        var1.setIntValue(mSource, -1000);
+        var1.setValue(mSource, -1000);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // before start
-        var1.setIntValue(mSource, 1000);
+        var1.setValue(mSource, 1000);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // unknown_before
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_after
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
@@ -125,7 +132,7 @@
 
         mEffect.setPropertyRanges(var1.atAbsolute(540), var1.atAbsolute(550));
         mEffect.target(mTarget);
-        var1.setIntValue(mSource, 0);
+        var1.setValue(mSource, 0);
         mEffect.performMapping(mSource);
     }
 
@@ -139,95 +146,137 @@
         mEffect.target(mTarget);
 
         // start
-        var1.setIntValue(mSource, 540);
-        var2.setIntValue(mSource, 840);
+        var1.setValue(mSource, 540);
+        var2.setValue(mSource, 840);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // middle
-        var1.setIntValue(mSource, 390);
-        var2.setIntValue(mSource, 690);
+        var1.setValue(mSource, 390);
+        var2.setValue(mSource, 690);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(.5f);
         Mockito.reset(mTarget);
 
         // end
-        var1.setIntValue(mSource, 240);
-        var2.setIntValue(mSource, 540);
+        var1.setValue(mSource, 240);
+        var2.setValue(mSource, 540);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // after end
-        var1.setIntValue(mSource, 200);
-        var2.setIntValue(mSource, 500);
+        var1.setValue(mSource, 200);
+        var2.setValue(mSource, 500);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // before start
-        var1.setIntValue(mSource, 1000);
-        var2.setIntValue(mSource, 1300);
+        var1.setValue(mSource, 1000);
+        var2.setValue(mSource, 1300);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // unknown_before
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
-        var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_before
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
-        var2.setIntValue(mSource, -1000);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, -1000);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_after
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
-        var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // unknown_after
-        var1.setIntValue(mSource, 1000);
-        var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, 1000);
+        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0f);
         Mockito.reset(mTarget);
 
         // unknown_before and less
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
-        var2.setIntValue(mSource, 500);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, 500);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_before and hit second
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
-        var2.setIntValue(mSource, 540);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, 540);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(1f);
         Mockito.reset(mTarget);
 
         // unknown_before with estimation
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
-        var2.setIntValue(mSource, 1080);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, 1080);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0.5f);
         Mockito.reset(mTarget);
 
         // unknown_after with estimation
-        var1.setIntValue(mSource, 0);
-        var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, 0);
+        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
         mEffect.performMapping(mSource);
         verify(mTarget, times(1)).update(0.5f);
         Mockito.reset(mTarget);
     }
 
+    @Test
+    public void testDirectMapping() {
+        mScreenMax = 1080;
+        Parallax.IntProperty var1 = mSource.addProperty("var1");
+
+        mEffect.setPropertyRanges(var1.atAbsolute((int) 540.45), var1.atAbsolute((int) 0.22));
+        Object object = new Object();
+        final int[] properValue = new int[1];
+        Property<Object, Integer> property = new Property<Object, Integer>(Integer.class, "attr") {
+            @Override
+            public void set(Object object, Integer value) {
+                properValue[0] = value;
+            }
+
+            @Override
+            public Integer get(Object o) {
+                return properValue[0];
+            }
+        };
+        mTarget = new ParallaxTarget.DirectPropertyTarget<>(object, property);
+        mEffect.target(mTarget);
+
+        var1.setValue(mSource, (int) 540.45);
+        mEffect.performMapping(mSource);
+        assertEquals((int) 540.45, properValue[0]);
+
+        var1.setValue(mSource, (int) 405.85);
+        mEffect.performMapping(mSource);
+        assertEquals((int) 405.85, properValue[0]);
+
+        var1.setValue(mSource, 2000);
+        mEffect.performMapping(mSource);
+        assertEquals((int) 540.45, properValue[0]);
+
+        var1.setValue(mSource, (int) 0.22);
+        mEffect.performMapping(mSource);
+        assertEquals((int) 0.22, properValue[0]);
+
+        var1.setValue(mSource, (int) 0.12);
+        mEffect.performMapping(mSource);
+        assertEquals((int) 0.22, properValue[0]);
+    }
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntTest.java
index 84fadbd0..187bfb6 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/ParallaxIntTest.java
@@ -29,7 +29,7 @@
 @SmallTest
 public class ParallaxIntTest {
 
-    Parallax.IntParallax mSource;
+    Parallax<Parallax.IntProperty> mSource;
     int mScreenMax;
 
     static void assertFloatEquals(float expected, float actual) {
@@ -38,9 +38,9 @@
 
     @Before
     public void setUp() throws Exception {
-        mSource = new Parallax.IntParallax<Parallax.IntProperty>() {
+        mSource = new Parallax<Parallax.IntProperty>() {
 
-            public int getMaxValue() {
+            public float getMaxValue() {
                 return mScreenMax;
             }
 
@@ -55,8 +55,8 @@
     public void testVariable() {
         mScreenMax = 1080;
         Parallax.IntProperty var1 = mSource.addProperty("var1");
-        var1.setIntValue(mSource, 54);
-        assertEquals((int) 54, var1.getIntValue(mSource));
+        var1.setValue(mSource, 54);
+        assertEquals((int) 54, var1.getValue(mSource));
         assertEquals(var1.getName(), "var1");
         var1.set(mSource, (int) 2000);
         assertEquals((int) 2000, var1.get(mSource).intValue());
@@ -67,7 +67,8 @@
         mScreenMax = 1080;
         Parallax.IntProperty var1 = mSource.addProperty("var1");
 
-        Parallax.IntPropertyMarkerValue keyValue = var1.atAbsolute(1000);
+        Parallax.IntPropertyMarkerValue keyValue = (Parallax.IntPropertyMarkerValue)
+                var1.atAbsolute(1000);
         assertSame(keyValue.getProperty(), var1);
         assertEquals((int) 1000, keyValue.getMarkerValue(mSource));
     }
@@ -77,7 +78,8 @@
         mScreenMax = 1080;
         Parallax.IntProperty var1 = mSource.addProperty("var1");
 
-        Parallax.IntPropertyMarkerValue keyValue = var1.at(0, 0.5f);
+        Parallax.IntPropertyMarkerValue keyValue = (Parallax.IntPropertyMarkerValue)
+                var1.at(0, 0.5f);
         assertSame(keyValue.getProperty(), var1);
         assertEquals((int) 540, keyValue.getMarkerValue(mSource));
     }
@@ -87,11 +89,13 @@
         mScreenMax = 1080;
         Parallax.IntProperty var1 = mSource.addProperty("var1");
 
-        Parallax.IntPropertyMarkerValue keyValue = var1.at(-100, 0.5f);
+        Parallax.IntPropertyMarkerValue keyValue = (Parallax.IntPropertyMarkerValue)
+                var1.at(-100, 0.5f);
         assertSame(keyValue.getProperty(), var1);
         assertEquals((int) 440, keyValue.getMarkerValue(mSource));
 
-        Parallax.IntPropertyMarkerValue keyValue2 = var1.at(100, 0.5f);
+        Parallax.IntPropertyMarkerValue keyValue2 = (Parallax.IntPropertyMarkerValue)
+                var1.at(100, 0.5f);
         assertSame(keyValue2.getProperty(), var1);
         assertEquals((int) 640, keyValue2.getMarkerValue(mSource));
     }
@@ -101,10 +105,10 @@
         Parallax.IntProperty var1 = mSource.addProperty("var1");
         Parallax.IntProperty var2 = mSource.addProperty("var2");
 
-        var1.setIntValue(mSource, (int) 500);
-        var2.setIntValue(mSource, (int) 499);
+        var1.setValue(mSource, (int) 500);
+        var2.setValue(mSource, (int) 499);
 
-        mSource.verifyProperties();
+        mSource.verifyIntProperties();
     }
 
     @Test(expected = IllegalStateException.class)
@@ -112,10 +116,10 @@
         Parallax.IntProperty var1 = mSource.addProperty("var1");
         Parallax.IntProperty var2 = mSource.addProperty("var2");
 
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
-        var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
 
-        mSource.verifyProperties();
+        mSource.verifyIntProperties();
     }
 
     @Test
@@ -123,19 +127,19 @@
         Parallax.IntProperty var1 = mSource.addProperty("var1");
         Parallax.IntProperty var2 = mSource.addProperty("var2");
 
-        var1.setIntValue(mSource, (int) 499);
-        var2.setIntValue(mSource, (int) 500);
+        var1.setValue(mSource, (int) 499);
+        var2.setValue(mSource, (int) 500);
 
-        mSource.verifyProperties();
+        mSource.verifyIntProperties();
 
-        var1.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
-        var2.setIntValue(mSource, (int) 500);
+        var1.setValue(mSource, Parallax.IntProperty.UNKNOWN_BEFORE);
+        var2.setValue(mSource, (int) 500);
 
-        mSource.verifyProperties();
+        mSource.verifyIntProperties();
 
-        var1.setIntValue(mSource, (int) 499);
-        var2.setIntValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
+        var1.setValue(mSource, (int) 499);
+        var2.setValue(mSource, Parallax.IntProperty.UNKNOWN_AFTER);
 
-        mSource.verifyProperties();
+        mSource.verifyIntProperties();
     }
 }
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/TitleViewAdapterTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/TitleViewAdapterTest.java
new file mode 100644
index 0000000..d038be7
--- /dev/null
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/TitleViewAdapterTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.v17.leanback.widget;
+
+import android.content.Context;
+import android.graphics.drawable.GradientDrawable;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TitleViewAdapterTest {
+
+
+    public static class CustomTitle extends LinearLayout implements TitleViewAdapter.Provider {
+
+        final View mSearchOrbView;
+
+        public CustomTitle(Context context, AttributeSet set) {
+            this(context, set, 0);
+        }
+
+        public CustomTitle(Context context, AttributeSet set, int s) {
+            super(context, set, s);
+            mSearchOrbView = new View(context);
+            addView(mSearchOrbView, 10, 10);
+        }
+
+        TitleViewAdapter mTitleViewAdapter = new TitleViewAdapter() {
+            @Override
+            public View getSearchAffordanceView() {
+                return mSearchOrbView;
+            }
+        };
+
+        @Override
+        public TitleViewAdapter getTitleViewAdapter() {
+            return mTitleViewAdapter;
+        }
+    }
+
+    @Test
+    public void customTitle() {
+        CustomTitle t = new CustomTitle(InstrumentationRegistry.getTargetContext(), null);
+        TitleViewAdapter adapter = t.getTitleViewAdapter();
+        adapter.setTitle("title");
+        adapter.setBadgeDrawable(new GradientDrawable());
+        View.OnClickListener listener = Mockito.mock(View.OnClickListener.class);
+        adapter.setOnSearchClickedListener(listener);
+        adapter.getSearchAffordanceView().performClick();
+        Mockito.verify(listener).onClick(Mockito.any(View.class));
+    }
+}
diff --git a/v4/AndroidManifest.xml b/v4/AndroidManifest.xml
index cecc743..6532182 100644
--- a/v4/AndroidManifest.xml
+++ b/v4/AndroidManifest.xml
@@ -17,6 +17,7 @@
           xmlns:tools="http://schemas.android.com/tools"
           package="android.support.v4">
     <uses-sdk android:minSdkVersion="9" tools:overrideLibrary="android.support.v4"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v7/appcompat/AndroidManifest.xml b/v7/appcompat/AndroidManifest.xml
index d5858d1..183d83b 100644
--- a/v7/appcompat/AndroidManifest.xml
+++ b/v7/appcompat/AndroidManifest.xml
@@ -18,6 +18,7 @@
           package="android.support.v7.appcompat">
     <uses-sdk android:minSdkVersion="9"
               tools:overrideLibrary="android.support.graphics.drawable.animated"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application/>
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v7/appcompat/res-public/values/public_attrs.xml b/v7/appcompat/res-public/values/public_attrs.xml
index 3961f49d..a7829eb 100644
--- a/v7/appcompat/res-public/values/public_attrs.xml
+++ b/v7/appcompat/res-public/values/public_attrs.xml
@@ -180,6 +180,7 @@
      <public type="attr" name="textAllCaps"/>
      <public type="attr" name="textAppearanceLargePopupMenu"/>
      <public type="attr" name="textAppearanceListItem"/>
+     <public type="attr" name="textAppearanceListItemSecondary"/>
      <public type="attr" name="textAppearanceListItemSmall"/>
      <public type="attr" name="textAppearancePopupMenuHeader"/>
      <public type="attr" name="textAppearanceSearchResultSubtitle"/>
@@ -194,6 +195,8 @@
      <public type="attr" name="tickMark"/>
      <public type="attr" name="tickMarkTint"/>
      <public type="attr" name="tickMarkTintMode"/>
+     <public type="attr" name="tint"/>
+     <public type="attr" name="tintMode"/>
      <public type="attr" name="title"/>
      <public type="attr" name="titleMargin"/>
      <public type="attr" name="titleMarginBottom"/>
diff --git a/v7/appcompat/res/values/attrs.xml b/v7/appcompat/res/values/attrs.xml
index 03ddeec..d5ec5a1 100644
--- a/v7/appcompat/res/values/attrs.xml
+++ b/v7/appcompat/res/values/attrs.xml
@@ -280,10 +280,11 @@
 
         <!-- The preferred TextAppearance for the primary text of list items. -->
         <attr name="textAppearanceListItem" format="reference"/>
+        <!-- The preferred TextAppearance for the secondary text of list items. -->
+        <attr name="textAppearanceListItemSecondary" format="reference" />
         <!-- The preferred TextAppearance for the primary text of small list items. -->
         <attr name="textAppearanceListItemSmall" format="reference"/>
 
-
         <!-- ============ -->
         <!-- Panel styles -->
         <!-- ============ -->
@@ -1062,6 +1063,27 @@
         <!-- Sets a drawable as the content of this ImageView. Allows the use of vector drawable
              when running on older versions of the platform. -->
         <attr name="srcCompat" format="reference" />
+
+        <!-- Tint to apply to the image source. -->
+        <attr name="tint" format="color" />
+
+        <!-- Blending mode used to apply the image source tint. -->
+        <attr name="tintMode">
+            <!-- The tint is drawn on top of the drawable.
+                 [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
+            <enum name="src_over" value="3" />
+            <!-- The tint is masked by the alpha channel of the drawable. The drawable’s
+                 color channels are thrown out. [Sa * Da, Sc * Da] -->
+            <enum name="src_in" value="5" />
+            <!-- The tint is drawn above the drawable, but with the drawable’s alpha
+                 channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
+            <enum name="src_atop" value="9" />
+            <!-- Multiplies the color and alpha channels of the drawable with those of
+                 the tint. [Sa * Da, Sc * Dc] -->
+            <enum name="multiply" value="14" />
+            <!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
+            <enum name="screen" value="15" />
+        </attr>
     </declare-styleable>
 
     <declare-styleable name="AppCompatSeekBar">
diff --git a/v7/appcompat/res/values/themes_base.xml b/v7/appcompat/res/values/themes_base.xml
index 92e7bce..434c619 100644
--- a/v7/appcompat/res/values/themes_base.xml
+++ b/v7/appcompat/res/values/themes_base.xml
@@ -181,6 +181,7 @@
         <!-- List attributes -->
         <item name="textAppearanceListItem">@style/TextAppearance.AppCompat.Subhead</item>
         <item name="textAppearanceListItemSmall">@style/TextAppearance.AppCompat.Subhead</item>
+        <item name="textAppearanceListItemSecondary">@style/TextAppearance.AppCompat.Body1</item>
         <item name="listPreferredItemHeight">64dp</item>
         <item name="listPreferredItemHeightSmall">48dp</item>
         <item name="listPreferredItemHeightLarge">80dp</item>
@@ -342,6 +343,7 @@
         <!-- List attributes -->
         <item name="textAppearanceListItem">@style/TextAppearance.AppCompat.Subhead</item>
         <item name="textAppearanceListItemSmall">@style/TextAppearance.AppCompat.Subhead</item>
+        <item name="textAppearanceListItemSecondary">@style/TextAppearance.AppCompat.Body1</item>
         <item name="listPreferredItemHeight">64dp</item>
         <item name="listPreferredItemHeightSmall">48dp</item>
         <item name="listPreferredItemHeightLarge">80dp</item>
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBar.java b/v7/appcompat/src/android/support/v7/app/ActionBar.java
index e26e813..320cf7b 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBar.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBar.java
@@ -900,7 +900,7 @@
      * call {@link #setHomeActionContentDescription(int) setHomeActionContentDescription()}
      * to provide a correct description of the action for accessibility support.</p>
      *
-     * @param resId Resource ID of a drawable to use for the up indicator, or 0
+     * @param resId Resource ID of a drawable to use for the up indicator, or null
      *              to use the theme's default
      *
      * @see #setDisplayOptions(int, int)
@@ -1100,7 +1100,9 @@
      * Attempts to move focus to the ActionBar if it does not already contain the focus.
      *
      * @return {@code true} if focus changes or {@code false} if focus doesn't change.
+     * @hide
      */
+    @RestrictTo(LIBRARY_GROUP)
     boolean requestFocus() {
         return false;
     }
@@ -1285,7 +1287,7 @@
          * @see #setContentDescription(CharSequence)
          * @see #getContentDescription()
          */
-        public abstract Tab setContentDescription(int resId);
+        public abstract Tab setContentDescription(@StringRes int resId);
 
         /**
          * Set a description of this tab's content for use in accessibility support.
diff --git a/v7/appcompat/src/android/support/v7/app/AlertController.java b/v7/appcompat/src/android/support/v7/app/AlertController.java
index ee7ea8e..d0f8fd6 100644
--- a/v7/appcompat/src/android/support/v7/app/AlertController.java
+++ b/v7/appcompat/src/android/support/v7/app/AlertController.java
@@ -16,6 +16,8 @@
 
 package android.support.v7.app;
 
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.res.TypedArray;
@@ -28,6 +30,7 @@
 import android.support.v4.view.ViewCompat;
 import android.support.v4.widget.NestedScrollView;
 import android.support.v7.appcompat.R;
+import android.support.v7.widget.LinearLayoutCompat;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.TypedValue;
@@ -58,8 +61,6 @@
 
 import java.lang.ref.WeakReference;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
 class AlertController {
     private final Context mContext;
     final AppCompatDialog mDialog;
@@ -652,7 +653,7 @@
             }
 
             if (mListView != null) {
-                ((LinearLayout.LayoutParams) customPanel.getLayoutParams()).weight = 0;
+                ((LinearLayoutCompat.LayoutParams) customPanel.getLayoutParams()).weight = 0;
             }
         } else {
             customPanel.setVisibility(View.GONE);
diff --git a/v7/appcompat/src/android/support/v7/app/AlertDialog.java b/v7/appcompat/src/android/support/v7/app/AlertDialog.java
index 051f5cc..c73e619 100644
--- a/v7/appcompat/src/android/support/v7/app/AlertDialog.java
+++ b/v7/appcompat/src/android/support/v7/app/AlertDialog.java
@@ -187,7 +187,9 @@
 
     /**
      * Internal api to allow hinting for the best button panel layout.
+     * @hide
      */
+    @RestrictTo(LIBRARY_GROUP)
     void setButtonPanelLayoutHint(int layoutHint) {
         mAlert.setButtonPanelLayoutHint(layoutHint);
     }
diff --git a/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java b/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java
index 4776812..8828458 100644
--- a/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java
+++ b/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java
@@ -70,9 +70,9 @@
                 }
             };
 
-    public ToolbarActionBar(Toolbar toolbar, CharSequence title, Window.Callback callback) {
+    ToolbarActionBar(Toolbar toolbar, CharSequence title, Window.Callback windowCallback) {
         mDecorToolbar = new ToolbarWidgetWrapper(toolbar, false);
-        mWindowCallback = new ToolbarCallbackWrapper(callback);
+        mWindowCallback = new ToolbarCallbackWrapper(windowCallback);
         mDecorToolbar.setWindowCallback(mWindowCallback);
         toolbar.setOnMenuItemClickListener(mMenuClicker);
         mDecorToolbar.setWindowTitle(title);
diff --git a/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java b/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java
index 44c0478..5069812 100644
--- a/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java
+++ b/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java
@@ -21,7 +21,9 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.res.AssetManager;
+import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.os.Build;
 import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.v7.appcompat.R;
@@ -38,18 +40,103 @@
     private int mThemeResource;
     private Resources.Theme mTheme;
     private LayoutInflater mInflater;
+    private Configuration mOverrideConfiguration;
+    private Resources mResources;
 
+    /**
+     * Creates a new context wrapper with no theme and no base context.
+     * <p>
+     * <stong>Note:</strong> A base context <strong>must</strong> be attached
+     * using {@link #attachBaseContext(Context)} before calling any other
+     * method on the newly constructed context wrapper.
+     */
+    public ContextThemeWrapper() {
+        super(null);
+    }
+
+    /**
+     * Creates a new context wrapper with the specified theme.
+     * <p>
+     * The specified theme will be applied on top of the base context's theme.
+     * Any attributes not explicitly defined in the theme identified by
+     * <var>themeResId</var> will retain their original values.
+     *
+     * @param base the base context
+     * @param themeResId the resource ID of the theme to be applied on top of
+     *                   the base context's theme
+     */
     public ContextThemeWrapper(Context base, @StyleRes int themeResId) {
         super(base);
         mThemeResource = themeResId;
     }
 
+    /**
+     * Creates a new context wrapper with the specified theme.
+     * <p>
+     * Unlike {@link #ContextThemeWrapper(Context, int)}, the theme passed to
+     * this constructor will completely replace the base context's theme.
+     *
+     * @param base the base context
+     * @param theme the theme against which resources should be inflated
+     */
     public ContextThemeWrapper(Context base, Resources.Theme theme) {
         super(base);
         mTheme = theme;
     }
 
     @Override
+    protected void attachBaseContext(Context newBase) {
+        super.attachBaseContext(newBase);
+    }
+
+    /**
+     * Call to set an "override configuration" on this context -- this is
+     * a configuration that replies one or more values of the standard
+     * configuration that is applied to the context.  See
+     * {@link Context#createConfigurationContext(Configuration)} for more
+     * information.
+     *
+     * <p>This method can only be called once, and must be called before any
+     * calls to {@link #getResources()} or {@link #getAssets()} are made.
+     */
+    public void applyOverrideConfiguration(Configuration overrideConfiguration) {
+        if (mResources != null) {
+            throw new IllegalStateException(
+                    "getResources() or getAssets() has already been called");
+        }
+        if (mOverrideConfiguration != null) {
+            throw new IllegalStateException("Override configuration has already been set");
+        }
+        mOverrideConfiguration = new Configuration(overrideConfiguration);
+    }
+
+    /**
+     * Used by ActivityThread to apply the overridden configuration to onConfigurationChange
+     * callbacks.
+     * @hide
+     */
+    public Configuration getOverrideConfiguration() {
+        return mOverrideConfiguration;
+    }
+
+    @Override
+    public Resources getResources() {
+        return getResourcesInternal();
+    }
+
+    private Resources getResourcesInternal() {
+        if (mResources == null) {
+            if (mOverrideConfiguration == null) {
+                mResources = super.getResources();
+            } else if (Build.VERSION.SDK_INT >= 17) {
+                final Context resContext = createConfigurationContext(mOverrideConfiguration);
+                mResources = resContext.getResources();
+            }
+        }
+        return mResources;
+    }
+
+    @Override
     public void setTheme(int resid) {
         if (mThemeResource != resid) {
             mThemeResource = resid;
diff --git a/v7/appcompat/src/android/support/v7/view/menu/CascadingMenuPopup.java b/v7/appcompat/src/android/support/v7/view/menu/CascadingMenuPopup.java
index d3c2fc8..dd6a5bc 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/CascadingMenuPopup.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/CascadingMenuPopup.java
@@ -228,6 +228,7 @@
         popupWindow.setAnchorView(mAnchorView);
         popupWindow.setDropDownGravity(mDropDownGravity);
         popupWindow.setModal(true);
+        popupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
         return popupWindow;
     }
 
diff --git a/v7/appcompat/src/android/support/v7/widget/AbsActionBarView.java b/v7/appcompat/src/android/support/v7/widget/AbsActionBarView.java
index 1faf568..b048ffa 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;
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java b/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java
index de4484c..f34b577 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java
@@ -210,6 +210,14 @@
         return true;
     }
 
+    @Override
+    public boolean onHoverEvent(MotionEvent ev) {
+        super.onHoverEvent(ev);
+
+        // An action bar always eats hover events.
+        return true;
+    }
+
     public void setTabContainer(ScrollingTabContainerView tabView) {
         if (mTabContainer != null) {
             removeView(mTabContainer);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java
index edbd1a7..96a481e 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java
@@ -37,7 +37,7 @@
  * <ul>
  *     <li>Supports {@link R.attr#textAllCaps} style attribute which works back to
  *     {@link android.os.Build.VERSION_CODES#GINGERBREAD Gingerbread}.</li>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.view.ViewCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
  *     {@link R.attr#backgroundTintMode}.</li>
@@ -53,8 +53,8 @@
             android.R.attr.popupBackground
     };
 
-    private AppCompatBackgroundHelper mBackgroundTintHelper;
-    private AppCompatTextHelper mTextHelper;
+    private final AppCompatBackgroundHelper mBackgroundTintHelper;
+    private final AppCompatTextHelper mTextHelper;
 
     public AppCompatAutoCompleteTextView(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
index a4551dbe..cb0ef68 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
@@ -148,18 +148,18 @@
 
     private boolean shouldApplyFrameworkTintUsingColorFilter() {
         final int sdk = Build.VERSION.SDK_INT;
-        if (sdk < 21) {
-            // API 19 and below doesn't have framework tint
-            return false;
+        if (sdk > 21) {
+            // On API 22+, if we're using an internal compat background tint, we're also
+            // responsible for applying any custom tint set via the framework impl
+            return mInternalBackgroundTint != null;
         } else if (sdk == 21) {
             // GradientDrawable doesn't implement setTintList on API 21, and since there is
             // no nice way to unwrap DrawableContainers we have to blanket apply this
             // on API 21
             return true;
         } else {
-            // On API 22+, if we're using an internal compat background tint, we're also
-            // responsible for applying any custom tint set via the framework impl
-            return mInternalBackgroundTint != null;
+            // API 19 and below doesn't have framework tint
+            return false;
         }
     }
 
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java b/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
index f7fa23f..c2075b94 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
@@ -40,7 +40,7 @@
  * <ul>
  *     <li>Supports {@link R.attr#textAllCaps} style attribute which works back to
  *     {@link android.os.Build.VERSION_CODES#GINGERBREAD Gingerbread}.</li>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.view.ViewCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
  *     {@link R.attr#backgroundTintMode}.</li>
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java b/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java
index 6942cc5..5809d25 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java
@@ -35,7 +35,7 @@
  * A {@link CheckBox} which supports compatible features on older version of the platform,
  * including:
  * <ul>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.widget.CompoundButtonCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#buttonTint} and
  *     {@link R.attr#buttonTintMode}.</li>
@@ -46,7 +46,7 @@
  */
 public class AppCompatCheckBox extends CheckBox implements TintableCompoundButton {
 
-    private AppCompatCompoundButtonHelper mCompoundButtonHelper;
+    private final AppCompatCompoundButtonHelper mCompoundButtonHelper;
 
     public AppCompatCheckBox(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatCheckedTextView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatCheckedTextView.java
index fadf328..1725c24 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatCheckedTextView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatCheckedTextView.java
@@ -34,7 +34,7 @@
             android.R.attr.checkMark
     };
 
-    private AppCompatTextHelper mTextHelper;
+    private final AppCompatTextHelper mTextHelper;
 
     public AppCompatCheckedTextView(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java b/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
index 50a17cd..2437e51 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
@@ -48,10 +48,10 @@
 import android.support.v4.util.ArrayMap;
 import android.support.v4.util.LongSparseArray;
 import android.support.v4.util.LruCache;
+import android.support.v4.util.SparseArrayCompat;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.SparseArray;
 import android.util.TypedValue;
 import android.util.Xml;
 
@@ -174,9 +174,9 @@
             R.drawable.abc_btn_radio_material
     };
 
-    private WeakHashMap<Context, SparseArray<ColorStateList>> mTintLists;
+    private WeakHashMap<Context, SparseArrayCompat<ColorStateList>> mTintLists;
     private ArrayMap<String, InflateDelegate> mDelegates;
-    private SparseArray<String> mKnownDrawableIdTags;
+    private SparseArrayCompat<String> mKnownDrawableIdTags;
 
     private final Object mDrawableCacheLock = new Object();
     private final WeakHashMap<Context, LongSparseArray<WeakReference<Drawable.ConstantState>>>
@@ -321,7 +321,7 @@
                 }
             } else {
                 // Create an id cache as we'll need one later
-                mKnownDrawableIdTags = new SparseArray<>();
+                mKnownDrawableIdTags = new SparseArrayCompat<>();
             }
 
             if (mTypedValue == null) {
@@ -423,7 +423,7 @@
                     cache = new LongSparseArray<>();
                     mDrawableCaches.put(context, cache);
                 }
-                cache.put(key, new WeakReference<ConstantState>(cs));
+                cache.put(key, new WeakReference<>(cs));
             }
             return true;
         }
@@ -562,7 +562,7 @@
 
     private ColorStateList getTintListFromCache(@NonNull Context context, @DrawableRes int resId) {
         if (mTintLists != null) {
-            final SparseArray<ColorStateList> tints = mTintLists.get(context);
+            final SparseArrayCompat<ColorStateList> tints = mTintLists.get(context);
             return tints != null ? tints.get(resId) : null;
         }
         return null;
@@ -573,9 +573,9 @@
         if (mTintLists == null) {
             mTintLists = new WeakHashMap<>();
         }
-        SparseArray<ColorStateList> themeTints = mTintLists.get(context);
+        SparseArrayCompat<ColorStateList> themeTints = mTintLists.get(context);
         if (themeTints == null) {
-            themeTints = new SparseArray<>();
+            themeTints = new SparseArrayCompat<>();
             mTintLists.put(context, themeTints);
         }
         themeTints.append(resId, tintList);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java b/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java
index 9ea02c6..d93f399 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java
@@ -36,7 +36,7 @@
  * <ul>
  *     <li>Supports {@link R.attr#textAllCaps} style attribute which works back to
  *     {@link android.os.Build.VERSION_CODES#GINGERBREAD Gingerbread}.</li>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.view.ViewCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
  *     {@link R.attr#backgroundTintMode}.</li>
@@ -47,8 +47,8 @@
  */
 public class AppCompatEditText extends EditText implements TintableBackgroundView {
 
-    private AppCompatBackgroundHelper mBackgroundTintHelper;
-    private AppCompatTextHelper mTextHelper;
+    private final AppCompatBackgroundHelper mBackgroundTintHelper;
+    private final AppCompatTextHelper mTextHelper;
 
     public AppCompatEditText(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java b/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
index f8280c9..d0bcf00 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
@@ -20,33 +20,44 @@
 
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
+import android.support.v4.widget.ImageViewCompat;
+import android.support.v4.widget.TintableImageSourceView;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
 import android.widget.ImageButton;
+import android.widget.ImageView;
 
 /**
  * A {@link ImageButton} which supports compatible features on older version of the platform,
  * including:
  * <ul>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.view.ViewCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
  *     {@link R.attr#backgroundTintMode}.</li>
+ *     <li>Allows dynamic tint of its image via the image tint methods in
+ *     {@link ImageViewCompat}.</li>
+ *     <li>Allows setting of the image tint using {@link R.attr#tint} and
+ *     {@link R.attr#tintMode}.</li>
  * </ul>
  *
  * <p>This will automatically be used when you use {@link android.widget.ImageButton} in your
  * layouts. You should only need to manually use this class when writing custom views.</p>
  */
-public class AppCompatImageButton extends ImageButton implements TintableBackgroundView {
+public class AppCompatImageButton extends ImageButton implements TintableBackgroundView,
+        TintableImageSourceView {
 
-    private AppCompatBackgroundHelper mBackgroundTintHelper;
-    private AppCompatImageHelper mImageHelper;
+    private final AppCompatBackgroundHelper mBackgroundTintHelper;
+    private final AppCompatImageHelper mImageHelper;
 
     public AppCompatImageButton(Context context) {
         this(context, null);
@@ -73,6 +84,38 @@
     }
 
     @Override
+    public void setImageDrawable(@Nullable Drawable drawable) {
+        super.setImageDrawable(drawable);
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
+    }
+
+    @Override
+    public void setImageBitmap(Bitmap bm) {
+        super.setImageBitmap(bm);
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
+    }
+
+    @Override
+    public void setImageIcon(@Nullable Icon icon) {
+        super.setImageIcon(icon);
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
+    }
+
+    @Override
+    public void setImageURI(@Nullable Uri uri) {
+        super.setImageURI(uri);
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
+    }
+
+    @Override
     public void setBackgroundResource(@DrawableRes int resId) {
         super.setBackgroundResource(resId);
         if (mBackgroundTintHelper != null) {
@@ -143,6 +186,61 @@
         return mBackgroundTintHelper != null
                 ? mBackgroundTintHelper.getSupportBackgroundTintMode() : null;
     }
+    /**
+     * This should be accessed via
+     * {@link android.support.v4.widget.ImageViewCompat#setImageTintList(ImageView, ColorStateList)}
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    public void setSupportImageTintList(@Nullable ColorStateList tint) {
+        if (mImageHelper != null) {
+            mImageHelper.setSupportImageTintList(tint);
+        }
+    }
+
+    /**
+     * This should be accessed via
+     * {@link android.support.v4.widget.ImageViewCompat#getImageTintList(ImageView)}
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    @Nullable
+    public ColorStateList getSupportImageTintList() {
+        return mImageHelper != null
+                ? mImageHelper.getSupportImageTintList() : null;
+    }
+
+    /**
+     * This should be accessed via
+     * {@link android.support.v4.widget.ImageViewCompat#setImageTintMode(ImageView, PorterDuff.Mode)}
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    public void setSupportImageTintMode(@Nullable PorterDuff.Mode tintMode) {
+        if (mImageHelper != null) {
+            mImageHelper.setSupportImageTintMode(tintMode);
+        }
+    }
+
+    /**
+     * This should be accessed via
+     * {@link android.support.v4.widget.ImageViewCompat#getImageTintMode(ImageView)}
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    @Nullable
+    public PorterDuff.Mode getSupportImageTintMode() {
+        return mImageHelper != null
+                ? mImageHelper.getSupportImageTintMode() : null;
+    }
 
     @Override
     protected void drawableStateChanged() {
@@ -150,6 +248,9 @@
         if (mBackgroundTintHelper != null) {
             mBackgroundTintHelper.applySupportBackgroundTint();
         }
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
     }
 
     public boolean hasOverlappingRendering() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java
index fe733f7d..12b8520 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java
@@ -18,9 +18,13 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.NonNull;
 import android.support.annotation.RestrictTo;
+import android.support.v4.widget.ImageViewCompat;
 import android.support.v7.appcompat.R;
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
@@ -31,22 +35,22 @@
  */
 @RestrictTo(LIBRARY_GROUP)
 public class AppCompatImageHelper {
-
     private final ImageView mView;
 
+    private TintInfo mInternalImageTint;
+    private TintInfo mImageTint;
+    private TintInfo mTmpInfo;
+
     public AppCompatImageHelper(ImageView view) {
         mView = view;
     }
 
     public void loadFromAttributes(AttributeSet attrs, int defStyleAttr) {
-        TintTypedArray a = null;
+        TintTypedArray a = TintTypedArray.obtainStyledAttributes(mView.getContext(), attrs,
+                R.styleable.AppCompatImageView, defStyleAttr, 0);
         try {
             Drawable drawable = mView.getDrawable();
-
             if (drawable == null) {
-                a = TintTypedArray.obtainStyledAttributes(mView.getContext(), attrs,
-                        R.styleable.AppCompatImageView, defStyleAttr, 0);
-
                 // If the view doesn't already have a drawable (from android:src), try loading
                 // it from srcCompat
                 final int id = a.getResourceId(R.styleable.AppCompatImageView_srcCompat, -1);
@@ -61,10 +65,18 @@
             if (drawable != null) {
                 DrawableUtils.fixDrawable(drawable);
             }
-        } finally {
-            if (a != null) {
-                a.recycle();
+
+            if (a.hasValue(R.styleable.AppCompatImageView_tint)) {
+                ImageViewCompat.setImageTintList(mView,
+                        a.getColorStateList(R.styleable.AppCompatImageView_tint));
             }
+            if (a.hasValue(R.styleable.AppCompatImageView_tintMode)) {
+                ImageViewCompat.setImageTintMode(mView,
+                        DrawableUtils.parseTintMode(
+                                a.getInt(R.styleable.AppCompatImageView_tintMode, -1), null));
+            }
+        } finally {
+            a.recycle();
         }
     }
 
@@ -78,6 +90,8 @@
         } else {
             mView.setImageDrawable(null);
         }
+
+        applySupportImageTint();
     }
 
     boolean hasOverlappingRendering() {
@@ -90,4 +104,116 @@
         }
         return true;
     }
+
+    void setSupportImageTintList(ColorStateList tint) {
+        if (mImageTint == null) {
+            mImageTint = new TintInfo();
+        }
+        mImageTint.mTintList = tint;
+        mImageTint.mHasTintList = true;
+        applySupportImageTint();
+    }
+
+    ColorStateList getSupportImageTintList() {
+        return mImageTint != null ? mImageTint.mTintList : null;
+    }
+
+    void setSupportImageTintMode(PorterDuff.Mode tintMode) {
+        if (mImageTint == null) {
+            mImageTint = new TintInfo();
+        }
+        mImageTint.mTintMode = tintMode;
+        mImageTint.mHasTintMode = true;
+
+        applySupportImageTint();
+    }
+
+    PorterDuff.Mode getSupportImageTintMode() {
+        return mImageTint != null ? mImageTint.mTintMode : null;
+    }
+
+    void applySupportImageTint() {
+        final Drawable imageViewDrawable = mView.getDrawable();
+        if (imageViewDrawable != null) {
+            DrawableUtils.fixDrawable(imageViewDrawable);
+        }
+
+        if (imageViewDrawable != null) {
+            if (shouldApplyFrameworkTintUsingColorFilter()
+                    && applyFrameworkTintUsingColorFilter(imageViewDrawable)) {
+                // This needs to be called before the internal tints below so it takes
+                // effect on any widgets using the compat tint on API 21
+                return;
+            }
+
+            if (mImageTint != null) {
+                AppCompatDrawableManager.tintDrawable(imageViewDrawable, mImageTint,
+                        mView.getDrawableState());
+            } else if (mInternalImageTint != null) {
+                AppCompatDrawableManager.tintDrawable(imageViewDrawable, mInternalImageTint,
+                        mView.getDrawableState());
+            }
+        }
+    }
+
+    void setInternalImageTint(ColorStateList tint) {
+        if (tint != null) {
+            if (mInternalImageTint == null) {
+                mInternalImageTint = new TintInfo();
+            }
+            mInternalImageTint.mTintList = tint;
+            mInternalImageTint.mHasTintList = true;
+        } else {
+            mInternalImageTint = null;
+        }
+        applySupportImageTint();
+    }
+
+    private boolean shouldApplyFrameworkTintUsingColorFilter() {
+        final int sdk = Build.VERSION.SDK_INT;
+        if (sdk > 21) {
+            // On API 22+, if we're using an internal compat image source tint, we're also
+            // responsible for applying any custom tint set via the framework impl
+            return mInternalImageTint != null;
+        } else if (sdk == 21) {
+            // GradientDrawable doesn't implement setTintList on API 21, and since there is
+            // no nice way to unwrap DrawableContainers we have to blanket apply this
+            // on API 21
+            return true;
+        } else {
+            // API 19 and below doesn't have framework tint
+            return false;
+        }
+    }
+
+    /**
+     * Applies the framework image source tint to a view, but using the compat method (ColorFilter)
+     *
+     * @return true if a tint was applied
+     */
+    private boolean applyFrameworkTintUsingColorFilter(@NonNull Drawable imageSource) {
+        if (mTmpInfo == null) {
+            mTmpInfo = new TintInfo();
+        }
+        final TintInfo info = mTmpInfo;
+        info.clear();
+
+        final ColorStateList tintList = ImageViewCompat.getImageTintList(mView);
+        if (tintList != null) {
+            info.mHasTintList = true;
+            info.mTintList = tintList;
+        }
+        final PorterDuff.Mode mode = ImageViewCompat.getImageTintMode(mView);
+        if (mode != null) {
+            info.mHasTintMode = true;
+            info.mTintMode = mode;
+        }
+
+        if (info.mHasTintList || info.mHasTintMode) {
+            AppCompatDrawableManager.tintDrawable(imageSource, info, mView.getDrawableState());
+            return true;
+        }
+
+        return false;
+    }
 }
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
index b749d6c..532a18b 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
@@ -20,12 +20,17 @@
 
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
+import android.support.v4.widget.ImageViewCompat;
+import android.support.v4.widget.TintableImageSourceView;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
 import android.widget.ImageView;
@@ -34,19 +39,24 @@
  * A {@link ImageView} which supports compatible features on older version of the platform,
  * including:
  * <ul>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.view.ViewCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
  *     {@link R.attr#backgroundTintMode}.</li>
+ *     <li>Allows dynamic tint of its image via the image tint methods in
+ *     {@link ImageViewCompat}.</li>
+ *     <li>Allows setting of the image tint using {@link R.attr#tint} and
+ *     {@link R.attr#tintMode}.</li>
  * </ul>
  *
  * <p>This will automatically be used when you use {@link android.widget.ImageView} in your
  * layouts. You should only need to manually use this class when writing custom views.</p>
  */
-public class AppCompatImageView extends ImageView implements TintableBackgroundView {
+public class AppCompatImageView extends ImageView implements TintableBackgroundView,
+        TintableImageSourceView {
 
-    private AppCompatBackgroundHelper mBackgroundTintHelper;
-    private AppCompatImageHelper mImageHelper;
+    private final AppCompatBackgroundHelper mBackgroundTintHelper;
+    private final AppCompatImageHelper mImageHelper;
 
     public AppCompatImageView(Context context) {
         this(context, null);
@@ -77,8 +87,42 @@
      */
     @Override
     public void setImageResource(@DrawableRes int resId) {
-        // Intercept this call and instead retrieve the Drawable via the image helper
-        mImageHelper.setImageResource(resId);
+        if (mImageHelper != null) {
+            // Intercept this call and instead retrieve the Drawable via the image helper
+            mImageHelper.setImageResource(resId);
+        }
+    }
+
+    @Override
+    public void setImageDrawable(@Nullable Drawable drawable) {
+        super.setImageDrawable(drawable);
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
+    }
+
+    @Override
+    public void setImageBitmap(Bitmap bm) {
+        super.setImageBitmap(bm);
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
+    }
+
+    @Override
+    public void setImageIcon(@Nullable Icon icon) {
+        super.setImageIcon(icon);
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
+    }
+
+    @Override
+    public void setImageURI(@Nullable Uri uri) {
+        super.setImageURI(uri);
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
     }
 
     @Override
@@ -153,12 +197,71 @@
                 ? mBackgroundTintHelper.getSupportBackgroundTintMode() : null;
     }
 
+    /**
+     * This should be accessed via
+     * {@link android.support.v4.widget.ImageViewCompat#setImageTintList(ImageView, ColorStateList)}
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    public void setSupportImageTintList(@Nullable ColorStateList tint) {
+        if (mImageHelper != null) {
+            mImageHelper.setSupportImageTintList(tint);
+        }
+    }
+
+    /**
+     * This should be accessed via
+     * {@link android.support.v4.widget.ImageViewCompat#getImageTintList(ImageView)}
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    @Nullable
+    public ColorStateList getSupportImageTintList() {
+        return mImageHelper != null
+                ? mImageHelper.getSupportImageTintList() : null;
+    }
+
+    /**
+     * This should be accessed via
+     * {@link android.support.v4.widget.ImageViewCompat#setImageTintMode(ImageView, PorterDuff.Mode)}
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    public void setSupportImageTintMode(@Nullable PorterDuff.Mode tintMode) {
+        if (mImageHelper != null) {
+            mImageHelper.setSupportImageTintMode(tintMode);
+        }
+    }
+
+    /**
+     * This should be accessed via
+     * {@link android.support.v4.widget.ImageViewCompat#getImageTintMode(ImageView)}
+     *
+     * @hide
+     */
+    @RestrictTo(LIBRARY_GROUP)
+    @Override
+    @Nullable
+    public PorterDuff.Mode getSupportImageTintMode() {
+        return mImageHelper != null
+                ? mImageHelper.getSupportImageTintMode() : null;
+    }
+
     @Override
     protected void drawableStateChanged() {
         super.drawableStateChanged();
         if (mBackgroundTintHelper != null) {
             mBackgroundTintHelper.applySupportBackgroundTint();
         }
+        if (mImageHelper != null) {
+            mImageHelper.applySupportImageTint();
+        }
     }
 
     public boolean hasOverlappingRendering() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
index 381169d..8060d7d 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
@@ -37,7 +37,7 @@
  * <ul>
  *     <li>Supports {@link R.attr#textAllCaps} style attribute which works back to
  *     {@link android.os.Build.VERSION_CODES#GINGERBREAD Gingerbread}.</li>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.view.ViewCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
  *     {@link R.attr#backgroundTintMode}.</li>
@@ -53,8 +53,8 @@
             android.R.attr.popupBackground
     };
 
-    private AppCompatBackgroundHelper mBackgroundTintHelper;
-    private AppCompatTextHelper mTextHelper;
+    private final AppCompatBackgroundHelper mBackgroundTintHelper;
+    private final AppCompatTextHelper mTextHelper;
 
     public AppCompatMultiAutoCompleteTextView(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java b/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java
index 768d610..8aa22f3 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java
@@ -35,7 +35,7 @@
  * A {@link RadioButton} which supports compatible features on older version of the platform,
  * including:
  * <ul>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.widget.CompoundButtonCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#buttonTint} and
  *     {@link R.attr#buttonTintMode}.</li>
@@ -46,7 +46,7 @@
  */
 public class AppCompatRadioButton extends RadioButton implements TintableCompoundButton {
 
-    private AppCompatCompoundButtonHelper mCompoundButtonHelper;
+    private final AppCompatCompoundButtonHelper mCompoundButtonHelper;
 
     public AppCompatRadioButton(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java b/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java
index afaa02a..762e97a 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatRatingBar.java
@@ -31,7 +31,7 @@
  */
 public class AppCompatRatingBar extends RatingBar {
 
-    private AppCompatProgressBarHelper mAppCompatProgressBarHelper;
+    private final AppCompatProgressBarHelper mAppCompatProgressBarHelper;
 
     public AppCompatRatingBar(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java b/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java
index bac1cb8..8b476b8 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatSeekBar.java
@@ -32,7 +32,7 @@
  */
 public class AppCompatSeekBar extends SeekBar {
 
-    private AppCompatSeekBarHelper mAppCompatSeekBarHelper;
+    private final AppCompatSeekBarHelper mAppCompatSeekBarHelper;
 
     public AppCompatSeekBar(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java b/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java
index 9f27f78..1be8ed8 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java
@@ -55,11 +55,11 @@
  * A {@link Spinner} which supports compatible features on older versions of the platform,
  * including:
  * <ul>
- * <li>Dynamic tinting of the background via the background tint methods in
- * {@link android.support.v4.view.ViewCompat}.</li>
- * <li>Configuring the background tint using {@link R.attr#backgroundTint} and
- * {@link R.attr#backgroundTintMode}.</li>
- * <li>Setting the popup theme using {@link R.attr#popupTheme}.</li>
+ *     <li>Allows dynamic tint of its background via the background tint methods in
+ *     {@link android.support.v4.widget.CompoundButtonCompat}.</li>
+ *     <li>Allows setting of the background tint using {@link R.attr#buttonTint} and
+ *     {@link R.attr#buttonTintMode}.</li>
+ *     <li>Setting the popup theme using {@link R.attr#popupTheme}.</li>
  * </ul>
  *
  * <p>This will automatically be used when you use {@link Spinner} in your layouts.
@@ -77,10 +77,10 @@
     private static final int MODE_DROPDOWN = 1;
     private static final int MODE_THEME = -1;
 
-    private AppCompatBackgroundHelper mBackgroundTintHelper;
+    private final AppCompatBackgroundHelper mBackgroundTintHelper;
 
     /** Context used to inflate the popup window or dialog. */
-    private Context mPopupContext;
+    private final Context mPopupContext;
 
     /** Forwarding listener used to implement drag-to-open. */
     private ForwardingListener mForwardingListener;
@@ -88,13 +88,13 @@
     /** Temporary holder for setAdapter() calls from the super constructor. */
     private SpinnerAdapter mTempAdapter;
 
-    private boolean mPopupSet;
+    private final boolean mPopupSet;
 
-    DropdownPopup mPopup;
+    private DropdownPopup mPopup;
 
-    int mDropDownWidth;
+    private int mDropDownWidth;
 
-    final Rect mTempRect = new Rect();
+    private final Rect mTempRect = new Rect();
 
     /**
      * Construct a new spinner with the given context's theme.
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java
index 66fd929..96dfd5a 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java
@@ -36,7 +36,7 @@
  * <ul>
  *     <li>Supports {@link R.attr#textAllCaps} style attribute which works back to
  *     {@link android.os.Build.VERSION_CODES#GINGERBREAD Gingerbread}.</li>
- *     <li>Allows dynamic tint of it background via the background tint methods in
+ *     <li>Allows dynamic tint of its background via the background tint methods in
  *     {@link android.support.v4.view.ViewCompat}.</li>
  *     <li>Allows setting of the background tint using {@link R.attr#backgroundTint} and
  *     {@link R.attr#backgroundTintMode}.</li>
@@ -47,8 +47,8 @@
  */
 public class AppCompatTextView extends TextView implements TintableBackgroundView {
 
-    private AppCompatBackgroundHelper mBackgroundTintHelper;
-    private AppCompatTextHelper mTextHelper;
+    private final AppCompatBackgroundHelper mBackgroundTintHelper;
+    private final AppCompatTextHelper mTextHelper;
 
     public AppCompatTextView(Context context) {
         this(context, null);
diff --git a/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java b/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
index 048f2b6..732cbf5 100644
--- a/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
@@ -48,6 +48,8 @@
 
     private int mLastWidthSize = -1;
 
+    private int mMinimumHeight = 0;
+
     public ButtonBarLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
         final boolean allowStackingDefault =
@@ -162,6 +164,11 @@
         return -1;
     }
 
+    @Override
+    public int getMinimumHeight() {
+        return Math.max(mMinimumHeight, super.getMinimumHeight());
+    }
+
     private void setStacked(boolean stacked) {
         setOrientation(stacked ? LinearLayout.VERTICAL : LinearLayout.HORIZONTAL);
         setGravity(stacked ? Gravity.RIGHT : Gravity.BOTTOM);
diff --git a/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java b/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java
index a6ddb34..c363301 100644
--- a/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java
+++ b/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java
@@ -938,6 +938,7 @@
      * @return true if the event was handled, false if it was ignored.
      *
      * @see #setModal(boolean)
+     * @see #onKeyUp(int, KeyEvent)
      */
     public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
         // when the drop down is shown, we drive it directly
@@ -1033,6 +1034,7 @@
      * @return true if the event was handled, false if it was ignored.
      *
      * @see #setModal(boolean)
+     * @see #onKeyDown(int, KeyEvent)
      */
     public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
         if (isShowing() && mDropDownList.getSelectedItemPosition() >= 0) {
diff --git a/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java b/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java
index 9f2975f..24dafb3 100644
--- a/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java
+++ b/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java
@@ -110,7 +110,7 @@
      * copied to the query text field.
      * <p>
      *
-     * @param refine which queries to refine. Possible values are {@link #REFINE_NONE},
+     * @param refineWhat which queries to refine. Possible values are {@link #REFINE_NONE},
      * {@link #REFINE_BY_ENTRY}, and {@link #REFINE_ALL}.
      */
     public void setQueryRefinement(int refineWhat) {
@@ -461,6 +461,29 @@
     }
 
     /**
+     * This method is overridden purely to provide a bit of protection against
+     * flaky content providers.
+     *
+     * @see android.widget.CursorAdapter#getDropDownView(int, View, ViewGroup)
+     */
+    @Override
+    public View getDropDownView(int position, View convertView, ViewGroup parent) {
+        try {
+            return super.getDropDownView(position, convertView, parent);
+        } catch (RuntimeException e) {
+            Log.w(LOG_TAG, "Search suggestions cursor threw exception.", e);
+            // Put exception string in item title
+            final View v = newDropDownView(mContext, mCursor, parent);
+            if (v != null) {
+                final ChildViewCache views = (ChildViewCache) v.getTag();
+                final TextView tv = views.mText1;
+                tv.setText(e.toString());
+            }
+            return v;
+        }
+    }
+
+    /**
      * Gets a drawable given a value provided by a suggestion provider.
      *
      * This value could be just the string value of a resource id
diff --git a/v7/appcompat/src/android/support/v7/widget/Toolbar.java b/v7/appcompat/src/android/support/v7/widget/Toolbar.java
index 8687292..fc5f1f1 100644
--- a/v7/appcompat/src/android/support/v7/widget/Toolbar.java
+++ b/v7/appcompat/src/android/support/v7/widget/Toolbar.java
@@ -2174,6 +2174,17 @@
     }
 
     /**
+     * Accessor to enable LayoutLib to get ActionMenuPresenter directly.
+     */
+    ActionMenuPresenter getOuterActionMenuPresenter() {
+        return mOuterActionMenuPresenter;
+    }
+
+    Context getPopupContext() {
+        return mPopupContext;
+    }
+
+    /**
      * Interface responsible for receiving menu item click events if the items themselves
      * do not have individual item click listeners.
      */
diff --git a/v7/appcompat/tests/AndroidManifest.xml b/v7/appcompat/tests/AndroidManifest.xml
index 7385a5f..14413a2 100644
--- a/v7/appcompat/tests/AndroidManifest.xml
+++ b/v7/appcompat/tests/AndroidManifest.xml
@@ -75,6 +75,11 @@
                 android:theme="@style/Theme.TextColors" />
 
         <activity
+                android:name="android.support.v7.widget.AppCompatImageButtonActivity"
+                android:label="@string/app_compat_image_button_activity"
+                android:theme="@style/Theme.AppCompat.Light" />
+
+        <activity
                 android:name="android.support.v7.widget.AppCompatImageViewActivity"
                 android:label="@string/app_compat_image_view_activity"
                 android:theme="@style/Theme.AppCompat.Light" />
diff --git a/v7/appcompat/tests/res/layout/appcompat_imagebutton_activity.xml b/v7/appcompat/tests/res/layout/appcompat_imagebutton_activity.xml
new file mode 100755
index 0000000..4be0ee0
--- /dev/null
+++ b/v7/appcompat/tests/res/layout/appcompat_imagebutton_activity.xml
@@ -0,0 +1,88 @@
+<?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.
+-->
+
+<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">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+
+        <android.support.v7.widget.AppCompatImageButton
+            android:id="@+id/view_tinted_no_background"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@null"
+            android:src="@drawable/test_drawable_blue"
+            app:backgroundTint="@color/color_state_list_lilac"
+            app:backgroundTintMode="src_in"/>
+
+        <android.support.v7.widget.AppCompatImageButton
+            android:id="@+id/view_tinted_background"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@drawable/test_drawable"
+            android:src="@drawable/test_drawable_blue"
+            app:backgroundTint="@color/color_state_list_lilac"
+            app:backgroundTintMode="src_in"/>
+
+        <android.support.v7.widget.AppCompatImageButton
+            android:id="@+id/view_untinted_no_background"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@null"
+            android:src="@drawable/test_drawable_blue"/>
+
+        <android.support.v7.widget.AppCompatImageButton
+            android:id="@+id/view_untinted_background"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@drawable/test_background_green"
+            android:src="@drawable/test_drawable_blue"/>
+
+        <android.support.v7.widget.AppCompatImageButton
+            android:id="@+id/view_tinted_source"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/test_drawable_blue"
+            app:tint="@color/color_state_list_lilac"
+            app:tintMode="src_in"/>
+
+        <android.support.v7.widget.AppCompatImageButton
+            android:id="@+id/view_tinted_no_source"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:tint="@color/color_state_list_lilac"
+            app:tintMode="src_in"/>
+
+        <android.support.v7.widget.AppCompatImageButton
+            android:id="@+id/view_untinted_source"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/test_drawable_blue"/>
+
+        <android.support.v7.widget.AppCompatImageButton
+            android:id="@+id/view_untinted_no_source"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
+
+    </LinearLayout>
+
+</ScrollView>
diff --git a/v7/appcompat/tests/res/layout/appcompat_imageview_activity.xml b/v7/appcompat/tests/res/layout/appcompat_imageview_activity.xml
index c2aa5ed..b8af1b2 100644
--- a/v7/appcompat/tests/res/layout/appcompat_imageview_activity.xml
+++ b/v7/appcompat/tests/res/layout/appcompat_imageview_activity.xml
@@ -56,11 +56,44 @@
             android:background="@drawable/test_background_green" />
 
         <android.support.v7.widget.AppCompatImageView
-                android:id="@+id/view_android_src_srccompat"
-                android:layout_width="30dp"
-                android:layout_height="30dp"
-                android:src="@drawable/test_drawable_blue"
-                app:srcCompat="@drawable/test_drawable_red" />
+            android:id="@+id/view_android_src_srccompat"
+            android:layout_width="30dp"
+            android:layout_height="30dp"
+            android:src="@drawable/test_drawable_blue"
+            app:srcCompat="@drawable/test_drawable_red" />
+
+        <android.support.v7.widget.AppCompatImageView
+            android:id="@+id/view_tinted_source"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/test_drawable_blue"
+            app:tint="@color/color_state_list_lilac"
+            app:tintMode="src_in" />
+
+        <android.support.v7.widget.AppCompatImageView
+            android:id="@+id/view_tinted_no_source"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:tint="@color/color_state_list_lilac"
+            app:tintMode="src_in" />
+
+        <android.support.v7.widget.AppCompatImageView
+            android:id="@+id/view_untinted_source"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:src="@drawable/test_drawable_blue" />
+
+        <android.support.v7.widget.AppCompatImageView
+            android:id="@+id/view_untinted_no_source"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <android.support.v7.widget.AppCompatImageView
+            android:id="@+id/view_tinted_android_src_srccompat"
+            android:layout_width="30dp"
+            android:layout_height="30dp"
+            android:src="@drawable/test_drawable_blue"
+            app:srcCompat="@drawable/test_drawable_red" />
 
     </LinearLayout>
 
diff --git a/v7/appcompat/tests/res/menu/sample_actions.xml b/v7/appcompat/tests/res/menu/sample_actions.xml
index 68882bd..a854fd2 100644
--- a/v7/appcompat/tests/res/menu/sample_actions.xml
+++ b/v7/appcompat/tests/res/menu/sample_actions.xml
@@ -19,7 +19,7 @@
     <item android:id="@+id/action_search"
           android:title="@string/search_menu_title"
           app:showAsAction="always|collapseActionView"
-          app:actionViewClass="android.support.v7.widget.SearchView"/>
+          app:actionViewClass="android.support.v7.app.CustomCollapsibleView"/>
 
     <item android:id="@+id/action_alpha_shortcut"
           android:title="Alpha"
diff --git a/v7/appcompat/tests/res/values/strings.xml b/v7/appcompat/tests/res/values/strings.xml
index 812bd61..926418a 100644
--- a/v7/appcompat/tests/res/values/strings.xml
+++ b/v7/appcompat/tests/res/values/strings.xml
@@ -53,6 +53,7 @@
     <string name="app_compat_text_view_activity">AppCompat text view</string>
     <string name="sample_text1">Sample text 1</string>
     <string name="sample_text2">Sample text 2</string>
+    <string name="app_compat_image_button_activity">AppCompat image button</string>
     <string name="app_compat_image_view_activity">AppCompat image view</string>
     <string name="app_compat_button_activity">AppCompat button</string>
     <string-array name="planets_array">
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 844f527..5afbab5 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/BaseKeyEventsTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/BaseKeyEventsTestCase.java
@@ -21,18 +21,16 @@
 import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist;
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
 import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
 import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
-import static android.support.test.espresso.matcher.ViewMatchers.withId;
 
 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.support.test.filters.FlakyTest;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.SmallTest;
-import android.support.test.filters.Suppress;
 import android.support.v7.appcompat.test.R;
 import android.support.v7.testutils.BaseTestActivity;
 import android.support.v7.view.ActionMode;
@@ -40,6 +38,7 @@
 import android.view.Menu;
 import android.view.MenuItem;
 
+import org.hamcrest.Matchers;
 import org.junit.Test;
 
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -92,30 +91,29 @@
         assertTrue("ActionMode was destroyed", destroyed.get());
     }
 
-    @Suppress
-    @FlakyTest(bugId = 34956766)
     @Test
     @LargeTest
-    public void testBackCollapsesSearchView() throws InterruptedException {
+    public void testBackCollapsesActionView() throws InterruptedException {
         final String itemTitle = getActivity().getString(R.string.search_menu_title);
 
         // Click on the Search menu item
         onView(withContentDescription(itemTitle)).perform(click());
-        // Check that the SearchView is displayed
-        onView(withId(R.id.search_bar)).check(matches(isDisplayed()));
+        // Check that the action view is displayed (expanded)
+        onView(withClassName(Matchers.is(CustomCollapsibleView.class.getName())))
+                .check(matches(isDisplayed()));
 
-        // Wait for the IME to show
+        // Let things settle
         getInstrumentation().waitForIdleSync();
-        // Now send a back event to dismiss the IME
+        // Now send a back event to collapse the custom action view
         getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
-        // ...and another to collapse the SearchView
-        getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
+        getInstrumentation().waitForIdleSync();
 
         // Check that the Activity is still running
         assertFalse(getActivity().isFinishing());
         assertFalse(getActivity().isDestroyed());
-        // ...and that the SearchView is not attached
-        onView(withId(R.id.search_bar)).check(doesNotExist());
+        // ... and that our action view is not attached
+        onView(withClassName(Matchers.is(CustomCollapsibleView.class.getName())))
+                .check(doesNotExist());
     }
 
     @Test
diff --git a/v7/appcompat/tests/src/android/support/v7/app/CustomCollapsibleView.java b/v7/appcompat/tests/src/android/support/v7/app/CustomCollapsibleView.java
new file mode 100644
index 0000000..27e6f8a
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/app/CustomCollapsibleView.java
@@ -0,0 +1,48 @@
+/*
+ * 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.app;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.support.v7.view.CollapsibleActionView;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class CustomCollapsibleView extends View implements CollapsibleActionView {
+    public CustomCollapsibleView(Context context) {
+        this(context, null, 0);
+    }
+
+    public CustomCollapsibleView(Context context,
+            @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CustomCollapsibleView(Context context,
+            @Nullable AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        setBackgroundColor(0xFFFF0000);
+    }
+
+    @Override
+    public void onActionViewExpanded() {
+    }
+
+    @Override
+    public void onActionViewCollapsed() {
+    }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/testutils/AppCompatTintableViewActions.java b/v7/appcompat/tests/src/android/support/v7/testutils/AppCompatTintableViewActions.java
index de36207..357de5c 100644
--- a/v7/appcompat/tests/src/android/support/v7/testutils/AppCompatTintableViewActions.java
+++ b/v7/appcompat/tests/src/android/support/v7/testutils/AppCompatTintableViewActions.java
@@ -16,26 +16,28 @@
 
 package android.support.v7.testutils;
 
+import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
+
+import static org.hamcrest.core.AllOf.allOf;
+import static org.hamcrest.core.AnyOf.anyOf;
+
 import android.content.res.ColorStateList;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.test.espresso.UiController;
 import android.support.test.espresso.ViewAction;
-import android.support.v4.view.TintableBackgroundView;
 import android.support.v4.view.ViewCompat;
-import android.support.v7.widget.AppCompatTextView;
+import android.support.v4.widget.ImageViewCompat;
 import android.view.View;
-import org.hamcrest.Matcher;
+import android.widget.ImageView;
 
-import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
-import static android.support.test.espresso.matcher.ViewMatchers.isDisplayingAtLeast;
-import static org.hamcrest.core.AllOf.allOf;
+import org.hamcrest.Matcher;
 
 public class AppCompatTintableViewActions {
     /**
-     * Sets the passed color state list as the background layer on a {@link View}.
+     * Sets the passed color state list as the background tint on a {@link View}.
      */
     public static ViewAction setBackgroundTintList(final ColorStateList tint) {
         return new ViewAction() {
@@ -87,6 +89,58 @@
     }
 
     /**
+     * Sets the passed color state list as the image source tint on a {@link View}.
+     */
+    public static ViewAction setImageSourceTintList(final ColorStateList tint) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return anyOf(isAssignableFrom(ImageView.class));
+            }
+
+            @Override
+            public String getDescription() {
+                return "set image source tint list";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                ImageViewCompat.setImageTintList((ImageView) view, tint);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    /**
+     * Sets the passed mode as the image source tint mode on a <code>View</code>.
+     */
+    public static ViewAction setImageSourceTintMode(final PorterDuff.Mode mode) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return anyOf(isAssignableFrom(ImageView.class));
+            }
+
+            @Override
+            public String getDescription() {
+                return "set image source tint mode";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                ImageViewCompat.setImageTintMode((ImageView) view, mode);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
+
+    /**
      * Sets background drawable on a <code>View</code> that implements the
      * <code>TintableBackgroundView</code> interface.
      */
@@ -140,4 +194,32 @@
         };
     }
 
+    /**
+     * Sets image resource on a <code>View</code> that implements the
+     * <code>TintableBackgroundView</code> interface and also extends the
+     * <code>ImageView</code> base class.
+     */
+    public static ViewAction setImageResource(final @DrawableRes int resId) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return allOf(TestUtilsMatchers.isTintableBackgroundView(),
+                        isAssignableFrom(ImageView.class));
+            }
+
+            @Override
+            public String getDescription() {
+                return "set image resource";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                ((ImageView) view).setImageResource(resId);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
 }
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseImageViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseImageViewTest.java
new file mode 100755
index 0000000..c8398ed
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseImageViewTest.java
@@ -0,0 +1,421 @@
+/*
+ * 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 android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.v7.testutils.TestUtilsActions.setEnabled;
+
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorInt;
+import android.support.annotation.IdRes;
+import android.support.annotation.NonNull;
+import android.support.test.filters.SmallTest;
+import android.support.v4.content.res.ResourcesCompat;
+import android.support.v4.graphics.ColorUtils;
+import android.support.v7.appcompat.test.R;
+import android.support.v7.testutils.AppCompatTintableViewActions;
+import android.support.v7.testutils.BaseTestActivity;
+import android.support.v7.testutils.TestUtils;
+import android.widget.ImageView;
+
+import org.junit.Test;
+
+/**
+ * In addition to all tinting-related tests done by the base class, this class provides
+ * testing for tinting image resources on appcompat-v7 view classes that extend directly
+ * or indirectly the core {@link ImageView} class.
+ */
+public abstract class AppCompatBaseImageViewTest<T extends ImageView>
+        extends AppCompatBaseViewTest<BaseTestActivity, T> {
+    public AppCompatBaseImageViewTest(Class clazz) {
+        super(clazz);
+    }
+
+    private void verifyImageSourceIsColoredAs(String description, @NonNull ImageView imageView,
+            @ColorInt int color, int allowedComponentVariance) {
+        Drawable imageSource = imageView.getDrawable();
+        TestUtils.assertAllPixelsOfColor(description,
+                imageSource, imageSource.getIntrinsicWidth(), imageSource.getIntrinsicHeight(),
+                true, color, allowedComponentVariance, false);
+    }
+
+    /**
+     * This method tests that image tinting is applied to tintable image view
+     * in enabled and disabled state across a number of <code>ColorStateList</code>s set as
+     * image source tint lists on the same image source.
+     */
+    @Test
+    @SmallTest
+    public void testImageTintingAcrossStateChange() {
+        final @IdRes int viewId = R.id.view_tinted_source;
+        final Resources res = getActivity().getResources();
+        final T view = (T) mContainer.findViewById(viewId);
+
+        @ColorInt int lilacDefault = ResourcesCompat.getColor(res, R.color.lilac_default, null);
+        @ColorInt int lilacDisabled = ResourcesCompat.getColor(res, R.color.lilac_disabled, null);
+        @ColorInt int sandDefault = ResourcesCompat.getColor(res, R.color.sand_default, null);
+        @ColorInt int sandDisabled = ResourcesCompat.getColor(res, R.color.sand_disabled, null);
+        @ColorInt int oceanDefault = ResourcesCompat.getColor(res, R.color.ocean_default, null);
+        @ColorInt int oceanDisabled = ResourcesCompat.getColor(res, R.color.ocean_disabled, null);
+
+        // Test the default state for tinting set up in the layout XML file.
+        verifyImageSourceIsColoredAs("Default lilac tinting in enabled state", view,
+                lilacDefault, 0);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in the default color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("Default lilac tinting in disabled state", view,
+                lilacDisabled, 0);
+
+        // Enable the view and check that the image has switched to the matching entry
+        // in the default color state list.
+        onView(withId(viewId)).perform(setEnabled(true));
+        verifyImageSourceIsColoredAs("Default lilac tinting in re-enabled state", view,
+                lilacDefault, 0);
+
+        // Load a new color state list, set it on the view and check that the image has
+        // switched to the matching entry in newly set color state list.
+        final ColorStateList sandColor = ResourcesCompat.getColorStateList(
+                res, R.color.color_state_list_sand, null);
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintList(sandColor));
+        verifyImageSourceIsColoredAs("New sand tinting in enabled state", view,
+                sandDefault, 0);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in the newly set color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("New sand tinting in disabled state", view,
+                sandDisabled, 0);
+
+        // Enable the view and check that the image has switched to the matching entry
+        // in the newly set color state list.
+        onView(withId(viewId)).perform(setEnabled(true));
+        verifyImageSourceIsColoredAs("New sand tinting in re-enabled state", view,
+                sandDefault, 0);
+
+        // Load another color state list, set it on the view and check that the image has
+        // switched to the matching entry in newly set color state list.
+        final ColorStateList oceanColor = ResourcesCompat.getColorStateList(
+                res, R.color.color_state_list_ocean, null);
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintList(oceanColor));
+        verifyImageSourceIsColoredAs("New ocean tinting in enabled state", view,
+                oceanDefault, 0);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in the newly set color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("New ocean tinting in disabled state", view,
+                oceanDisabled, 0);
+
+        // Enable the view and check that the image has switched to the matching entry
+        // in the newly set color state list.
+        onView(withId(viewId)).perform(setEnabled(true));
+        verifyImageSourceIsColoredAs("New ocean tinting in re-enabled state", view,
+                oceanDefault, 0);
+    }
+
+    /**
+     * This method tests that image tinting is applied to tintable image view
+     * in enabled and disabled state across the same image source respects the currently set
+     * image source tinting mode.
+     */
+    @Test
+    @SmallTest
+    public void testImageTintingAcrossModeChange() {
+        final @IdRes int viewId = R.id.view_untinted_source;
+        final Resources res = getActivity().getResources();
+        final T view = (T) mContainer.findViewById(viewId);
+
+        @ColorInt int emeraldDefault = ResourcesCompat.getColor(
+                res, R.color.emerald_translucent_default, null);
+        @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
+                res, R.color.emerald_translucent_disabled, null);
+        // This is the fill color of R.drawable.test_drawable_blue set on our view
+        // that we'll be testing in this method
+        @ColorInt int sourceColor = ResourcesCompat.getColor(
+                res, R.color.test_blue, null);
+
+        // Test the default state for tinting set up in the layout XML file.
+        verifyImageSourceIsColoredAs("Default no tinting in enabled state", view,
+                sourceColor, 0);
+
+        // From this point on in this method we're allowing a margin of error in checking the
+        // color of the image source. This is due to both translucent colors being used
+        // in the color state list and off-by-one discrepancies of SRC_OVER when it's compositing
+        // translucent color on top of solid fill color. This is where the allowed variance
+        // value of 2 comes from - one for compositing and one for color translucency.
+        final int allowedComponentVariance = 2;
+
+        // Set src_in tint mode on our view
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintMode(PorterDuff.Mode.SRC_IN));
+
+        // Load a new color state list, set it on the view and check that the image has
+        // switched to the matching entry in newly set color state list.
+        final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
+                res, R.color.color_state_list_emerald_translucent, null);
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintList(emeraldColor));
+        verifyImageSourceIsColoredAs("New emerald tinting in enabled state under src_in", view,
+                emeraldDefault, allowedComponentVariance);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in the newly set color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("New emerald tinting in disabled state under src_in", view,
+                emeraldDisabled, allowedComponentVariance);
+
+        // Set src_over tint mode on our view. As the currently set tint list is using
+        // translucent colors, we expect the actual image source of the view to be different under
+        // this new mode (unlike src_in and src_over that behave identically when the destination is
+        // a fully filled rectangle and the source is an opaque color).
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintMode(PorterDuff.Mode.SRC_OVER));
+
+        // Enable the view and check that the image has switched to the matching entry
+        // in the color state list.
+        onView(withId(viewId)).perform(setEnabled(true));
+        verifyImageSourceIsColoredAs("New emerald tinting in enabled state under src_over", view,
+                ColorUtils.compositeColors(emeraldDefault, sourceColor),
+                allowedComponentVariance);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in the newly set color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("New emerald tinting in disabled state under src_over",
+                view, ColorUtils.compositeColors(emeraldDisabled, sourceColor),
+                allowedComponentVariance);
+    }
+
+    /**
+     * This method tests that opaque tinting applied to tintable image source
+     * is applied correctly after changing the image source itself.
+     */
+    @Test
+    @SmallTest
+    public void testImageOpaqueTintingAcrossImageChange() {
+        final @IdRes int viewId = R.id.view_tinted_no_source;
+        final Resources res = getActivity().getResources();
+        final T view = (T) mContainer.findViewById(viewId);
+
+        @ColorInt int lilacDefault = ResourcesCompat.getColor(res, R.color.lilac_default, null);
+        @ColorInt int lilacDisabled = ResourcesCompat.getColor(res, R.color.lilac_disabled, null);
+
+        // Set image source on our view
+        onView(withId(viewId)).perform(AppCompatTintableViewActions.setImageResource(
+                R.drawable.test_drawable_green));
+
+        // Test the default state for tinting set up in the layout XML file.
+        verifyImageSourceIsColoredAs("Default lilac tinting in enabled state on green source",
+                view, lilacDefault, 0);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in the default color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("Default lilac tinting in disabled state on green source",
+                view, lilacDisabled, 0);
+
+        // Enable the view and check that the image has switched to the matching entry
+        // in the default color state list.
+        onView(withId(viewId)).perform(setEnabled(true));
+        verifyImageSourceIsColoredAs("Default lilac tinting in re-enabled state on green source",
+                view, lilacDefault, 0);
+
+        // Set a different image source on our view based on resource ID
+        onView(withId(viewId)).perform(AppCompatTintableViewActions.setImageResource(
+                R.drawable.test_drawable_red));
+
+        // Test the default state for tinting set up in the layout XML file.
+        verifyImageSourceIsColoredAs("Default lilac tinting in enabled state on red source",
+                view, lilacDefault, 0);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in the default color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("Default lilac tinting in disabled state on red source",
+                view, lilacDisabled, 0);
+
+        // Enable the view and check that the image has switched to the matching entry
+        // in the default color state list.
+        onView(withId(viewId)).perform(setEnabled(true));
+        verifyImageSourceIsColoredAs("Default lilac tinting in re-enabled state on red source",
+                view, lilacDefault, 0);
+    }
+
+    /**
+     * This method tests that translucent tinting applied to tintable image source
+     * is applied correctly after changing the image source itself.
+     */
+    @Test
+    @SmallTest
+    public void testImageTranslucentTintingAcrossImageChange() {
+        final @IdRes int viewId = R.id.view_untinted_no_source;
+        final Resources res = getActivity().getResources();
+        final T view = (T) mContainer.findViewById(viewId);
+
+        @ColorInt int emeraldDefault = ResourcesCompat.getColor(
+                res, R.color.emerald_translucent_default, null);
+        @ColorInt int emeraldDisabled = ResourcesCompat.getColor(
+                res, R.color.emerald_translucent_disabled, null);
+        // This is the fill color of R.drawable.test_drawable_green that will be set on our view
+        // that we'll be testing in this method
+        @ColorInt int colorGreen = ResourcesCompat.getColor(
+                res, R.color.test_green, null);
+        // This is the fill color of R.drawable.test_drawable_red that will be set on our view
+        // that we'll be testing in this method
+        @ColorInt int colorRed = ResourcesCompat.getColor(
+                res, R.color.test_red, null);
+
+        // Set src_over tint mode on our view. As the currently set tint list is using
+        // translucent colors, we expect the actual image source of the view to be different under
+        // this new mode (unlike src_in and src_over that behave identically when the destination is
+        // a fully filled rectangle and the source is an opaque color).
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintMode(PorterDuff.Mode.SRC_OVER));
+        // Load and set a translucent color state list as the image source tint list
+        final ColorStateList emeraldColor = ResourcesCompat.getColorStateList(
+                res, R.color.color_state_list_emerald_translucent, null);
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintList(emeraldColor));
+
+        // Set image source on our view
+        onView(withId(viewId)).perform(AppCompatTintableViewActions.setImageResource(
+                R.drawable.test_drawable_green));
+
+        // From this point on in this method we're allowing a margin of error in checking the
+        // color of the image source. This is due to both translucent colors being used
+        // in the color state list and off-by-one discrepancies of SRC_OVER when it's compositing
+        // translucent color on top of solid fill color. This is where the allowed variance
+        // value of 2 comes from - one for compositing and one for color translucency.
+        final int allowedComponentVariance = 2;
+
+        // Test the default state for tinting set up with the just loaded tint list.
+        verifyImageSourceIsColoredAs("Emerald tinting in enabled state on green source",
+                view, ColorUtils.compositeColors(emeraldDefault, colorGreen),
+                allowedComponentVariance);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in the default color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("Emerald tinting in disabled state on green source",
+                view, ColorUtils.compositeColors(emeraldDisabled, colorGreen),
+                allowedComponentVariance);
+
+        // Enable the view and check that the image has switched to the matching entry
+        // in the default color state list.
+        onView(withId(viewId)).perform(setEnabled(true));
+        verifyImageSourceIsColoredAs("Emerald tinting in re-enabled state on green source",
+                view, ColorUtils.compositeColors(emeraldDefault, colorGreen),
+                allowedComponentVariance);
+
+        // Set a different image source on our view based on resource ID
+        onView(withId(viewId)).perform(AppCompatTintableViewActions.setImageResource(
+                R.drawable.test_drawable_red));
+
+        // Test the default state for tinting the new image with the same color state list
+        verifyImageSourceIsColoredAs("Emerald tinting in enabled state on red source",
+                view, ColorUtils.compositeColors(emeraldDefault, colorRed),
+                allowedComponentVariance);
+
+        // Disable the view and check that the image has switched to the matching entry
+        // in our current color state list.
+        onView(withId(viewId)).perform(setEnabled(false));
+        verifyImageSourceIsColoredAs("Emerald tinting in disabled state on red source",
+                view, ColorUtils.compositeColors(emeraldDisabled, colorRed),
+                allowedComponentVariance);
+
+        // Enable the view and check that the image has switched to the matching entry
+        // in our current color state list.
+        onView(withId(viewId)).perform(setEnabled(true));
+        verifyImageSourceIsColoredAs("Emerald tinting in re-enabled state on red source",
+                view, ColorUtils.compositeColors(emeraldDefault, colorRed),
+                allowedComponentVariance);
+    }
+
+    /**
+     * This method tests that background tinting applied on a tintable image view does not
+     * affect the tinting of the image source.
+     */
+    @Test
+    @SmallTest
+    public void testImageTintingAcrossBackgroundTintingChange() {
+        final @IdRes int viewId = R.id.view_untinted_source;
+        final Resources res = getActivity().getResources();
+        final T view = (T) mContainer.findViewById(viewId);
+
+        @ColorInt int lilacDefault = ResourcesCompat.getColor(res, R.color.lilac_default, null);
+        @ColorInt int lilacDisabled = ResourcesCompat.getColor(res, R.color.lilac_disabled, null);
+        // This is the fill color of R.drawable.test_drawable_blue set on our view
+        // that we'll be testing in this method
+        @ColorInt int sourceColor = ResourcesCompat.getColor(
+                res, R.color.test_blue, null);
+        @ColorInt int newSourceColor = ResourcesCompat.getColor(
+                res, R.color.test_red, null);
+
+        // Test the default state for tinting set up in the layout XML file.
+        verifyImageSourceIsColoredAs("Default no tinting in enabled state", view,
+                sourceColor, 0);
+
+        // Change background tinting of our image
+        final ColorStateList lilacColor = ResourcesCompat.getColorStateList(
+                mResources, R.color.color_state_list_lilac, null);
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setBackgroundResource(
+                        R.drawable.test_background_green));
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setBackgroundTintMode(PorterDuff.Mode.SRC_IN));
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setBackgroundTintList(lilacColor));
+
+        // Verify that the image still has the original color (untinted)
+        verifyImageSourceIsColoredAs("No image tinting after change in background tinting", view,
+                sourceColor, 0);
+
+        // Now set a different image source
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageResource(R.drawable.test_drawable_red));
+        // And verify that the image has the new color (untinted)
+        verifyImageSourceIsColoredAs("No image tinting after change of image source", view,
+                newSourceColor, 0);
+
+        // Change the background tinting again
+        final ColorStateList sandColor = ResourcesCompat.getColorStateList(
+                mResources, R.color.color_state_list_sand, null);
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setBackgroundTintList(sandColor));
+        // And verify that the image still has the same new color (untinted)
+        verifyImageSourceIsColoredAs("No image tinting after change in background tinting", view,
+                newSourceColor, 0);
+
+        // Now set up image tinting on our view. We're using a color state list with fully
+        // opaque colors, and we expect the matching entry in that list to be applied on the
+        // image source (ignoring the background tinting)
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintMode(PorterDuff.Mode.SRC_IN));
+        onView(withId(viewId)).perform(
+                AppCompatTintableViewActions.setImageSourceTintList(lilacColor));
+        verifyImageSourceIsColoredAs("New lilac image tinting", view,
+                lilacDefault, 0);
+    }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java
index bacb0e3..6e4e6c0 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatBaseViewTest.java
@@ -35,6 +35,7 @@
 import android.support.annotation.ColorInt;
 import android.support.annotation.IdRes;
 import android.support.annotation.NonNull;
+import android.support.test.filters.SmallTest;
 import android.support.v4.content.res.ResourcesCompat;
 import android.support.v4.graphics.ColorUtils;
 import android.support.v7.app.BaseInstrumentationTestCase;
@@ -42,7 +43,6 @@
 import android.support.v7.testutils.AppCompatTintableViewActions;
 import android.support.v7.testutils.BaseTestActivity;
 import android.support.v7.testutils.TestUtils;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
 import android.view.ViewGroup;
 
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageButtonActivity.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageButtonActivity.java
new file mode 100644
index 0000000..1a64047
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageButtonActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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.v7.appcompat.test.R;
+import android.support.v7.testutils.BaseTestActivity;
+
+public class AppCompatImageButtonActivity extends BaseTestActivity {
+    @Override
+    protected int getContentViewLayoutResId() {
+        return R.layout.appcompat_imagebutton_activity;
+    }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageButtonTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageButtonTest.java
new file mode 100644
index 0000000..67fca4a
--- /dev/null
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageButtonTest.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+/**
+ * In addition to all tinting-related tests done by the base class, this class provides
+ * tests specific to {@link AppCompatImageButton} class.
+ */
+public class AppCompatImageButtonTest extends AppCompatBaseImageViewTest<AppCompatImageButton> {
+    public AppCompatImageButtonTest() {
+        super(AppCompatImageButtonActivity.class);
+    }
+}
diff --git a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
index d6801da..88d105c 100644
--- a/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/widget/AppCompatImageViewTest.java
@@ -31,8 +31,7 @@
  * tests specific to {@link AppCompatImageView} class.
  */
 @SmallTest
-public class AppCompatImageViewTest
-        extends AppCompatBaseViewTest<AppCompatImageViewActivity, AppCompatImageView> {
+public class AppCompatImageViewTest extends AppCompatBaseImageViewTest<AppCompatImageView> {
     public AppCompatImageViewTest() {
         super(AppCompatImageViewActivity.class);
     }
@@ -40,7 +39,7 @@
     @Test
     public void testImageViewBothSrcCompatAndroidSrcSet() {
         final int expectedColor = mContainer.getResources().getColor(R.color.test_blue);
-        ViewInteraction imageViewInteration = onView(withId(R.id.view_android_src_srccompat));
-        imageViewInteration.check(matches(TestUtilsMatchers.drawable(expectedColor)));
+        ViewInteraction imageViewInteraction = onView(withId(R.id.view_android_src_srccompat));
+        imageViewInteraction.check(matches(TestUtilsMatchers.drawable(expectedColor)));
     }
 }
diff --git a/v7/cardview/AndroidManifest.xml b/v7/cardview/AndroidManifest.xml
index e85003c..78b5250 100644
--- a/v7/cardview/AndroidManifest.xml
+++ b/v7/cardview/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.cardview">
     <uses-sdk android:minSdkVersion="9"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v7/gridlayout/AndroidManifest.xml b/v7/gridlayout/AndroidManifest.xml
index dfcc942..45a0978 100644
--- a/v7/gridlayout/AndroidManifest.xml
+++ b/v7/gridlayout/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.gridlayout">
     <uses-sdk android:minSdkVersion="9"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v7/mediarouter/AndroidManifest.xml b/v7/mediarouter/AndroidManifest.xml
index bbebdfed..3f50fe6 100644
--- a/v7/mediarouter/AndroidManifest.xml
+++ b/v7/mediarouter/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.mediarouter">
     <uses-sdk android:minSdkVersion="9"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
index fe16de8..0d85b3b 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
@@ -2708,7 +2708,8 @@
                     record.updatePlaybackInfo();
                 }
                 if (mMediaSession != null) {
-                    if (mSelectedRoute == getDefaultRoute()) {
+                    if (mSelectedRoute == getDefaultRoute()
+                            || mSelectedRoute == getBluetoothRoute()) {
                         // Local route
                         mMediaSession.clearVolumeHandling();
                     } else {
diff --git a/v7/palette/src/main/AndroidManifest.xml b/v7/palette/src/main/AndroidManifest.xml
index 52e90a2..00ebcce 100644
--- a/v7/palette/src/main/AndroidManifest.xml
+++ b/v7/palette/src/main/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.palette">
     <uses-sdk android:minSdkVersion="9"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v7/preference/AndroidManifest.xml b/v7/preference/AndroidManifest.xml
index 19e6215..0c03b91 100644
--- a/v7/preference/AndroidManifest.xml
+++ b/v7/preference/AndroidManifest.xml
@@ -16,6 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.support.v7.preference">
     <uses-sdk android:minSdkVersion="9" />
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
-    <application />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v7/recyclerview/AndroidManifest.xml b/v7/recyclerview/AndroidManifest.xml
index f4f010d..eb3d53a 100644
--- a/v7/recyclerview/AndroidManifest.xml
+++ b/v7/recyclerview/AndroidManifest.xml
@@ -16,5 +16,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="android.support.v7.recyclerview">
     <uses-sdk android:minSdkVersion="9"/>
-    <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    <application>
+        <meta-data android:name="android.support.VERSION" android:value="${support-version}" />
+    </application>
 </manifest>
diff --git a/v7/recyclerview/src/android/support/v7/widget/GapWorker.java b/v7/recyclerview/src/android/support/v7/widget/GapWorker.java
index e6c7801..c7e81b5 100644
--- a/v7/recyclerview/src/android/support/v7/widget/GapWorker.java
+++ b/v7/recyclerview/src/android/support/v7/widget/GapWorker.java
@@ -106,6 +106,10 @@
 
         @Override
         public void addPosition(int layoutPosition, int pixelDistance) {
+            if (layoutPosition < 0) {
+                throw new IllegalArgumentException("Layout positions must be non-negative");
+            }
+
             if (pixelDistance < 0) {
                 throw new IllegalArgumentException("Pixel distance must be non-negative");
             }
@@ -145,6 +149,7 @@
             if (mPrefetchArray != null) {
                 Arrays.fill(mPrefetchArray, -1);
             }
+            mCount = 0;
         }
     }
 
@@ -221,6 +226,11 @@
         int totalTaskIndex = 0;
         for (int i = 0; i < viewCount; i++) {
             RecyclerView view = mRecyclerViews.get(i);
+            if (view.getWindowVisibility() != View.VISIBLE) {
+                // Invisible view, don't bother prefetching
+                continue;
+            }
+
             LayoutPrefetchRegistryImpl prefetchRegistry = view.mPrefetchRegistry;
             final int viewVelocity = Math.abs(prefetchRegistry.mPrefetchDx)
                     + Math.abs(prefetchRegistry.mPrefetchDy);
@@ -269,21 +279,27 @@
         }
 
         RecyclerView.Recycler recycler = view.mRecycler;
-        RecyclerView.ViewHolder holder = recycler.tryGetViewHolderForPositionByDeadline(
-                position, false, deadlineNs);
+        RecyclerView.ViewHolder holder;
+        try {
+            view.onEnterLayoutOrScroll();
+            holder = recycler.tryGetViewHolderForPositionByDeadline(
+                    position, false, deadlineNs);
 
-        if (holder != null) {
-            if (holder.isBound()) {
-                // Only give the view a chance to go into the cache if binding succeeded
-                // Note that we must use public method, since item may need cleanup
-                recycler.recycleView(holder.itemView);
-            } else {
-                // Didn't bind, so we can't cache the view, but it will stay in the pool until
-                // next prefetch/traversal. If a View fails to bind, it means we didn't have
-                // enough time prior to the deadline (and won't for other instances of this
-                // type, during this GapWorker prefetch pass).
-                recycler.addViewHolderToRecycledViewPool(holder, false);
+            if (holder != null) {
+                if (holder.isBound() && !holder.isInvalid()) {
+                    // Only give the view a chance to go into the cache if binding succeeded
+                    // Note that we must use public method, since item may need cleanup
+                    recycler.recycleView(holder.itemView);
+                } else {
+                    // Didn't bind, so we can't cache the view, but it will stay in the pool until
+                    // next prefetch/traversal. If a View fails to bind, it means we didn't have
+                    // enough time prior to the deadline (and won't for other instances of this
+                    // type, during this GapWorker prefetch pass).
+                    recycler.addViewHolderToRecycledViewPool(holder, false);
+                }
             }
+        } finally {
+            view.onExitLayoutOrScroll(false);
         }
         return holder;
     }
@@ -325,7 +341,10 @@
         long taskDeadlineNs = task.immediate ? RecyclerView.FOREVER_NS : deadlineNs;
         RecyclerView.ViewHolder holder = prefetchPositionWithDeadline(task.view,
                 task.position, taskDeadlineNs);
-        if (holder != null && holder.mNestedRecyclerView != null) {
+        if (holder != null
+                && holder.mNestedRecyclerView != null
+                && holder.isBound()
+                && !holder.isInvalid()) {
             prefetchInnerRecyclerViewWithDeadline(holder.mNestedRecyclerView.get(), deadlineNs);
         }
     }
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
index ac14206..0ec3b50 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
@@ -148,7 +148,7 @@
     /**
      * Number of items to prefetch when first coming on screen with new data.
      */
-    private int mInitialItemPrefetchCount = 2;
+    private int mInitialPrefetchItemCount = 2;
 
     /**
      * Creates a vertical LinearLayoutManager
@@ -1229,7 +1229,7 @@
                 ? LayoutState.ITEM_DIRECTION_HEAD
                 : LayoutState.ITEM_DIRECTION_TAIL;
         int targetPos = anchorPos;
-        for (int i = 0; i < mInitialItemPrefetchCount; i++) {
+        for (int i = 0; i < mInitialPrefetchItemCount; i++) {
             if (targetPos >= 0 && targetPos < adapterItemCount) {
                 layoutPrefetchRegistry.addPosition(targetPos, 0);
             } else {
@@ -1265,11 +1265,11 @@
      * @param itemCount Number of items to prefetch
      *
      * @see #isItemPrefetchEnabled()
-     * @see #getInitialItemPrefetchCount()
+     * @see #getInitialPrefetchItemCount()
      * @see #collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)
      */
     public void setInitialPrefetchItemCount(int itemCount) {
-        mInitialItemPrefetchCount = itemCount;
+        mInitialPrefetchItemCount = itemCount;
     }
 
     /**
@@ -1284,8 +1284,17 @@
      *
      * @return number of items to prefetch.
      */
+    public int getInitialPrefetchItemCount() {
+        return mInitialPrefetchItemCount;
+    }
+
+
+    /**
+     * @deprecated Use {@link #getInitialPrefetchItemCount()} instead.
+     */
+    @Deprecated
     public int getInitialItemPrefetchCount() {
-        return mInitialItemPrefetchCount;
+        return getInitialPrefetchItemCount();
     }
 
     @Override
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java b/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java
index 9e262db..c74e20d 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearSnapHelper.java
@@ -170,11 +170,7 @@
         }
         int distance =
                 Math.abs(distances[0]) > Math.abs(distances[1]) ? distances[0] : distances[1];
-        if (distance > 0) {
-            return (int) Math.floor(distance / distancePerChild);
-        } else {
-            return (int) Math.ceil(distance / distancePerChild);
-        }
+        return (int) Math.round(distance / distancePerChild);
     }
 
     /**
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 5f06408..a88213b 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -725,6 +725,11 @@
                 final View child = RecyclerView.this.getChildAt(index);
                 if (child != null) {
                     dispatchChildDetached(child);
+
+                    // Clear any android.view.animation.Animation that may prevent the item from
+                    // detaching when being removed. If a child is re-added before the
+                    // lazy detach occurs, it will receive invalid attach/detach sequencing.
+                    child.clearAnimation();
                 }
                 if (VERBOSE_TRACING) {
                     TraceCompat.beginSection("RV removeViewAt");
@@ -744,7 +749,13 @@
             public void removeAllViews() {
                 final int count = getChildCount();
                 for (int i = 0; i < count; i ++) {
-                    dispatchChildDetached(getChildAt(i));
+                    View child = getChildAt(i);
+                    dispatchChildDetached(child);
+
+                    // Clear any android.view.animation.Animation that may prevent the item from
+                    // detaching when being removed. If a child is re-added before the
+                    // lazy detach occurs, it will receive invalid attach/detach sequencing.
+                    child.clearAnimation();
                 }
                 RecyclerView.this.removeAllViews();
             }
@@ -3125,6 +3136,10 @@
     }
 
     void onExitLayoutOrScroll() {
+        onExitLayoutOrScroll(true);
+    }
+
+    void onExitLayoutOrScroll(boolean enableChangeEvents) {
         mLayoutOrScrollCounter --;
         if (mLayoutOrScrollCounter < 1) {
             if (DEBUG && mLayoutOrScrollCounter < 0) {
@@ -3132,8 +3147,10 @@
                         + "Some calls are not matching");
             }
             mLayoutOrScrollCounter = 0;
-            dispatchContentChangedIfNecessary();
-            dispatchPendingImportantForAccessibilityChanges();
+            if (enableChangeEvents) {
+                dispatchContentChangedIfNecessary();
+                dispatchPendingImportantForAccessibilityChanges();
+            }
         }
     }
 
@@ -3786,6 +3803,12 @@
                         + " is not flagged as tmp detached." + vh);
             }
         }
+
+        // Clear any android.view.animation.Animation that may prevent the item from
+        // detaching when being removed. If a child is re-added before the
+        // lazy detach occurs, it will receive invalid attach/detach sequencing.
+        child.clearAnimation();
+
         dispatchChildDetached(child);
         super.removeDetachedView(child, animate);
     }
@@ -4119,31 +4142,16 @@
     /**
      * Call this method to signal that *all* adapter content has changed (generally, because of
      * swapAdapter, or notifyDataSetChanged), and that once layout occurs, all attached items should
-     * be discarded or animated. Note that this work is deferred because RecyclerView requires a
-     * layout to resolve non-incremental changes to the data set.
+     * be discarded or animated.
      *
-     * Attached items are labeled as position unknown, and may no longer be cached.
+     * Attached items are labeled as invalid, and all cached items are discarded.
      *
      * It is still possible for items to be prefetched while mDataSetHasChangedAfterLayout == true,
-     * so calling this method *must* be associated with marking the cache invalid, so that the
-     * only valid items that remain in the cache, once layout occurs, are prefetched items.
+     * so this method must always discard all cached views so that the only valid items that remain
+     * in the cache, once layout occurs, are valid prefetched items.
      */
     void setDataSetChangedAfterLayout() {
-        if (mDataSetHasChangedAfterLayout) {
-            return;
-        }
         mDataSetHasChangedAfterLayout = true;
-        final int childCount = mChildHelper.getUnfilteredChildCount();
-        for (int i = 0; i < childCount; i++) {
-            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
-            if (holder != null && !holder.shouldIgnore()) {
-                holder.addFlags(ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN);
-            }
-        }
-        mRecycler.setAdapterPositionsAsUnknown();
-
-        // immediately mark all views as invalid, so prefetched views can be
-        // differentiated from views bound to previous data set - both in children, and cache
         markKnownViewsInvalid();
     }
 
@@ -6168,7 +6176,7 @@
                     continue;
                 }
 
-                final int pos = holder.getLayoutPosition();
+                final int pos = holder.mPosition;
                 if (pos >= positionStart && pos < positionEnd) {
                     holder.addFlags(ViewHolder.FLAG_UPDATE);
                     recycleCachedViewAt(i);
@@ -6178,16 +6186,6 @@
             }
         }
 
-        void setAdapterPositionsAsUnknown() {
-            final int cachedCount = mCachedViews.size();
-            for (int i = 0; i < cachedCount; i++) {
-                final ViewHolder holder = mCachedViews.get(i);
-                if (holder != null) {
-                    holder.addFlags(ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN);
-                }
-            }
-        }
-
         void markKnownViewsInvalid() {
             if (mAdapter != null && mAdapter.hasStableIds()) {
                 final int cachedCount = mCachedViews.size();
@@ -11561,7 +11559,6 @@
         void prepareForNestedPrefetch(Adapter adapter) {
             mLayoutStep = STEP_START;
             mItemCount = adapter.getItemCount();
-            mStructureChanged = false;
             mInPreLayout = false;
             mTrackOldChangeHolders = false;
             mIsMeasuring = false;
@@ -11749,7 +11746,7 @@
          * @param velocityX the fling velocity on the X axis
          * @param velocityY the fling velocity on the Y axis
          *
-         * @return true if the fling washandled, false otherwise.
+         * @return true if the fling was handled, false otherwise.
          */
         public abstract boolean onFling(int velocityX, int velocityY);
     }
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 5f7bf48..8ca5f4e 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseRecyclerViewInstrumentationTest.java
@@ -765,7 +765,7 @@
 
         int mAdapterIndex;
 
-        final String mText;
+        String mText;
         int mType = 0;
         boolean mFocusable;
 
@@ -882,7 +882,12 @@
             assertEquals(log, shouldHavePosition, adapterPosition != RecyclerView.NO_POSITION);
             if (shouldHavePosition) {
                 assertTrue(log, mItems.size() > adapterPosition);
-                assertSame(log, holder.mBoundItem, mItems.get(adapterPosition));
+                // TODO: fix b/36042615 getAdapterPosition() is wrong in
+                // consumePendingUpdatesInOnePass where it applies pending change to already
+                // modified position.
+                if (holder.mPreLayoutPosition == RecyclerView.NO_POSITION) {
+                    assertSame(log, holder.mBoundItem, mItems.get(adapterPosition));
+                }
             }
         }
 
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/GapWorkerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/GapWorkerTest.java
index 5d08931..9158161 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/GapWorkerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/GapWorkerTest.java
@@ -43,6 +43,43 @@
     }
 
     @Test
+    public void registrySimple() {
+        GapWorker.LayoutPrefetchRegistryImpl registry = new GapWorker.LayoutPrefetchRegistryImpl();
+        registry.addPosition(0, 0);
+        registry.addPosition(2, 0);
+        registry.addPosition(3, 0);
+        assertTrue(registry.lastPrefetchIncludedPosition(0));
+        assertFalse(registry.lastPrefetchIncludedPosition(1));
+        assertTrue(registry.lastPrefetchIncludedPosition(2));
+        assertTrue(registry.lastPrefetchIncludedPosition(3));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void registryNegativeLayout() {
+        GapWorker.LayoutPrefetchRegistryImpl registry = new GapWorker.LayoutPrefetchRegistryImpl();
+        registry.addPosition(-1, 0);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void registryNegativeDistance() {
+        GapWorker.LayoutPrefetchRegistryImpl registry = new GapWorker.LayoutPrefetchRegistryImpl();
+        registry.addPosition(0, -1);
+    }
+
+    @Test
+    public void registryResetCorrectly() {
+        GapWorker.LayoutPrefetchRegistryImpl registry = new GapWorker.LayoutPrefetchRegistryImpl();
+        registry.addPosition(0, 0);
+        assertFalse(registry.lastPrefetchIncludedPosition(-1));
+        assertTrue(registry.lastPrefetchIncludedPosition(0));
+
+        registry.clearPrefetchPositions();
+
+        assertFalse(registry.lastPrefetchIncludedPosition(-1));
+        assertFalse(registry.lastPrefetchIncludedPosition(0));
+    }
+
+    @Test
     public void taskOrderViewPresence() {
         ArrayList<GapWorker.Task> list = new ArrayList<>();
         list.add(new GapWorker.Task());
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 2da67af..ae70900 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java
@@ -31,7 +31,9 @@
 import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.StateListDrawable;
+import android.os.Build;
 import android.support.test.filters.LargeTest;
+import android.support.test.filters.SdkSuppress;
 import android.support.v4.view.AccessibilityDelegateCompat;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.support.v4.view.accessibility.AccessibilityRecordCompat;
@@ -402,6 +404,12 @@
         }
     }
 
+    // Run this test on Jelly Bean and newer because clearFocus on API 15 will call
+    // requestFocus in ViewRootImpl when clearChildFocus is called. Whereas, in API 16 and above,
+    // this call is delayed until after onFocusChange callback is called. Thus on API 16+, there's a
+    // transient state of no child having focus during which onFocusChange is executed. This
+    // transient state does not exist on API 15-.
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
     @Test
     public void unfocusableScrollingWhenFocusCleared() throws Throwable {
         // The maximum number of child views that can be visible at any time.
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..bd14d2c 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;
@@ -47,7 +43,7 @@
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class RecyclerViewAccessibilityLifecycleTest extends BaseRecyclerViewInstrumentationTest {
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
     @Test
     public void dontDispatchChangeDuringLayout() throws Throwable {
         LayoutAllLayoutManager lm = new LayoutAllLayoutManager();
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewCacheTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewCacheTest.java
index 2ef2783..1006e1b 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewCacheTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewCacheTest.java
@@ -20,6 +20,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
@@ -266,6 +267,38 @@
     }
 
     @Test
+    public void prefetchIsComputingLayout() {
+        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+
+        // 100x100 pixel views
+        RecyclerView.Adapter mockAdapter = mock(RecyclerView.Adapter.class);
+        when(mockAdapter.onCreateViewHolder(any(ViewGroup.class), anyInt()))
+                .thenAnswer(new Answer<RecyclerView.ViewHolder>() {
+                    @Override
+                    public RecyclerView.ViewHolder answer(InvocationOnMock invocation)
+                            throws Throwable {
+                        View view = new View(getContext());
+                        view.setMinimumWidth(100);
+                        view.setMinimumHeight(100);
+                        assertTrue(mRecyclerView.isComputingLayout());
+                        return new RecyclerView.ViewHolder(view) {};
+                    }
+                });
+        when(mockAdapter.getItemCount()).thenReturn(100);
+        mRecyclerView.setAdapter(mockAdapter);
+
+        layout(100, 100);
+
+        verify(mockAdapter, times(1)).onCreateViewHolder(mRecyclerView, 0);
+
+        // prefetch an item, should still observe isComputingLayout in that create
+        mRecyclerView.mPrefetchRegistry.setPrefetchVector(0, 1);
+        mRecyclerView.mGapWorker.prefetch(RecyclerView.FOREVER_NS);
+
+        verify(mockAdapter, times(2)).onCreateViewHolder(mRecyclerView, 0);
+    }
+
+    @Test
     public void prefetchDrag() {
         // event dispatch requires a parent
         ViewGroup parent = new FrameLayout(getContext());
@@ -787,7 +820,7 @@
     @Test
     public void nestedPrefetchSimple() {
         LinearLayoutManager llm = new LinearLayoutManager(getContext());
-        assertEquals(2, llm.getInitialItemPrefetchCount());
+        assertEquals(2, llm.getInitialPrefetchItemCount());
 
         mRecyclerView.setLayoutManager(llm);
         mRecyclerView.setAdapter(new OuterAdapter());
@@ -811,6 +844,58 @@
     }
 
     @Test
+    public void nestedPrefetchNotClearInnerStructureChangeFlag() {
+        LinearLayoutManager llm = new LinearLayoutManager(getContext());
+        assertEquals(2, llm.getInitialPrefetchItemCount());
+
+        mRecyclerView.setLayoutManager(llm);
+        mRecyclerView.setAdapter(new OuterAdapter());
+
+        layout(200, 200);
+        mRecyclerView.mPrefetchRegistry.setPrefetchVector(0, 1);
+
+        // prefetch 2 (default)
+        mRecyclerView.mGapWorker.prefetch(RecyclerView.FOREVER_NS);
+        RecyclerView.ViewHolder holder = CacheUtils.peekAtCachedViewForPosition(mRecyclerView, 2);
+        assertNotNull(holder);
+        assertNotNull(holder.mNestedRecyclerView);
+        RecyclerView innerView = holder.mNestedRecyclerView.get();
+        RecyclerView.Adapter innerAdapter = innerView.getAdapter();
+        CacheUtils.verifyCacheContainsPrefetchedPositions(innerView, 0, 1);
+        // mStructureChanged is initially true before first layout pass.
+        assertTrue(innerView.mState.mStructureChanged);
+        assertTrue(innerView.hasPendingAdapterUpdates());
+
+        // layout position 2 and clear mStructureChanged
+        mRecyclerView.scrollToPosition(2);
+        layout(200, 200);
+        mRecyclerView.scrollToPosition(0);
+        layout(200, 200);
+        assertFalse(innerView.mState.mStructureChanged);
+        assertFalse(innerView.hasPendingAdapterUpdates());
+
+        // notify change on the cached innerView.
+        innerAdapter.notifyDataSetChanged();
+        assertTrue(innerView.mState.mStructureChanged);
+        assertTrue(innerView.hasPendingAdapterUpdates());
+
+        // prefetch again
+        mRecyclerView.mPrefetchRegistry.setPrefetchVector(0, 1);
+        ((LinearLayoutManager) innerView.getLayoutManager())
+                .setInitialPrefetchItemCount(2);
+        mRecyclerView.mGapWorker.prefetch(RecyclerView.FOREVER_NS);
+        CacheUtils.verifyCacheContainsPrefetchedPositions(innerView, 0, 1);
+
+        // The re-prefetch is not necessary get the same inner view but we will get same Adapter
+        holder = CacheUtils.peekAtCachedViewForPosition(mRecyclerView, 2);
+        innerView = holder.mNestedRecyclerView.get();
+        assertSame(innerAdapter, innerView.getAdapter());
+        // prefetch shouldn't clear the mStructureChanged flag
+        assertTrue(innerView.mState.mStructureChanged);
+        assertTrue(innerView.hasPendingAdapterUpdates());
+    }
+
+    @Test
     public void nestedPrefetchReverseInner() {
         mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
         mRecyclerView.setAdapter(new OuterAdapter(/* reverseInner = */ true));
@@ -1066,8 +1151,10 @@
 
         @Override
         public void onViewRecycled(ViewHolder holder) {
-            mSavedStates.set(holder.getAdapterPosition(),
-                    holder.mRecyclerView.getLayoutManager().onSaveInstanceState());
+            if (holder.getAdapterPosition() >= 0) {
+                mSavedStates.set(holder.getAdapterPosition(),
+                        holder.mRecyclerView.getLayoutManager().onSaveInstanceState());
+            }
         }
 
         @Override
@@ -1079,7 +1166,7 @@
     @Test
     public void nestedPrefetchDiscardStaleChildren() {
         LinearLayoutManager llm = new LinearLayoutManager(getContext());
-        assertEquals(2, llm.getInitialItemPrefetchCount());
+        assertEquals(2, llm.getInitialPrefetchItemCount());
 
         mRecyclerView.setLayoutManager(llm);
         OuterNotifyAdapter outerAdapter = new OuterNotifyAdapter();
@@ -1122,4 +1209,55 @@
         mRecyclerView.mGapWorker.prefetch(RecyclerView.FOREVER_NS);
         CacheUtils.verifyCacheContainsPrefetchedPositions(holder.mNestedRecyclerView.get(), 0, 1);
     }
+
+
+    @Test
+    public void nestedPrefetchDiscardStalePrefetch() {
+        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+        OuterNotifyAdapter outerAdapter = new OuterNotifyAdapter();
+        mRecyclerView.setAdapter(outerAdapter);
+
+        // zero cache, so item we prefetch can't already be ready
+        mRecyclerView.setItemViewCacheSize(0);
+
+        // layout as 2x2, starting on row index 2, with empty cache
+        layout(200, 200);
+        mRecyclerView.scrollBy(0, 200);
+
+        // no views cached, or previously used (so we can trust number in mItemsBound)
+        mRecycler.mRecyclerPool.clear();
+        assertEquals(0, mRecycler.mRecyclerPool.getRecycledViewCount(0));
+        assertEquals(0, mRecycler.mCachedViews.size());
+
+        // prefetch the outer item and its inner children
+        mRecyclerView.mPrefetchRegistry.setPrefetchVector(0, 1);
+        mRecyclerView.mGapWorker.prefetch(RecyclerView.FOREVER_NS);
+
+        // 4 is prefetched with 2 inner children, first two binds
+        CacheUtils.verifyCacheContainsPrefetchedPositions(mRecyclerView, 4);
+        RecyclerView.ViewHolder holder = CacheUtils.peekAtCachedViewForPosition(mRecyclerView, 4);
+        assertNotNull(holder);
+        assertNotNull(holder.mNestedRecyclerView);
+        RecyclerView innerRecyclerView = holder.mNestedRecyclerView.get();
+        assertEquals(0, innerRecyclerView.mChildHelper.getUnfilteredChildCount());
+        assertEquals(2, innerRecyclerView.mRecycler.mCachedViews.size());
+        assertEquals(2, ((InnerAdapter) innerRecyclerView.getAdapter()).mItemsBound);
+
+        // notify data set changed, so any previously prefetched items invalid, and re-prefetch
+        innerRecyclerView.getAdapter().notifyDataSetChanged();
+        mRecyclerView.mPrefetchRegistry.setPrefetchVector(0, 1);
+        mRecyclerView.mGapWorker.prefetch(RecyclerView.FOREVER_NS);
+
+        // 4 is prefetched again...
+        CacheUtils.verifyCacheContainsPrefetchedPositions(mRecyclerView, 4);
+
+        // reusing the same instance with 2 inner children...
+        assertSame(holder, CacheUtils.peekAtCachedViewForPosition(mRecyclerView, 4));
+        assertSame(innerRecyclerView, holder.mNestedRecyclerView.get());
+        assertEquals(0, innerRecyclerView.mChildHelper.getUnfilteredChildCount());
+        assertEquals(2, innerRecyclerView.mRecycler.mCachedViews.size());
+
+        // ... but there should be two new binds
+        assertEquals(4, ((InnerAdapter) innerRecyclerView.getAdapter()).mItemsBound);
+    }
 }
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 cc6762a..6fd9a86 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewLayoutTest.java
@@ -345,7 +345,9 @@
             public View onFocusSearchFailed(View focused, int direction,
                     RecyclerView.Recycler recycler,
                     RecyclerView.State state) {
-                assertEquals(View.FOCUS_FORWARD, direction);
+                int expectedDir = Build.VERSION.SDK_INT <= 15 ? View.FOCUS_DOWN :
+                        View.FOCUS_FORWARD;
+                assertEquals(expectedDir, direction);
                 assertEquals(1, getChildCount());
                 View child0 = getChildAt(0);
                 View view = recycler.getViewForPosition(1);
@@ -909,6 +911,61 @@
     }
 
     @Test
+    public void moveAndUpdateCachedViews() throws Throwable {
+        final RecyclerView recyclerView = new RecyclerView(getActivity());
+        recyclerView.setItemViewCacheSize(3);
+        recyclerView.setItemAnimator(null);
+        final TestAdapter adapter = new TestAdapter(1000);
+        final CountDownLatch layoutLatch = new CountDownLatch(1);
+        LinearLayoutManager tlm = new LinearLayoutManager(recyclerView.getContext()) {
+            @Override
+            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+                super.onLayoutChildren(recycler, state);
+                layoutLatch.countDown();
+            }
+        };
+        tlm.setItemPrefetchEnabled(false);
+        recyclerView.setLayoutManager(tlm);
+        recyclerView.setAdapter(adapter);
+        setRecyclerView(recyclerView);
+        // wait first layout pass
+        layoutLatch.await();
+        // scroll and hide 0 and 1
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                recyclerView.smoothScrollBy(0, recyclerView.getChildAt(2).getTop() + 5);
+            }
+        });
+        waitForIdleScroll(recyclerView);
+        assertNull(recyclerView.findViewHolderForAdapterPosition(0));
+        assertNull(recyclerView.findViewHolderForAdapterPosition(1));
+        // swap 1 and 0 and update 0
+        mActivityRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    // swap 1 and 0
+                    adapter.moveInUIThread(1, 0);
+                    adapter.notifyItemMoved(1, 0);
+                    // update 0
+                    adapter.mItems.get(0).mText = "updated";
+                    adapter.notifyItemChanged(0);
+                } catch (Throwable throwable) {
+                    postExceptionToInstrumentation(throwable);
+                }
+            }
+        });
+        // scroll back to 0
+        smoothScrollToPosition(0);
+        waitForIdleScroll(recyclerView);
+        TestViewHolder vh = (TestViewHolder) recyclerView.findViewHolderForAdapterPosition(0);
+        // assert updated right item
+        assertTrue((((TextView) (vh.itemView)).getText()).toString().contains("updated"));
+        checkForMainThreadException();
+    }
+
+    @Test
     public void noLayoutIf0ItemsAreChanged() throws Throwable {
         unnecessaryNotifyEvents(new AdapterRunnable() {
             @Override