Fix some use of deprecated APIs in Support7Demos.
am: e8e0eae260

Change-Id: I0a62610e41bb7142e18312a15bba6dd9d4557c21
diff --git a/annotations/src/android/support/annotation/RestrictTo.java b/annotations/src/android/support/annotation/RestrictTo.java
new file mode 100644
index 0000000..65c8ba0
--- /dev/null
+++ b/annotations/src/android/support/annotation/RestrictTo.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.support.annotation;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PACKAGE;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+/**
+ * Denotes that the annotated element should only be accessed from within a
+ * specific scope (as defined by {@link Scope}).
+ * <p>
+ * Example of restricting usage within a library (based on gradle group ID):
+ * <pre><code>
+ *   &#64;RestrictTo(GROUP_ID)
+ *   public void resetPaddingToInitialValues() { ...
+ * </code></pre>
+ * Example of restricting usage to tests:
+ * <pre><code>
+ *   &#64;RestrictScope(TESTS)
+ *   public abstract int getUserId();
+ * </code></pre>
+ * Example of restricting usage to subclasses:
+ * <pre><code>
+ *   &#64;RestrictScope(SUBCLASSES)
+ *   public void onDrawForeground(Canvas canvas) { ...
+ * </code></pre>
+ */
+@Retention(CLASS)
+@Target({ANNOTATION_TYPE,TYPE,METHOD,CONSTRUCTOR,FIELD,PACKAGE})
+public @interface RestrictTo {
+
+    /**
+     * The scope to which usage should be restricted.
+     */
+    Scope[] value();
+
+    enum Scope {
+        /**
+         * Restrict usage to code within the same group ID (based on gradle
+         * group ID).
+         */
+        GROUP_ID,
+
+        /**
+         * Restrict usage to tests.
+         */
+        TESTS,
+
+        /**
+         * Restrict usage to subclasses of the enclosing class.
+         * <p>
+         * <strong>Note:</strong> This scope should not be used to annotate
+         * packages.
+         */
+        SUBCLASSES,
+    }
+}
diff --git a/annotations/src/android/support/annotation/VisibleForTesting.java b/annotations/src/android/support/annotation/VisibleForTesting.java
index 0c893ff..ddce1d5 100644
--- a/annotations/src/android/support/annotation/VisibleForTesting.java
+++ b/annotations/src/android/support/annotation/VisibleForTesting.java
@@ -18,11 +18,57 @@
 import java.lang.annotation.Retention;
 
 import static java.lang.annotation.RetentionPolicy.CLASS;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
 
 /**
  * Denotes that the class, method or field has its visibility relaxed, so that it is more widely
  * visible than otherwise necessary to make code testable.
+ * <p>
+ * You can optionally specify what the visibility <b>should</b> have been if not for
+ * testing; this allows tools to catch unintended access from within production
+ * code.
+ * <p>
+ * Example:
+ * <pre><code>
+ *  &#64;VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+ *  public String printDiagnostics() { ... }
+ * </code></pre>
+ *
+ * If not specified, the intended visibility is assumed to be private.
  */
 @Retention(CLASS)
 public @interface VisibleForTesting {
+    /**
+     * The visibility the annotated element would have if it did not need to be made visible for
+     * testing.
+     */
+    @ProductionVisibility
+    int otherwise() default PRIVATE;
+
+    /**
+     * The annotated element would have "private" visibility
+     */
+    int PRIVATE = 2; // Happens to be the same as Modifier.PRIVATE
+
+    /**
+     * The annotated element would have "package private" visibility
+     */
+    int PACKAGE_PRIVATE = 3;
+
+    /**
+     * The annotated element would have "protected" visibility
+     */
+    int PROTECTED = 4; // Happens to be the same as Modifier.PROTECTED
+
+    /**
+     * The annotated element should never be called from production code, only from tests.
+     * <p>
+     * This is equivalent to {@code @RestrictTo.Scope.TESTS}.
+     */
+    int NONE = 5;
+
+    @IntDef({PRIVATE, PACKAGE_PRIVATE, PROTECTED, NONE})
+    @Retention(SOURCE)
+    @interface ProductionVisibility {
+    }
 }
diff --git a/api/current.txt b/api/current.txt
index 49d9306..6b9a183 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5683,11 +5683,16 @@
     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 {
@@ -9760,6 +9765,7 @@
     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();
@@ -9813,6 +9819,7 @@
     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);
diff --git a/build.gradle b/build.gradle
index 8768f56..dd30dfb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,7 +14,7 @@
         maven { url "../../prebuilts/maven_repo/android" }
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:2.2.0-beta2'
+        classpath 'com.android.tools.build:gradle:2.2.0-rc1'
     }
 }
 
diff --git a/compat/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java b/compat/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java
index 31ec294..801b8ea 100644
--- a/compat/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java
+++ b/compat/api23/android/support/v4/hardware/fingerprint/FingerprintManagerCompatApi23.java
@@ -19,16 +19,20 @@
 import android.content.Context;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Handler;
+import android.support.annotation.RestrictTo;
 
 import java.security.Signature;
 
 import javax.crypto.Cipher;
 import javax.crypto.Mac;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Actual FingerprintManagerCompat implementation for API level 23 and later.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class FingerprintManagerCompatApi23 {
 
     private static FingerprintManager getFingerprintManager(Context ctx) {
diff --git a/compat/api24/android/support/v4/net/TrafficStatsCompatApi24.java b/compat/api24/android/support/v4/net/TrafficStatsCompatApi24.java
index f525dea..02a9699 100644
--- a/compat/api24/android/support/v4/net/TrafficStatsCompatApi24.java
+++ b/compat/api24/android/support/v4/net/TrafficStatsCompatApi24.java
@@ -17,11 +17,15 @@
 package android.support.v4.net;
 
 import android.net.TrafficStats;
+import android.support.annotation.RestrictTo;
 
 import java.net.DatagramSocket;
 import java.net.SocketException;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /** {@hide} */
+@RestrictTo(GROUP_ID)
 public class TrafficStatsCompatApi24 {
     public static void tagDatagramSocket(DatagramSocket socket) throws SocketException {
         TrafficStats.tagDatagramSocket(socket);
diff --git a/compat/api24/android/support/v4/os/UserManagerCompatApi24.java b/compat/api24/android/support/v4/os/UserManagerCompatApi24.java
index 7067e01..e5f7a7b 100644
--- a/compat/api24/android/support/v4/os/UserManagerCompatApi24.java
+++ b/compat/api24/android/support/v4/os/UserManagerCompatApi24.java
@@ -18,8 +18,12 @@
 
 import android.content.Context;
 import android.os.UserManager;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /** {@hide} */
+@RestrictTo(GROUP_ID)
 public class UserManagerCompatApi24 {
     public static boolean isUserUnlocked(Context context) {
         return context.getSystemService(UserManager.class).isUserUnlocked();
diff --git a/compat/gingerbread/android/support/v4/animation/AnimatorListenerCompat.java b/compat/gingerbread/android/support/v4/animation/AnimatorListenerCompat.java
index c70d6bc..d59ca7d 100644
--- a/compat/gingerbread/android/support/v4/animation/AnimatorListenerCompat.java
+++ b/compat/gingerbread/android/support/v4/animation/AnimatorListenerCompat.java
@@ -16,6 +16,10 @@
 
 package android.support.v4.animation;
 
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * <p>An animation listener that receives notifications from an animation.
  * Notifications indicate animation related events, such as the end or the
@@ -23,6 +27,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface AnimatorListenerCompat {
 
     /**
diff --git a/compat/gingerbread/android/support/v4/animation/AnimatorProvider.java b/compat/gingerbread/android/support/v4/animation/AnimatorProvider.java
index ca897dc..51d4bb0 100644
--- a/compat/gingerbread/android/support/v4/animation/AnimatorProvider.java
+++ b/compat/gingerbread/android/support/v4/animation/AnimatorProvider.java
@@ -24,8 +24,6 @@
  * Before Honeycomb, it uses a simple Handler to mimic animation callback.
  * <p>
  * This is only a minimal implementation which is why this class is hidden.
- *
- * @hide
  */
 interface AnimatorProvider {
 
diff --git a/compat/gingerbread/android/support/v4/animation/AnimatorUpdateListenerCompat.java b/compat/gingerbread/android/support/v4/animation/AnimatorUpdateListenerCompat.java
index acbcccf..ccfbbe2 100644
--- a/compat/gingerbread/android/support/v4/animation/AnimatorUpdateListenerCompat.java
+++ b/compat/gingerbread/android/support/v4/animation/AnimatorUpdateListenerCompat.java
@@ -16,6 +16,10 @@
 
 package android.support.v4.animation;
 
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Implementors of this interface can add themselves as update listeners
  * to a <code>ValueAnimator</code> instance to receive callbacks on every animation
@@ -24,6 +28,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface AnimatorUpdateListenerCompat {
 
     /**
diff --git a/compat/gingerbread/android/support/v4/animation/GingerbreadAnimatorCompatProvider.java b/compat/gingerbread/android/support/v4/animation/GingerbreadAnimatorCompatProvider.java
index 8c6d097..83e2d58 100644
--- a/compat/gingerbread/android/support/v4/animation/GingerbreadAnimatorCompatProvider.java
+++ b/compat/gingerbread/android/support/v4/animation/GingerbreadAnimatorCompatProvider.java
@@ -25,8 +25,6 @@
  * Provides similar functionality to Animators on platforms prior to Honeycomb.
  * <p>
  * This is not a fully implemented API which is why it is not public.
- *
- * @hide
  */
 class GingerbreadAnimatorCompatProvider implements AnimatorProvider {
 
diff --git a/compat/gingerbread/android/support/v4/animation/ValueAnimatorCompat.java b/compat/gingerbread/android/support/v4/animation/ValueAnimatorCompat.java
index 07cc602..eceeeb7 100644
--- a/compat/gingerbread/android/support/v4/animation/ValueAnimatorCompat.java
+++ b/compat/gingerbread/android/support/v4/animation/ValueAnimatorCompat.java
@@ -16,13 +16,17 @@
 
 package android.support.v4.animation;
 
+import android.support.annotation.RestrictTo;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Compatibility implementation for {@code android.animation.ValueAnimator}.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface ValueAnimatorCompat {
 
     public void setTarget(View view);
diff --git a/compat/gingerbread/android/support/v4/app/BundleCompatGingerbread.java b/compat/gingerbread/android/support/v4/app/BundleCompatGingerbread.java
index ce65f1b..b232baa 100644
--- a/compat/gingerbread/android/support/v4/app/BundleCompatGingerbread.java
+++ b/compat/gingerbread/android/support/v4/app/BundleCompatGingerbread.java
@@ -23,9 +23,6 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
-/**
- * @hide
- */
 class BundleCompatGingerbread {
     private static final String TAG = "BundleCompatGingerbread";
 
diff --git a/compat/gingerbread/android/support/v4/app/NotificationCompatBase.java b/compat/gingerbread/android/support/v4/app/NotificationCompatBase.java
index bcaaed6..e4d0f2b 100644
--- a/compat/gingerbread/android/support/v4/app/NotificationCompatBase.java
+++ b/compat/gingerbread/android/support/v4/app/NotificationCompatBase.java
@@ -20,10 +20,14 @@
 import android.app.PendingIntent;
 import android.content.Context;
 import android.os.Bundle;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class NotificationCompatBase {
 
     public static abstract class Action {
diff --git a/compat/gingerbread/android/support/v4/graphics/drawable/DrawableWrapper.java b/compat/gingerbread/android/support/v4/graphics/drawable/DrawableWrapper.java
index 2cfe4ea..94307dd 100644
--- a/compat/gingerbread/android/support/v4/graphics/drawable/DrawableWrapper.java
+++ b/compat/gingerbread/android/support/v4/graphics/drawable/DrawableWrapper.java
@@ -17,6 +17,9 @@
 package android.support.v4.graphics.drawable;
 
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * Interface which allows a {@link android.graphics.drawable.Drawable} to get/set wrapped
@@ -24,6 +27,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface DrawableWrapper {
     Drawable getWrappedDrawable();
     void setWrappedDrawable(Drawable drawable);
diff --git a/compat/gingerbread/android/support/v4/graphics/drawable/TintAwareDrawable.java b/compat/gingerbread/android/support/v4/graphics/drawable/TintAwareDrawable.java
index e59d9f2..d51fe8a 100644
--- a/compat/gingerbread/android/support/v4/graphics/drawable/TintAwareDrawable.java
+++ b/compat/gingerbread/android/support/v4/graphics/drawable/TintAwareDrawable.java
@@ -20,6 +20,9 @@
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.ColorInt;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * Interface which allows a {@link android.graphics.drawable.Drawable} to receive tinting calls
@@ -27,6 +30,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface TintAwareDrawable {
     void setTint(@ColorInt int tint);
     void setTintList(ColorStateList tint);
diff --git a/compat/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java b/compat/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
index f1b2d82..49495b2 100644
--- a/compat/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
+++ b/compat/honeycomb/android/support/v4/app/NotificationBuilderWithBuilderAccessor.java
@@ -17,6 +17,9 @@
 package android.support.v4.app;
 
 import android.app.Notification;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * Interface implemented by notification compat builders that support
@@ -25,6 +28,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface NotificationBuilderWithBuilderAccessor {
     public Notification.Builder getBuilder();
     public Notification build();
diff --git a/compat/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java b/compat/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java
index fa6af47..f0a9b66 100644
--- a/compat/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java
+++ b/compat/honeycomb/android/support/v4/content/ExecutorCompatHoneycomb.java
@@ -22,7 +22,6 @@
 
 /**
  * Implementation of parallel executor compatibility that can call Honeycomb APIs.
- * @hide
  */
 class ExecutorCompatHoneycomb {
     public static Executor getParallelExecutor() {
diff --git a/compat/honeycomb_mr1/android/support/v4/animation/HoneycombMr1AnimatorCompatProvider.java b/compat/honeycomb_mr1/android/support/v4/animation/HoneycombMr1AnimatorCompatProvider.java
index 1f9f8c6..5133a8a 100644
--- a/compat/honeycomb_mr1/android/support/v4/animation/HoneycombMr1AnimatorCompatProvider.java
+++ b/compat/honeycomb_mr1/android/support/v4/animation/HoneycombMr1AnimatorCompatProvider.java
@@ -27,8 +27,6 @@
  * Uses framework Animators to provide ValueAnimatorCompat interface.
  * <p>
  * This is not a fully implemented API which is why it is not public.
- *
- * @hide
  */
 class HoneycombMr1AnimatorCompatProvider implements AnimatorProvider {
 
diff --git a/compat/ics/android/support/v4/net/DatagramSocketWrapper.java b/compat/ics/android/support/v4/net/DatagramSocketWrapper.java
index d7646d9..2a316b0 100644
--- a/compat/ics/android/support/v4/net/DatagramSocketWrapper.java
+++ b/compat/ics/android/support/v4/net/DatagramSocketWrapper.java
@@ -27,7 +27,6 @@
 import java.net.SocketException;
 import java.net.SocketImpl;
 
-/** {@hide} */
 class DatagramSocketWrapper extends Socket {
     public DatagramSocketWrapper(DatagramSocket socket, FileDescriptor fd) throws SocketException {
         super(new DatagramSocketImplWrapper(socket, fd));
diff --git a/compat/java/android/support/v4/animation/AnimatorCompatHelper.java b/compat/java/android/support/v4/animation/AnimatorCompatHelper.java
index 389719e..201268a 100644
--- a/compat/java/android/support/v4/animation/AnimatorCompatHelper.java
+++ b/compat/java/android/support/v4/animation/AnimatorCompatHelper.java
@@ -17,11 +17,15 @@
 package android.support.v4.animation;
 
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class AnimatorCompatHelper {
 
     private final static AnimatorProvider IMPL;
diff --git a/compat/java/android/support/v4/app/AppOpsManagerCompat.java b/compat/java/android/support/v4/app/AppOpsManagerCompat.java
index c0058a9..06da861 100644
--- a/compat/java/android/support/v4/app/AppOpsManagerCompat.java
+++ b/compat/java/android/support/v4/app/AppOpsManagerCompat.java
@@ -48,6 +48,9 @@
     public static final int MODE_DEFAULT = 3;
 
     private static class AppOpsManagerImpl {
+        AppOpsManagerImpl() {
+        }
+
         public String permissionToOp(String permission) {
             return null;
         }
@@ -62,6 +65,9 @@
     }
 
     private static class AppOpsManager23 extends AppOpsManagerImpl {
+        AppOpsManager23() {
+        }
+
         @Override
         public String permissionToOp(String permission) {
             return AppOpsManagerCompat23.permissionToOp(permission);
diff --git a/compat/java/android/support/v4/app/NotificationCompat.java b/compat/java/android/support/v4/app/NotificationCompat.java
index cb02f41..fdf5a87 100644
--- a/compat/java/android/support/v4/app/NotificationCompat.java
+++ b/compat/java/android/support/v4/app/NotificationCompat.java
@@ -28,6 +28,7 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.support.annotation.ColorInt;
+import android.support.annotation.RestrictTo;
 import android.support.v4.os.BuildCompat;
 import android.support.v4.view.GravityCompat;
 import android.view.Gravity;
@@ -37,6 +38,8 @@
 import java.util.Collections;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for accessing features in {@link android.app.Notification}
  * introduced after API level 4 in a backwards compatible fashion.
@@ -485,7 +488,7 @@
      */
     public static final String CATEGORY_STATUS = NotificationCompatApi21.CATEGORY_STATUS;
 
-    private static final NotificationCompatImpl IMPL;
+    static final NotificationCompatImpl IMPL;
 
     interface NotificationCompatImpl {
         public Notification build(Builder b, BuilderExtender extender);
@@ -510,6 +513,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected static class BuilderExtender {
         public Notification build(Builder b, NotificationBuilderWithBuilderAccessor builder) {
             Notification n = builder.build();
@@ -867,14 +871,14 @@
         }
     }
 
-    private static void addActionsToBuilder(NotificationBuilderWithActions builder,
+    static void addActionsToBuilder(NotificationBuilderWithActions builder,
             ArrayList<Action> actions) {
         for (Action action : actions) {
             builder.addAction(action);
         }
     }
 
-    private static void addStyleToBuilderJellybean(NotificationBuilderWithBuilderAccessor builder,
+    static void addStyleToBuilderJellybean(NotificationBuilderWithBuilderAccessor builder,
             Style style) {
         if (style != null) {
             if (style instanceof BigTextStyle) {
@@ -904,7 +908,7 @@
         }
     }
 
-    private static void addStyleToBuilderApi24(NotificationBuilderWithBuilderAccessor builder,
+    static void addStyleToBuilderApi24(NotificationBuilderWithBuilderAccessor builder,
             Style style) {
         if (style != null) {
             if (style instanceof MessagingStyle) {
@@ -984,30 +988,40 @@
         // extender.
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public Context mContext;
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public CharSequence mContentTitle;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public CharSequence mContentText;
         PendingIntent mContentIntent;
         PendingIntent mFullScreenIntent;
         RemoteViews mTickerView;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public Bitmap mLargeIcon;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public CharSequence mContentInfo;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public int mNumber;
         int mPriority;
         boolean mShowWhen = true;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public boolean mUseChronometer;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public Style mStyle;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public CharSequence mSubText;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public CharSequence[] mRemoteInputHistory;
         int mProgressMax;
         int mProgress;
@@ -1016,6 +1030,7 @@
         boolean mGroupSummary;
         String mSortKey;
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public ArrayList<Action> mActions = new ArrayList<Action>();
         boolean mLocalOnly = false;
         String mCategory;
@@ -1028,6 +1043,7 @@
         RemoteViews mHeadsUpContentView;
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public Notification mNotification = new Notification();
         public ArrayList<String> mPeople;
 
@@ -1730,6 +1746,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         protected BuilderExtender getExtender() {
             return new BuilderExtender();
         }
@@ -1745,6 +1762,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public RemoteViews getContentView() {
             return mContentView;
         }
@@ -1752,6 +1770,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public RemoteViews getBigContentView() {
             return mBigContentView;
         }
@@ -1759,6 +1778,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public RemoteViews getHeadsUpContentView() {
             return mHeadsUpContentView;
         }
@@ -1768,6 +1788,7 @@
          *
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public long getWhenIfShowing() {
             return mShowWhen ? mNotification.when : 0;
         }
@@ -1777,6 +1798,7 @@
          *
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public int getPriority() {
             return mPriority;
         }
@@ -1786,6 +1808,7 @@
          *
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public int getColor() {
             return mColor;
         }
@@ -1796,6 +1819,7 @@
          *
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         protected CharSequence resolveText() {
             return mContentText;
         }
@@ -1805,6 +1829,7 @@
          *
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         protected CharSequence resolveTitle() {
             return mContentTitle;
         }
@@ -1843,6 +1868,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         // TODO: implement for all styles
         public void addCompatExtras(Bundle extras) {
         }
@@ -1850,6 +1876,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         // TODO: implement for all styles
         protected void restoreFromCompatExtras(Bundle extras) {
         }
@@ -2140,6 +2167,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         @Override
         protected void restoreFromCompatExtras(Bundle extras) {
             mMessages.clear();
@@ -2385,7 +2413,7 @@
      * to attach actions.
      */
     public static class Action extends NotificationCompatBase.Action {
-        private final Bundle mExtras;
+        final Bundle mExtras;
         private final RemoteInput[] mRemoteInputs;
         private boolean mAllowGeneratedReplies = false;
 
@@ -2407,7 +2435,7 @@
             this(icon, title, intent, new Bundle(), null, false);
         }
 
-        private Action(int icon, CharSequence title, PendingIntent intent, Bundle extras,
+        Action(int icon, CharSequence title, PendingIntent intent, Bundle extras,
                 RemoteInput[] remoteInputs, boolean allowGeneratedReplies) {
             this.icon = icon;
             this.title = NotificationCompat.Builder.limitCharSequenceLength(title);
@@ -2827,6 +2855,7 @@
         }
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public static final Factory FACTORY = new Factory() {
             @Override
             public NotificationCompatBase.Action build(int icon, CharSequence title,
@@ -3891,7 +3920,6 @@
                 return mLatestTimestamp;
             }
 
-            /** @hide */
             static final Factory FACTORY = new Factory() {
                 @Override
                 public UnreadConversation build(
@@ -4006,7 +4034,7 @@
      * Update the bundle to have a typed array so fetches in the future don't need
      * to do an array copy.
      */
-    private static Notification[] getNotificationArrayFromBundle(Bundle bundle, String key) {
+    static Notification[] getNotificationArrayFromBundle(Bundle bundle, String key) {
         Parcelable[] array = bundle.getParcelableArray(key);
         if (array instanceof Notification[] || array == null) {
             return (Notification[]) array;
diff --git a/compat/java/android/support/v4/app/NotificationCompatSideChannelService.java b/compat/java/android/support/v4/app/NotificationCompatSideChannelService.java
index ee4c1e6..f633076 100644
--- a/compat/java/android/support/v4/app/NotificationCompatSideChannelService.java
+++ b/compat/java/android/support/v4/app/NotificationCompatSideChannelService.java
@@ -71,6 +71,9 @@
     public abstract void cancelAll(String packageName);
 
     private class NotificationSideChannelStub extends INotificationSideChannel.Stub {
+        NotificationSideChannelStub() {
+        }
+
         @Override
         public void notify(String packageName, int id, String tag, Notification notification)
                 throws RemoteException {
@@ -106,7 +109,7 @@
         }
     }
 
-    private void checkPermission(int callingUid, String packageName) {
+    void checkPermission(int callingUid, String packageName) {
         for (String validPackage : getPackageManager().getPackagesForUid(callingUid)) {
             if (validPackage.equals(packageName)) {
                 return;
diff --git a/compat/java/android/support/v4/app/NotificationManagerCompat.java b/compat/java/android/support/v4/app/NotificationManagerCompat.java
index 3763e7b..f2010a3 100644
--- a/compat/java/android/support/v4/app/NotificationManagerCompat.java
+++ b/compat/java/android/support/v4/app/NotificationManagerCompat.java
@@ -83,7 +83,7 @@
     /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
     private static final String SETTING_ENABLED_NOTIFICATION_LISTENERS =
             "enabled_notification_listeners";
-    private static final int SIDE_CHANNEL_BIND_FLAGS;
+    static final int SIDE_CHANNEL_BIND_FLAGS;
 
     /** Cache of enabled notification listener components */
     private static final Object sEnabledNotificationListenersLock = new Object();
diff --git a/compat/java/android/support/v4/app/RemoteInput.java b/compat/java/android/support/v4/app/RemoteInput.java
index 99b018d..9208cf6 100644
--- a/compat/java/android/support/v4/app/RemoteInput.java
+++ b/compat/java/android/support/v4/app/RemoteInput.java
@@ -19,8 +19,11 @@
 import android.content.Intent;
 import android.os.Build;
 import android.os.Bundle;
+import android.support.annotation.RestrictTo;
 import android.util.Log;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for using the {@link android.app.RemoteInput} API
  * introduced after API level 4 in a backwards compatible fashion.
@@ -40,7 +43,7 @@
     private final boolean mAllowFreeFormInput;
     private final Bundle mExtras;
 
-    private RemoteInput(String resultKey, CharSequence label, CharSequence[] choices,
+    RemoteInput(String resultKey, CharSequence label, CharSequence[] choices,
             boolean allowFreeFormInput, Bundle extras) {
         this.mResultKey = resultKey;
         this.mLabel = label;
@@ -265,6 +268,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public static final Factory FACTORY = new Factory() {
         @Override
         public RemoteInput build(String resultKey,
diff --git a/compat/java/android/support/v4/app/ServiceCompat.java b/compat/java/android/support/v4/app/ServiceCompat.java
index daa3756..37b7ab9 100644
--- a/compat/java/android/support/v4/app/ServiceCompat.java
+++ b/compat/java/android/support/v4/app/ServiceCompat.java
@@ -19,11 +19,14 @@
 import android.app.Notification;
 import android.app.Service;
 import android.support.annotation.IntDef;
+import android.support.annotation.RestrictTo;
 import android.support.v4.os.BuildCompat;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for accessing features in {@link android.app.Service}
  * introduced after API level 9 in a backwards compatible fashion.
@@ -74,6 +77,7 @@
     public static final int STOP_FOREGROUND_DETACH = 1<<1;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef(flag = true,
             value = {
                     STOP_FOREGROUND_REMOVE,
diff --git a/compat/java/android/support/v4/app/ShareCompat.java b/compat/java/android/support/v4/app/ShareCompat.java
index 27dc48f..2c82c96 100644
--- a/compat/java/android/support/v4/app/ShareCompat.java
+++ b/compat/java/android/support/v4/app/ShareCompat.java
@@ -150,7 +150,7 @@
         }
     }
 
-    private static ShareCompatImpl IMPL;
+    static ShareCompatImpl IMPL;
 
     static {
         if (Build.VERSION.SDK_INT >= 16) {
diff --git a/compat/java/android/support/v4/content/ModernAsyncTask.java b/compat/java/android/support/v4/content/ModernAsyncTask.java
index 34724db..bb80bb6 100644
--- a/compat/java/android/support/v4/content/ModernAsyncTask.java
+++ b/compat/java/android/support/v4/content/ModernAsyncTask.java
@@ -35,6 +35,9 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Process;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * Copy of the required parts of {@link android.os.AsyncTask} from Android 3.0 that is
@@ -83,7 +86,7 @@
 
     private volatile Status mStatus = Status.PENDING;
 
-    private final AtomicBoolean mTaskInvoked = new AtomicBoolean();
+    final AtomicBoolean mTaskInvoked = new AtomicBoolean();
 
     /**
      * Indicates the current status of the task. Each status will be set only once
@@ -114,6 +117,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public static void setDefaultExecutor(Executor exec) {
         sDefaultExecutor = exec;
     }
@@ -161,14 +165,14 @@
         };
     }
 
-    private void postResultIfNotInvoked(Result result) {
+    void postResultIfNotInvoked(Result result) {
         final boolean wasTaskInvoked = mTaskInvoked.get();
         if (!wasTaskInvoked) {
             postResult(result);
         }
     }
 
-    private Result postResult(Result result) {
+    Result postResult(Result result) {
         Message message = getHandler().obtainMessage(MESSAGE_POST_RESULT,
                 new AsyncTaskResult<Result>(this, result));
         message.sendToTarget();
@@ -469,7 +473,7 @@
         }
     }
 
-    private void finish(Result result) {
+    void finish(Result result) {
         if (isCancelled()) {
             onCancelled(result);
         } else {
@@ -501,6 +505,9 @@
 
     private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
         Params[] mParams;
+
+        WorkerRunnable() {
+        }
     }
 
     @SuppressWarnings({"RawUseOfParameterizedType"})
diff --git a/compat/java/android/support/v4/content/SharedPreferencesCompat.java b/compat/java/android/support/v4/content/SharedPreferencesCompat.java
index e748f48..25c65b0 100644
--- a/compat/java/android/support/v4/content/SharedPreferencesCompat.java
+++ b/compat/java/android/support/v4/content/SharedPreferencesCompat.java
@@ -27,6 +27,9 @@
         private static EditorCompat sInstance;
 
         private static class Helper {
+            Helper() {
+            }
+
             public void apply(@NonNull SharedPreferences.Editor editor) {
                 try {
                     editor.apply();
diff --git a/compat/java/android/support/v4/content/res/ConfigurationHelper.java b/compat/java/android/support/v4/content/res/ConfigurationHelper.java
index ebf6df5..b821bd6 100644
--- a/compat/java/android/support/v4/content/res/ConfigurationHelper.java
+++ b/compat/java/android/support/v4/content/res/ConfigurationHelper.java
@@ -49,6 +49,9 @@
     }
 
     private static class GingerbreadImpl implements ConfigurationHelperImpl {
+        GingerbreadImpl() {
+        }
+
         @Override
         public int getScreenHeightDp(@NonNull Resources resources) {
             return ConfigurationHelperGingerbread.getScreenHeightDp(resources);
@@ -71,6 +74,9 @@
     }
 
     private static class HoneycombMr2Impl extends GingerbreadImpl {
+        HoneycombMr2Impl() {
+        }
+
         @Override
         public int getScreenHeightDp(@NonNull Resources resources) {
             return ConfigurationHelperHoneycombMr2.getScreenHeightDp(resources);
@@ -88,6 +94,9 @@
     }
 
     private static class JellybeanMr1Impl extends HoneycombMr2Impl {
+        JellybeanMr1Impl() {
+        }
+
         @Override
         public int getDensityDpi(@NonNull Resources resources) {
             return ConfigurationHelperJellybeanMr1.getDensityDpi(resources);
diff --git a/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java b/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
index 10663a2..f01ac17 100644
--- a/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
+++ b/compat/java/android/support/v4/hardware/fingerprint/FingerprintManagerCompat.java
@@ -267,7 +267,7 @@
             }
         }
 
-        private static CryptoObject unwrapCryptoObject(
+        static CryptoObject unwrapCryptoObject(
                 FingerprintManagerCompatApi23.CryptoObject cryptoObject) {
             if (cryptoObject == null) {
                 return null;
diff --git a/compat/java/android/support/v4/internal/package-info.java b/compat/java/android/support/v4/internal/package-info.java
new file mode 100644
index 0000000..4efb10a
--- /dev/null
+++ b/compat/java/android/support/v4/internal/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * @hide
+ */
+@RestrictTo(GROUP_ID)
+package android.support.v4.internal;
+
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
\ No newline at end of file
diff --git a/compat/java/android/support/v4/internal/view/SupportMenu.java b/compat/java/android/support/v4/internal/view/SupportMenu.java
index 5754062..6a3b126 100644
--- a/compat/java/android/support/v4/internal/view/SupportMenu.java
+++ b/compat/java/android/support/v4/internal/view/SupportMenu.java
@@ -16,6 +16,10 @@
 
 package android.support.v4.internal.view;
 
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Interface for managing the items in a menu.
  *
@@ -25,39 +29,32 @@
  * @see android.view.Menu
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface SupportMenu extends android.view.Menu {
 
     /**
      * This is the part of an order integer that the user can provide.
-     *
-     * @hide
      */
-    static final int USER_MASK = 0x0000ffff;
+    int USER_MASK = 0x0000ffff;
+
     /**
      * Bit shift of the user portion of the order integer.
-     *
-     * @hide
      */
-    static final int USER_SHIFT = 0;
+    int USER_SHIFT = 0;
 
     /**
      * This is the part of an order integer that supplies the category of the item.
-     *
-     * @hide
      */
-    static final int CATEGORY_MASK = 0xffff0000;
+    int CATEGORY_MASK = 0xffff0000;
+
     /**
      * Bit shift of the category portion of the order integer.
-     *
-     * @hide
      */
-    static final int CATEGORY_SHIFT = 16;
+    int CATEGORY_SHIFT = 16;
 
     /**
      * Flag which stops the Menu being closed when a sub menu is opened
-     *
-     * @hide
      */
-    static final int FLAG_KEEP_OPEN_ON_SUBMENU_OPENED = 4;
+    int FLAG_KEEP_OPEN_ON_SUBMENU_OPENED = 4;
 }
 
diff --git a/compat/java/android/support/v4/internal/view/SupportMenuItem.java b/compat/java/android/support/v4/internal/view/SupportMenuItem.java
index 0a1bccb..3e3ac1a 100644
--- a/compat/java/android/support/v4/internal/view/SupportMenuItem.java
+++ b/compat/java/android/support/v4/internal/view/SupportMenuItem.java
@@ -16,11 +16,14 @@
 
 package android.support.v4.internal.view;
 
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ActionProvider;
 import android.support.v4.view.MenuItemCompat;
 import android.view.MenuItem;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Interface for direct access to a previously created menu item.
  *
@@ -30,6 +33,7 @@
  * @see android.view.MenuItem
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface SupportMenuItem extends android.view.MenuItem {
     /*
     * These should be kept in sync with attrs.xml enum constants for showAsAction
@@ -37,30 +41,30 @@
     /**
      * Never show this item as a button in an Action Bar.
      */
-    public static final int SHOW_AS_ACTION_NEVER = 0;
+    int SHOW_AS_ACTION_NEVER = 0;
     /**
      * Show this item as a button in an Action Bar if the system decides there is room for it.
      */
-    public static final int SHOW_AS_ACTION_IF_ROOM = 1;
+    int SHOW_AS_ACTION_IF_ROOM = 1;
     /**
      * Always show this item as a button in an Action Bar.
      * Use sparingly! If too many items are set to always show in the Action Bar it can
      * crowd the Action Bar and degrade the user experience on devices with smaller screens.
      * A good rule of thumb is to have no more than 2 items set to always show at a time.
      */
-    public static final int SHOW_AS_ACTION_ALWAYS = 2;
+    int SHOW_AS_ACTION_ALWAYS = 2;
 
     /**
      * When this item is in the action bar, always show it with a text label even if it also has an
      * icon specified.
      */
-    public static final int SHOW_AS_ACTION_WITH_TEXT = 4;
+    int SHOW_AS_ACTION_WITH_TEXT = 4;
 
     /**
      * This item's action view collapses to a normal menu item. When expanded, the action view
      * temporarily takes over a larger segment of its container.
      */
-    public static final int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8;
+    int SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8;
 
     /**
      * Sets how this item should display in the presence of an Action Bar. The parameter actionEnum
@@ -75,7 +79,7 @@
      * @see android.app.ActionBar
      * @see #setActionView(View)
      */
-    public void setShowAsAction(int actionEnum);
+    void setShowAsAction(int actionEnum);
 
     /**
      * Sets how this item should display in the presence of an Action Bar.
@@ -95,7 +99,7 @@
      * @see android.app.ActionBar
      * @see #setActionView(View)
      */
-    public MenuItem setShowAsActionFlags(int actionEnum);
+    MenuItem setShowAsActionFlags(int actionEnum);
 
     /**
      * Set an action view for this menu item. An action view will be displayed in place
@@ -109,7 +113,7 @@
      * @return This Item so additional setters can be called.
      * @see #setShowAsAction(int)
      */
-    public MenuItem setActionView(View view);
+    MenuItem setActionView(View view);
 
     /**
      * Set an action view for this menu item. An action view will be displayed in place
@@ -123,7 +127,7 @@
      * @return This Item so additional setters can be called.
      * @see #setShowAsAction(int)
      */
-    public MenuItem setActionView(int resId);
+    MenuItem setActionView(int resId);
 
     /**
      * Returns the currently set action view for this menu item.
@@ -132,7 +136,7 @@
      * @see #setActionView(View)
      * @see #setShowAsAction(int)
      */
-    public View getActionView();
+    View getActionView();
 
     /**
      * Sets the {@link android.support.v4.view.ActionProvider} responsible for creating an action view if
@@ -147,7 +151,7 @@
      * @return This Item so additional setters can be called.
      * @see android.support.v4.view.ActionProvider
      */
-    public SupportMenuItem setSupportActionProvider(ActionProvider actionProvider);
+    SupportMenuItem setSupportActionProvider(ActionProvider actionProvider);
 
     /**
      * Gets the {@link ActionProvider}.
@@ -156,7 +160,7 @@
      * @see ActionProvider
      * @see #setSupportActionProvider(ActionProvider)
      */
-    public ActionProvider getSupportActionProvider();
+    ActionProvider getSupportActionProvider();
 
     /**
      * Expand the action view associated with this menu item. The menu item must have an action view
@@ -167,7 +171,7 @@
      *
      * @return true if the action view was expanded, false otherwise.
      */
-    public boolean expandActionView();
+    boolean expandActionView();
 
     /**
      * Collapse the action view associated with this menu item. The menu item must have an action
@@ -179,7 +183,7 @@
      *
      * @return true if the action view was collapsed, false otherwise.
      */
-    public boolean collapseActionView();
+    boolean collapseActionView();
 
     /**
      * Returns true if this menu item's action view has been expanded.
@@ -190,7 +194,7 @@
      * @see #SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW
      * @see android.support.v4.view.MenuItemCompat.OnActionExpandListener
      */
-    public boolean isActionViewExpanded();
+    boolean isActionViewExpanded();
 
     /**
      * Set an {@link android.support.v4.view.MenuItemCompat.OnActionExpandListener} on this menu item to be notified when the associated
@@ -200,5 +204,5 @@
      * @param listener Listener that will respond to expand/collapse events
      * @return This menu item instance for call chaining
      */
-    public SupportMenuItem setSupportOnActionExpandListener(MenuItemCompat.OnActionExpandListener listener);
+    SupportMenuItem setSupportOnActionExpandListener(MenuItemCompat.OnActionExpandListener listener);
 }
\ No newline at end of file
diff --git a/compat/java/android/support/v4/internal/view/SupportSubMenu.java b/compat/java/android/support/v4/internal/view/SupportSubMenu.java
index 4f9bd39..3a26e70 100644
--- a/compat/java/android/support/v4/internal/view/SupportSubMenu.java
+++ b/compat/java/android/support/v4/internal/view/SupportSubMenu.java
@@ -16,6 +16,10 @@
 
 package android.support.v4.internal.view;
 
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Subclass of {@link SupportMenu} for sub menus.
  *
@@ -25,5 +29,6 @@
  * @see android.view.SubMenu
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface SupportSubMenu extends SupportMenu, android.view.SubMenu {
 }
diff --git a/compat/java/android/support/v4/net/ConnectivityManagerCompat.java b/compat/java/android/support/v4/net/ConnectivityManagerCompat.java
index 90479c1..3a85f2e 100644
--- a/compat/java/android/support/v4/net/ConnectivityManagerCompat.java
+++ b/compat/java/android/support/v4/net/ConnectivityManagerCompat.java
@@ -21,6 +21,7 @@
 import android.net.NetworkInfo;
 import android.os.Build;
 import android.support.annotation.IntDef;
+import android.support.annotation.RestrictTo;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -32,6 +33,7 @@
 import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
 import static android.net.ConnectivityManager.TYPE_WIFI;
 import static android.net.ConnectivityManager.TYPE_WIMAX;
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * Helper for accessing features in {@link ConnectivityManager} introduced after
@@ -47,6 +49,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag = false, value = {
             RESTRICT_BACKGROUND_STATUS_DISABLED,
diff --git a/compat/java/android/support/v4/net/TrafficStatsCompat.java b/compat/java/android/support/v4/net/TrafficStatsCompat.java
index 57b8a7e..2e0fa69 100644
--- a/compat/java/android/support/v4/net/TrafficStatsCompat.java
+++ b/compat/java/android/support/v4/net/TrafficStatsCompat.java
@@ -43,6 +43,9 @@
     static class BaseTrafficStatsCompatImpl implements TrafficStatsCompatImpl {
         private static class SocketTags {
             public int statsTag = -1;
+
+            SocketTags() {
+            }
         }
 
         private ThreadLocal<SocketTags> mThreadSocketTags = new ThreadLocal<SocketTags>() {
diff --git a/compat/java/android/support/v4/os/ResultReceiver.java b/compat/java/android/support/v4/os/ResultReceiver.java
index ce66dc6..7a34e8a 100644
--- a/compat/java/android/support/v4/os/ResultReceiver.java
+++ b/compat/java/android/support/v4/os/ResultReceiver.java
@@ -21,8 +21,11 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
+import android.support.annotation.RestrictTo;
 import android.support.v4.os.IResultReceiver;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Generic interface for receiving a callback result from someone.  Use this
  * by creating a subclass and implement {@link #onReceiveResult}, which you can
@@ -37,6 +40,7 @@
  * break if your process goes away for any reason, etc.</p>
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ResultReceiver implements Parcelable {
     final boolean mLocal;
     final Handler mHandler;
diff --git a/compat/java/android/support/v4/text/TextDirectionHeuristicsCompat.java b/compat/java/android/support/v4/text/TextDirectionHeuristicsCompat.java
index b0ede87..d55ae8a 100644
--- a/compat/java/android/support/v4/text/TextDirectionHeuristicsCompat.java
+++ b/compat/java/android/support/v4/text/TextDirectionHeuristicsCompat.java
@@ -75,7 +75,7 @@
     private static final int STATE_FALSE = 1;
     private static final int STATE_UNKNOWN = 2;
 
-    private static int isRtlText(int directionality) {
+    static int isRtlText(int directionality) {
         switch (directionality) {
             case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
                 return STATE_FALSE;
@@ -87,7 +87,7 @@
         }
     }
 
-    private static int isRtlTextOrFormat(int directionality) {
+    static int isRtlTextOrFormat(int directionality) {
         switch (directionality) {
             case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
             case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING:
@@ -151,8 +151,8 @@
     private static class TextDirectionHeuristicInternal extends TextDirectionHeuristicImpl {
         private final boolean mDefaultIsRtl;
 
-        private TextDirectionHeuristicInternal(TextDirectionAlgorithm algorithm,
-                                               boolean defaultIsRtl) {
+        TextDirectionHeuristicInternal(TextDirectionAlgorithm algorithm,
+                boolean defaultIsRtl) {
             super(algorithm);
             mDefaultIsRtl = defaultIsRtl;
         }
diff --git a/compat/java/android/support/v4/text/TextUtilsCompat.java b/compat/java/android/support/v4/text/TextUtilsCompat.java
index f512c16..6acf644 100644
--- a/compat/java/android/support/v4/text/TextUtilsCompat.java
+++ b/compat/java/android/support/v4/text/TextUtilsCompat.java
@@ -25,6 +25,9 @@
 
 public final class TextUtilsCompat {
     private static class TextUtilsCompatImpl {
+        TextUtilsCompatImpl() {
+        }
+
         @NonNull
         public String htmlEncode(@NonNull String s) {
             StringBuilder sb = new StringBuilder();
@@ -100,6 +103,9 @@
     }
 
     private static class TextUtilsCompatJellybeanMr1Impl extends TextUtilsCompatImpl {
+        TextUtilsCompatJellybeanMr1Impl() {
+        }
+
         @Override
         @NonNull
         public String htmlEncode(@NonNull String s) {
@@ -148,8 +154,8 @@
 
     public static final Locale ROOT = new Locale("", "");
 
-    private static String ARAB_SCRIPT_SUBTAG = "Arab";
-    private static String HEBR_SCRIPT_SUBTAG = "Hebr";
+    static String ARAB_SCRIPT_SUBTAG = "Arab";
+    static String HEBR_SCRIPT_SUBTAG = "Hebr";
 
     private TextUtilsCompat() {}
 }
diff --git a/compat/java/android/support/v4/text/util/LinkifyCompat.java b/compat/java/android/support/v4/text/util/LinkifyCompat.java
index 3894f6b..d933c40 100644
--- a/compat/java/android/support/v4/text/util/LinkifyCompat.java
+++ b/compat/java/android/support/v4/text/util/LinkifyCompat.java
@@ -499,5 +499,8 @@
         String url;
         int start;
         int end;
+
+        LinkSpec() {
+        }
     }
 }
diff --git a/compat/java/android/support/v4/util/DebugUtils.java b/compat/java/android/support/v4/util/DebugUtils.java
index 9d4f14e..4f1e95a 100644
--- a/compat/java/android/support/v4/util/DebugUtils.java
+++ b/compat/java/android/support/v4/util/DebugUtils.java
@@ -16,12 +16,17 @@
 
 package android.support.v4.util;
 
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for accessing features in {@link android.util.DebugUtils}
  * introduced after API level 4 in a backwards compatible fashion.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class DebugUtils {
 
     public static void buildShortClassTag(Object cls, StringBuilder out) {
diff --git a/compat/java/android/support/v4/util/LogWriter.java b/compat/java/android/support/v4/util/LogWriter.java
index 53453e3..a250ce4 100644
--- a/compat/java/android/support/v4/util/LogWriter.java
+++ b/compat/java/android/support/v4/util/LogWriter.java
@@ -16,16 +16,20 @@
 
 package android.support.v4.util;
 
+import android.support.annotation.RestrictTo;
 import android.util.Log;
 
 import java.io.Writer;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for accessing features in {@link android.util.LogWriter}
  * introduced after API level 4 in a backwards compatible fashion.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class LogWriter extends Writer {
     private final String mTag;
     private StringBuilder mBuilder = new StringBuilder(128);
diff --git a/compat/java/android/support/v4/util/MapCollections.java b/compat/java/android/support/v4/util/MapCollections.java
index 5ef5410..441f338 100644
--- a/compat/java/android/support/v4/util/MapCollections.java
+++ b/compat/java/android/support/v4/util/MapCollections.java
@@ -25,7 +25,6 @@
 /**
  * Helper for writing standard Java collection interfaces to a data
  * structure like {@link ArrayMap}.
- * @hide
  */
 abstract class MapCollections<K, V> {
     EntrySet mEntrySet;
diff --git a/compat/java/android/support/v4/util/PatternsCompat.java b/compat/java/android/support/v4/util/PatternsCompat.java
index bbd38a1..f09f199 100644
--- a/compat/java/android/support/v4/util/PatternsCompat.java
+++ b/compat/java/android/support/v4/util/PatternsCompat.java
@@ -16,9 +16,13 @@
 
 package android.support.v4.util;
 
+import android.support.annotation.RestrictTo;
+
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Commonly used regular expression patterns.
  */
@@ -29,8 +33,6 @@
      *  List accurate as of 2015/11/24.  List taken from:
      *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
      *  This pattern is auto-generated by frameworks/ex/common/tools/make-iana-tld-pattern.py
-     *
-     *  @hide
      */
     static final String IANA_TOP_LEVEL_DOMAINS =
         "(?:"
@@ -298,6 +300,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final Pattern AUTOLINK_WEB_URL = Pattern.compile(
             "(" + WEB_URL_WITH_PROTOCOL + "|" + WEB_URL_WITHOUT_PROTOCOL + ")");
 
@@ -326,6 +329,7 @@
      * and the special characters #&~!^`{}/=$*?| that are included in RFC5321.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final Pattern AUTOLINK_EMAIL_ADDRESS = Pattern.compile("(" + WORD_BOUNDARY +
             "(?:" + EMAIL_ADDRESS_LOCAL_PART + "@" + EMAIL_ADDRESS_DOMAIN + ")" +
             WORD_BOUNDARY + ")"
diff --git a/compat/java/android/support/v4/util/TimeUtils.java b/compat/java/android/support/v4/util/TimeUtils.java
index 36a1964..3de970f 100644
--- a/compat/java/android/support/v4/util/TimeUtils.java
+++ b/compat/java/android/support/v4/util/TimeUtils.java
@@ -16,14 +16,19 @@
 
 package android.support.v4.util;
 
+import android.support.annotation.RestrictTo;
+
 import java.io.PrintWriter;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for accessing features in {@link android.util.TimeUtils}
  * introduced after API level 4 in a backwards compatible fashion.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class TimeUtils {
     /** @hide Field length that can hold 999 days of time */
     public static final int HUNDRED_DAY_FIELD_LEN = 19;
diff --git a/compat/java/android/support/v4/view/ActionProvider.java b/compat/java/android/support/v4/view/ActionProvider.java
index 070ea46..fcde05e 100644
--- a/compat/java/android/support/v4/view/ActionProvider.java
+++ b/compat/java/android/support/v4/view/ActionProvider.java
@@ -17,11 +17,14 @@
 package android.support.v4.view;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.util.Log;
 import android.view.MenuItem;
 import android.view.SubMenu;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This class is a mediator for accomplishing a given task, for example sharing a file. It is
  * responsible for creating a view that performs an action that accomplishes the task. This class
@@ -270,6 +273,7 @@
      *
      * @hide Pending future API approval
      */
+    @RestrictTo(GROUP_ID)
     public void subUiVisibilityChanged(boolean isVisible) {
         if (mSubUiVisibilityListener != null) {
             mSubUiVisibilityListener.onSubUiVisibilityChanged(isVisible);
@@ -279,6 +283,7 @@
     /**
      * @hide Internal use only
      */
+    @RestrictTo(GROUP_ID)
     public void setSubUiVisibilityListener(SubUiVisibilityListener listener) {
         mSubUiVisibilityListener = listener;
     }
@@ -301,6 +306,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void reset() {
         mVisibilityListener = null;
         mSubUiVisibilityListener = null;
@@ -309,6 +315,7 @@
     /**
      * @hide Internal use only
      */
+    @RestrictTo(GROUP_ID)
     public interface SubUiVisibilityListener {
 
         public void onSubUiVisibilityChanged(boolean isVisible);
diff --git a/compat/java/android/support/v4/view/GestureDetectorCompat.java b/compat/java/android/support/v4/view/GestureDetectorCompat.java
index aaed921..3809605 100644
--- a/compat/java/android/support/v4/view/GestureDetectorCompat.java
+++ b/compat/java/android/support/v4/view/GestureDetectorCompat.java
@@ -69,16 +69,16 @@
         private static final int TAP = 3;
 
         private final Handler mHandler;
-        private final OnGestureListener mListener;
-        private OnDoubleTapListener mDoubleTapListener;
+        final OnGestureListener mListener;
+        OnDoubleTapListener mDoubleTapListener;
 
-        private boolean mStillDown;
-        private boolean mDeferConfirmSingleTap;
+        boolean mStillDown;
+        boolean mDeferConfirmSingleTap;
         private boolean mInLongPress;
         private boolean mAlwaysInTapRegion;
         private boolean mAlwaysInBiggerTapRegion;
 
-        private MotionEvent mCurrentDownEvent;
+        MotionEvent mCurrentDownEvent;
         private MotionEvent mPreviousUpEvent;
 
         /**
@@ -453,7 +453,7 @@
             return (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare);
         }
 
-        private void dispatchLongPress() {
+        void dispatchLongPress() {
             mHandler.removeMessages(TAP);
             mDeferConfirmSingleTap = false;
             mInLongPress = true;
diff --git a/compat/java/android/support/v4/view/MotionEventCompat.java b/compat/java/android/support/v4/view/MotionEventCompat.java
index 111cf58..48ce0f9 100644
--- a/compat/java/android/support/v4/view/MotionEventCompat.java
+++ b/compat/java/android/support/v4/view/MotionEventCompat.java
@@ -74,6 +74,9 @@
      * Interface implementation for devices with at least v14 APIs.
      */
     private static class ICSMotionEventVersionImpl extends HoneycombMr1MotionEventVersionImpl {
+        ICSMotionEventVersionImpl() {
+        }
+
         @Override
         public int getButtonState(MotionEvent event) {
             return MotionEventCompatICS.getButtonState(event);
diff --git a/compat/java/android/support/v4/view/PointerIconCompat.java b/compat/java/android/support/v4/view/PointerIconCompat.java
index 70344b8..809c891 100644
--- a/compat/java/android/support/v4/view/PointerIconCompat.java
+++ b/compat/java/android/support/v4/view/PointerIconCompat.java
@@ -19,8 +19,11 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.support.annotation.RestrictTo;
 import android.support.v4.os.BuildCompat;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for accessing features in {@link android.view.PointerIcon} introduced after API
  * level 4 in a backwards compatible fashion.
@@ -105,6 +108,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public Object getPointerIcon() {
         return mPointerIcon;
     }
diff --git a/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java b/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java
index fe24cc7..30d0ca1 100644
--- a/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java
+++ b/compat/java/android/support/v4/view/ScaleGestureDetectorCompat.java
@@ -31,6 +31,9 @@
     }
 
     private static class BaseScaleGestureDetectorImpl implements ScaleGestureDetectorImpl {
+        BaseScaleGestureDetectorImpl() {
+        }
+
         @Override
         public void setQuickScaleEnabled(Object o, boolean enabled) {
             // Intentionally blank
@@ -43,6 +46,9 @@
     }
 
     private static class ScaleGestureDetectorCompatKitKatImpl implements ScaleGestureDetectorImpl {
+        ScaleGestureDetectorCompatKitKatImpl() {
+        }
+
         @Override
         public void setQuickScaleEnabled(Object o, boolean enabled) {
             ScaleGestureDetectorCompatKitKat.setQuickScaleEnabled(o, enabled);
diff --git a/compat/java/android/support/v4/view/ViewCompat.java b/compat/java/android/support/v4/view/ViewCompat.java
index d9d3cfb..9637e65 100644
--- a/compat/java/android/support/v4/view/ViewCompat.java
+++ b/compat/java/android/support/v4/view/ViewCompat.java
@@ -28,6 +28,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.os.BuildCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeProviderCompat;
@@ -48,6 +49,8 @@
 import java.lang.reflect.Method;
 import java.util.WeakHashMap;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for accessing features in {@link View} introduced after API
  * level 4 in a backwards compatible fashion.
@@ -56,22 +59,24 @@
     private static final String TAG = "ViewCompat";
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({View.FOCUS_LEFT, View.FOCUS_UP, View.FOCUS_RIGHT, View.FOCUS_DOWN,
             View.FOCUS_FORWARD, View.FOCUS_BACKWARD})
     @Retention(RetentionPolicy.SOURCE)
     public @interface FocusDirection {}
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({View.FOCUS_LEFT, View.FOCUS_UP, View.FOCUS_RIGHT, View.FOCUS_DOWN})
     @Retention(RetentionPolicy.SOURCE)
     public @interface FocusRealDirection {}
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({View.FOCUS_FORWARD, View.FOCUS_BACKWARD})
     @Retention(RetentionPolicy.SOURCE)
     public @interface FocusRelativeDirection {}
 
-    /** @hide */
     @IntDef({OVER_SCROLL_ALWAYS, OVER_SCROLL_IF_CONTENT_SCROLLS, OVER_SCROLL_NEVER})
     @Retention(RetentionPolicy.SOURCE)
     private @interface OverScroll {}
@@ -104,7 +109,6 @@
 
     private static final long FAKE_FRAME_TIME = 10;
 
-    /** @hide */
     @IntDef({
             IMPORTANT_FOR_ACCESSIBILITY_AUTO,
             IMPORTANT_FOR_ACCESSIBILITY_YES,
@@ -135,7 +139,6 @@
      */
     public static final int IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS = 0x00000004;
 
-    /** @hide */
     @IntDef({
             ACCESSIBILITY_LIVE_REGION_NONE,
             ACCESSIBILITY_LIVE_REGION_POLITE,
@@ -169,7 +172,6 @@
      */
     public static final int ACCESSIBILITY_LIVE_REGION_ASSERTIVE = 0x00000002;
 
-    /** @hide */
     @IntDef({LAYER_TYPE_NONE, LAYER_TYPE_SOFTWARE, LAYER_TYPE_HARDWARE})
     @Retention(RetentionPolicy.SOURCE)
     private @interface LayerType {}
@@ -222,7 +224,6 @@
      */
     public static final int LAYER_TYPE_HARDWARE = 2;
 
-    /** @hide */
     @IntDef({
             LAYOUT_DIRECTION_LTR,
             LAYOUT_DIRECTION_RTL,
@@ -231,7 +232,6 @@
     @Retention(RetentionPolicy.SOURCE)
     private @interface LayoutDirectionMode {}
 
-    /** @hide */
     @IntDef({
             LAYOUT_DIRECTION_LTR,
             LAYOUT_DIRECTION_RTL
diff --git a/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java b/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
index 3427e26..b92c14d 100644
--- a/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
+++ b/compat/java/android/support/v4/view/ViewPropertyAnimatorCompat.java
@@ -25,9 +25,9 @@
 public final class ViewPropertyAnimatorCompat {
     private static final String TAG = "ViewAnimatorCompat";
     private WeakReference<View> mView;
-    private Runnable mStartAction = null;
-    private Runnable mEndAction = null;
-    private int mOldLayerType = -1;
+    Runnable mStartAction = null;
+    Runnable mEndAction = null;
+    int mOldLayerType = -1;
     // HACK ALERT! Choosing this id knowing that the framework does not use it anywhere
     // internally and apps should use ids higher than it
     static final int LISTENER_TAG_ID = 0x7e000000;
@@ -290,7 +290,7 @@
             // noop
         }
 
-        private void startAnimation(ViewPropertyAnimatorCompat vpa, View view) {
+        void startAnimation(ViewPropertyAnimatorCompat vpa, View view) {
             Object listenerTag = view.getTag(LISTENER_TAG_ID);
             ViewPropertyAnimatorListener listener = null;
             if (listenerTag instanceof ViewPropertyAnimatorListener) {
@@ -319,7 +319,7 @@
             WeakReference<View> mViewRef;
             ViewPropertyAnimatorCompat mVpa;
 
-            private Starter(ViewPropertyAnimatorCompat vpa, View view) {
+            Starter(ViewPropertyAnimatorCompat vpa, View view) {
                 mViewRef = new WeakReference<View>(view);
                 mVpa = vpa;
             }
diff --git a/compat/java/android/support/v4/view/WindowInsetsCompat.java b/compat/java/android/support/v4/view/WindowInsetsCompat.java
index 168d181..79befe9 100644
--- a/compat/java/android/support/v4/view/WindowInsetsCompat.java
+++ b/compat/java/android/support/v4/view/WindowInsetsCompat.java
@@ -50,6 +50,9 @@
     }
 
     private static class WindowInsetsCompatBaseImpl implements WindowInsetsCompatImpl {
+        WindowInsetsCompatBaseImpl() {
+        }
+
         @Override
         public int getSystemWindowInsetLeft(Object insets) {
             return 0;
@@ -142,6 +145,9 @@
     }
 
     private static class WindowInsetsCompatApi20Impl extends WindowInsetsCompatBaseImpl {
+        WindowInsetsCompatApi20Impl() {
+        }
+
         @Override
         public WindowInsetsCompat consumeSystemWindowInsets(Object insets) {
             return new WindowInsetsCompat(
@@ -197,6 +203,9 @@
     }
 
     private static class WindowInsetsCompatApi21Impl extends WindowInsetsCompatApi20Impl {
+        WindowInsetsCompatApi21Impl() {
+        }
+
         @Override
         public WindowInsetsCompat consumeStableInsets(Object insets) {
             return new WindowInsetsCompat(WindowInsetsCompatApi21.consumeStableInsets(insets));
@@ -254,7 +263,7 @@
 
     private final Object mInsets;
 
-    private WindowInsetsCompat(Object insets) {
+    WindowInsetsCompat(Object insets) {
         mInsets = insets;
     }
 
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
index 30b1409..0f0df96 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeInfoCompat.java
@@ -401,7 +401,7 @@
         public static final AccessibilityActionCompat ACTION_SET_PROGRESS =
                 new AccessibilityActionCompat(IMPL.getActionSetProgress());
 
-        private final Object mAction;
+        final Object mAction;
 
         /**
          * Creates a new instance.
@@ -413,7 +413,7 @@
             this(IMPL.newAccessibilityAction(actionId, label));
         }
 
-        private AccessibilityActionCompat(Object action) {
+        AccessibilityActionCompat(Object action) {
             mAction = action;
         }
 
@@ -496,7 +496,7 @@
                     hierarchical));
         }
 
-        private CollectionInfoCompat(Object info) {
+        CollectionInfoCompat(Object info) {
             mInfo = info;
         }
 
@@ -554,7 +554,7 @@
      */
     public static class CollectionItemInfoCompat {
 
-        private final Object mInfo;
+        final Object mInfo;
 
         /**
          * Returns a cached instance if such is available otherwise a new one.
@@ -589,7 +589,7 @@
                     columnIndex, columnSpan, heading));
         }
 
-        private CollectionItemInfoCompat(Object info) {
+        CollectionItemInfoCompat(Object info) {
             mInfo = info;
         }
 
@@ -673,9 +673,9 @@
             return new RangeInfoCompat(IMPL.obtainRangeInfo(type, min, max, current));
         }
 
-        private final Object mInfo;
+        final Object mInfo;
 
-        private RangeInfoCompat(Object info) {
+        RangeInfoCompat(Object info) {
             mInfo = info;
         }
 
@@ -2361,7 +2361,7 @@
         }
     }
 
-    private static final AccessibilityNodeInfoImpl IMPL;
+    static final AccessibilityNodeInfoImpl IMPL;
 
     private final Object mInfo;
 
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
index b7fd696..19d4776 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityNodeProviderCompat.java
@@ -43,6 +43,9 @@
 
     private static class AccessibilityNodeProviderJellyBeanImpl
             extends AccessibilityNodeProviderStubImpl {
+        AccessibilityNodeProviderJellyBeanImpl() {
+        }
+
         @Override
         public Object newAccessibilityNodeProviderBridge(
                 final AccessibilityNodeProviderCompat compat) {
@@ -89,6 +92,9 @@
 
     private static class AccessibilityNodeProviderKitKatImpl
             extends AccessibilityNodeProviderStubImpl {
+        AccessibilityNodeProviderKitKatImpl() {
+        }
+
         @Override
         public Object newAccessibilityNodeProviderBridge(
                 final AccessibilityNodeProviderCompat compat) {
diff --git a/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java b/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
index 53f57fc..bec1dd5 100644
--- a/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
+++ b/compat/java/android/support/v4/view/accessibility/AccessibilityWindowInfoCompat.java
@@ -46,6 +46,9 @@
 
     private static class AccessibilityWindowInfoStubImpl implements AccessibilityWindowInfoImpl {
 
+        AccessibilityWindowInfoStubImpl() {
+        }
+
         @Override
         public Object obtain() {
             return null;
@@ -126,6 +129,9 @@
     }
 
     private static class AccessibilityWindowInfoApi21Impl extends AccessibilityWindowInfoStubImpl {
+        AccessibilityWindowInfoApi21Impl() {
+        }
+
         @Override
         public Object obtain() {
             return AccessibilityWindowInfoCompatApi21.obtain();
@@ -198,6 +204,9 @@
     }
 
     private static class AccessibilityWindowInfoApi24Impl extends AccessibilityWindowInfoApi21Impl {
+        AccessibilityWindowInfoApi24Impl() {
+        }
+
         @Override
         public CharSequence getTitle(Object info) {
             return AccessibilityWindowInfoCompatApi24.getTitle(info);
diff --git a/compat/jellybean-mr2/android/support/v4/app/BundleCompatJellybeanMR2.java b/compat/jellybean-mr2/android/support/v4/app/BundleCompatJellybeanMR2.java
index a567cab..bafefba 100644
--- a/compat/jellybean-mr2/android/support/v4/app/BundleCompatJellybeanMR2.java
+++ b/compat/jellybean-mr2/android/support/v4/app/BundleCompatJellybeanMR2.java
@@ -19,9 +19,6 @@
 import android.os.Bundle;
 import android.os.IBinder;
 
-/**
- * @hide
- */
 class BundleCompatJellybeanMR2 {
     public static IBinder getBinder(Bundle bundle, String key) {
         return bundle.getBinder(key);
diff --git a/compat/jellybean/android/support/v4/app/BundleUtil.java b/compat/jellybean/android/support/v4/app/BundleUtil.java
index fb6350d..c5e9998 100644
--- a/compat/jellybean/android/support/v4/app/BundleUtil.java
+++ b/compat/jellybean/android/support/v4/app/BundleUtil.java
@@ -5,9 +5,6 @@
 
 import java.util.Arrays;
 
-/**
- * @hide
- */
 class BundleUtil {
     /**
      * Get an array of Bundle objects from a parcelable array field in a bundle.
diff --git a/compat/tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java b/compat/tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java
deleted file mode 100644
index 8c1abcc..0000000
--- a/compat/tests/java/android/support/v4/app/NotificationCompatActionWearableExtenderTest.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.compat.test.R;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-
-import java.util.List;
-
-/**
- * Tests for {@link android.support.v4.app.NotificationCompat.Action.WearableExtender}.
- */
-@MediumTest
-public class NotificationCompatActionWearableExtenderTest extends AndroidTestCase {
-
-    private int mIcon;
-    private String mTitle = "Test Title";
-    private PendingIntent mPendingIntent;
-
-    private String mInProgress = "In Progress Label";
-    private String mConfirm = "Confirmation Label";
-    private String mCancel = "Cancelation Label";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mIcon = R.drawable.action_icon;
-        mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
-    }
-
-    // Test that the default empty Extender is equal to the compat version.
-    public void testEmptyEquals() throws Exception {
-        assertExtendersEqual(new Notification.Action.WearableExtender(),
-                new NotificationCompat.Action.WearableExtender());
-    }
-
-    // Test that the fully populated Extender is equal to the compat version.
-    public void testFullEquals() throws Exception {
-        Notification.Action.WearableExtender baseExtender =
-            new Notification.Action.WearableExtender()
-                .setAvailableOffline(true)
-                .setInProgressLabel(mInProgress)
-                .setConfirmLabel(mConfirm)
-                .setCancelLabel(mCancel);
-        NotificationCompat.Action.WearableExtender compatExtender =
-            new NotificationCompat.Action.WearableExtender()
-                .setAvailableOffline(true)
-                .setInProgressLabel(mInProgress)
-                .setConfirmLabel(mConfirm)
-                .setCancelLabel(mCancel);
-        assertExtendersEqual(baseExtender, compatExtender);
-    }
-
-    // Test that the base WearableExtender from an empty Notification is equal to the compat.
-    public void testEmptyNotification() throws Exception {
-        Notification baseNotif = new Notification.Builder(getContext())
-                .build();
-        Notification compatNotif = new NotificationCompat.Builder(getContext())
-                .build();
-
-        assertExtendersFromNotificationEqual(baseNotif, baseNotif);
-        assertExtendersFromNotificationEqual(compatNotif, compatNotif);
-        assertExtendersFromNotificationEqual(baseNotif, compatNotif);
-        assertExtendersFromNotificationEqual(compatNotif, baseNotif);
-    }
-
-    public void testDefaultActionNotification() throws Exception {
-        Notification.Action.Builder baseAction =
-            new Notification.Action.Builder(mIcon, mTitle, mPendingIntent);
-        NotificationCompat.Action.Builder compatAction =
-            new NotificationCompat.Action.Builder(mIcon, mTitle, mPendingIntent);
-
-        Notification.WearableExtender baseNoteExtender =
-                new Notification.WearableExtender()
-                        .addAction(baseAction.build());
-        NotificationCompat.WearableExtender compatNoteExtender =
-                new NotificationCompat.WearableExtender()
-                        .addAction(compatAction.build());
-
-        Notification baseNotif = new Notification.Builder(getContext())
-                .extend(baseNoteExtender).build();
-        Notification compatNotif = new NotificationCompat.Builder(getContext())
-                .extend(compatNoteExtender).build();
-
-        assertExtendersFromNotificationEqual(baseNotif, baseNotif);
-        assertExtendersFromNotificationEqual(compatNotif, compatNotif);
-        assertExtendersFromNotificationEqual(baseNotif, compatNotif);
-        assertExtendersFromNotificationEqual(compatNotif, baseNotif);
-    }
-
-    public void testDefaultActionExtenderNotification() throws Exception {
-        Notification.Action.WearableExtender baseExtender =
-            new Notification.Action.WearableExtender();
-        NotificationCompat.Action.WearableExtender compatExtender =
-            new NotificationCompat.Action.WearableExtender();
-
-        Notification.Action.Builder baseAction =
-            new Notification.Action.Builder(mIcon, mTitle, mPendingIntent)
-                .extend(baseExtender);
-        NotificationCompat.Action.Builder compatAction =
-            new NotificationCompat.Action.Builder(mIcon, mTitle, mPendingIntent)
-                .extend(compatExtender);
-
-        Notification.WearableExtender baseNoteExtender =
-                new Notification.WearableExtender()
-                        .addAction(baseAction.build());
-        NotificationCompat.WearableExtender compatNoteExtender =
-                new NotificationCompat.WearableExtender()
-                        .addAction(compatAction.build());
-
-        Notification baseNotif = new Notification.Builder(getContext())
-                .extend(baseNoteExtender).build();
-        Notification compatNotif = new NotificationCompat.Builder(getContext())
-                .extend(compatNoteExtender).build();
-
-        assertExtendersFromNotificationEqual(baseNotif, baseNotif);
-        assertExtendersFromNotificationEqual(compatNotif, compatNotif);
-        assertExtendersFromNotificationEqual(baseNotif, compatNotif);
-        assertExtendersFromNotificationEqual(compatNotif, baseNotif);
-    }
-
-    public void testFullNotification() throws Exception {
-        Notification.Action.WearableExtender baseExtender =
-            new Notification.Action.WearableExtender()
-                .setAvailableOffline(true)
-                .setInProgressLabel(mInProgress)
-                .setConfirmLabel(mConfirm)
-                .setCancelLabel(mCancel);
-        NotificationCompat.Action.WearableExtender compatExtender =
-            new NotificationCompat.Action.WearableExtender()
-                .setAvailableOffline(true)
-                .setInProgressLabel(mInProgress)
-                .setConfirmLabel(mConfirm)
-                .setCancelLabel(mCancel);
-
-        Notification.Action.Builder baseAction =
-            new Notification.Action.Builder(mIcon, mTitle, mPendingIntent)
-                .extend(baseExtender);
-        NotificationCompat.Action.Builder compatAction =
-            new NotificationCompat.Action.Builder(mIcon, mTitle, mPendingIntent)
-                .extend(compatExtender);
-
-        Notification.WearableExtender baseNoteExtender =
-                new Notification.WearableExtender()
-                        .addAction(baseAction.build());
-        NotificationCompat.WearableExtender compatNoteExtender =
-                new NotificationCompat.WearableExtender()
-                        .addAction(compatAction.build());
-
-        Notification baseNotif = new Notification.Builder(getContext())
-                .extend(baseNoteExtender).build();
-        Notification compatNotif = new NotificationCompat.Builder(getContext())
-                .extend(compatNoteExtender).build();
-
-        assertExtendersFromNotificationEqual(baseNotif, baseNotif);
-        assertExtendersFromNotificationEqual(compatNotif, compatNotif);
-        assertExtendersFromNotificationEqual(baseNotif, compatNotif);
-        assertExtendersFromNotificationEqual(compatNotif, baseNotif);
-    }
-
-    public void testMultipleActionsInANotification() throws Exception {
-        Notification.Action.WearableExtender baseExtender1 =
-            new Notification.Action.WearableExtender()
-                .setAvailableOffline(true)
-                .setInProgressLabel(mInProgress)
-                .setConfirmLabel(mConfirm)
-                .setCancelLabel(mCancel);
-        NotificationCompat.Action.WearableExtender compatExtender1 =
-            new NotificationCompat.Action.WearableExtender()
-                .setAvailableOffline(true)
-                .setInProgressLabel(mInProgress)
-                .setConfirmLabel(mConfirm)
-                .setCancelLabel(mCancel);
-
-        Notification.Action.Builder baseAction1 =
-            new Notification.Action.Builder(mIcon, mTitle, mPendingIntent)
-                .extend(baseExtender1);
-        NotificationCompat.Action.Builder compatAction1 =
-            new NotificationCompat.Action.Builder(mIcon, mTitle, mPendingIntent)
-                .extend(compatExtender1);
-
-        Notification.Action.WearableExtender baseExtender2 =
-            new Notification.Action.WearableExtender()
-                .setAvailableOffline(false)
-                .setInProgressLabel("Alternate Label")
-                .setConfirmLabel("Duplicated Label")
-                .setCancelLabel("Duplicated Label");
-        NotificationCompat.Action.WearableExtender compatExtender2 =
-            new NotificationCompat.Action.WearableExtender()
-                .setAvailableOffline(false)
-                .setInProgressLabel("Alternate Label")
-                .setConfirmLabel("Duplicated Label")
-                .setCancelLabel("Duplicated Label");
-
-        Notification.Action.Builder baseAction2 =
-            new Notification.Action.Builder(mIcon, mTitle, mPendingIntent)
-                .extend(baseExtender2);
-        NotificationCompat.Action.Builder compatAction2 =
-            new NotificationCompat.Action.Builder(mIcon, mTitle, mPendingIntent)
-                .extend(compatExtender2);
-
-        Notification.WearableExtender baseNoteExtender =
-                new Notification.WearableExtender()
-                        .addAction(baseAction1.build())
-                        .addAction(new Notification.Action(R.drawable.action_icon2, "Action1",
-                                mPendingIntent))
-                        .addAction(baseAction2.build());
-        NotificationCompat.WearableExtender compatNoteExtender =
-                new NotificationCompat.WearableExtender()
-                        .addAction(compatAction1.build())
-                        .addAction(new NotificationCompat.Action(R.drawable.action_icon2,
-                                "Action1", mPendingIntent))
-                        .addAction(compatAction2.build());
-
-        Notification baseNotif = new Notification.Builder(getContext())
-                .extend(baseNoteExtender).build();
-        Notification compatNotif = new NotificationCompat.Builder(getContext())
-                .extend(compatNoteExtender).build();
-
-        assertExtendersFromNotificationEqual(baseNotif, baseNotif);
-        assertExtendersFromNotificationEqual(compatNotif, compatNotif);
-        assertExtendersFromNotificationEqual(baseNotif, compatNotif);
-        assertExtendersFromNotificationEqual(compatNotif, baseNotif);
-    }
-
-    private void assertExtendersEqual(Notification.Action.WearableExtender base,
-            NotificationCompat.Action.WearableExtender compat) {
-        assertEquals(base.isAvailableOffline(), compat.isAvailableOffline());
-        assertEquals(base.getInProgressLabel(), compat.getInProgressLabel());
-        assertEquals(base.getConfirmLabel(), compat.getConfirmLabel());
-        assertEquals(base.getCancelLabel(), compat.getCancelLabel());
-    }
-
-    // Parse the Notification using the base parser and the compat parser and confirm
-    // that the WearableExtender bundles are equivelent.
-    private void assertExtendersFromNotificationEqual(Notification first,
-                                                      Notification second) {
-        Notification.WearableExtender baseExtender = new Notification.WearableExtender(first);
-        NotificationCompat.WearableExtender compatExtender =
-            new NotificationCompat.WearableExtender(second);
-        List<Notification.Action> baseArray = baseExtender.getActions();
-        List<NotificationCompat.Action> compatArray = compatExtender.getActions();
-        assertEquals(baseArray.size(), compatArray.size());
-        for (int i = 0; i < baseArray.size(); i++) {
-            // Verify that the key value pairs are equal. We only care about
-            // the bundle in getExtras().getBundle("android.wearable.EXTENSIONS"),
-            // but it doesn't hurt to check them all as long we recurse.
-            assertBundlesEqual(baseArray.get(i).getExtras(),
-                               compatArray.get(i).getExtras());
-            // Verify that the parsed WearableExtentions are equal
-            Notification.Action.WearableExtender base =
-                new Notification.Action.WearableExtender(baseArray.get(i));
-            NotificationCompat.Action.WearableExtender compat =
-                new NotificationCompat.Action.WearableExtender(compatArray.get(i));
-            assertExtendersEqual(base, compat);
-        }
-    }
-
-    private void assertBundlesEqual(Bundle bundle1, Bundle bundle2) {
-        assertEquals(bundle1.size(), bundle2.size());
-        for (String key : bundle1.keySet()) {
-            Object value1 = bundle1.get(key);
-            Object value2 = bundle2.get(key);
-            if (value1 instanceof Bundle && value2 instanceof Bundle) {
-                assertBundlesEqual((Bundle) value1, (Bundle) value2);
-            } else {
-                assertEquals(value1, value2);
-            }
-        }
-    }
-}
diff --git a/compat/tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java b/compat/tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java
deleted file mode 100644
index 4e945dd..0000000
--- a/compat/tests/java/android/support/v4/app/NotificationCompatWearableExtenderTest.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.support.v4.app;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.compat.test.R;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.Gravity;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Tests for {@link android.support.v4.app.NotificationCompat.WearableExtender}.
- */
-@MediumTest
-public class NotificationCompatWearableExtenderTest extends AndroidTestCase {
-    public static final int CUSTOM_CONTENT_HEIGHT_DP = 256;
-
-    private PendingIntent mPendingIntent;
-    private int mCustomContentHeightPx;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mPendingIntent = PendingIntent.getActivity(getContext(), 0, new Intent(), 0);
-
-        mCustomContentHeightPx = Math.round(getContext().getResources().getDisplayMetrics().density
-                * CUSTOM_CONTENT_HEIGHT_DP);
-    }
-
-    public void testEmptyEquals() throws Exception {
-        assertExtendersEqual(new Notification.WearableExtender(),
-                new NotificationCompat.WearableExtender());
-    }
-
-    public void testRealReadCompatEmptyValue() throws Exception {
-        NotificationCompat.WearableExtender compatExtender =
-                new NotificationCompat.WearableExtender();
-        Notification notif = new NotificationCompat.Builder(getContext())
-                .extend(compatExtender)
-                .build();
-
-        assertExtendersEqual(new Notification.WearableExtender(notif), compatExtender);
-        assertExtendersEqual(new Notification.WearableExtender(notif),
-                new NotificationCompat.WearableExtender(notif));
-    }
-
-    public void testCompatReadRealEmptyValue() throws Exception {
-        Notification.WearableExtender realExtender =
-                new Notification.WearableExtender();
-        Notification notif = new Notification.Builder(getContext())
-                .extend(realExtender)
-                .build();
-
-        assertExtendersEqual(realExtender, new NotificationCompat.WearableExtender(notif));
-        assertExtendersEqual(new Notification.WearableExtender(notif),
-                new NotificationCompat.WearableExtender(notif));
-    }
-
-    public void testRealReadCompatValue() throws Exception {
-        RemoteInput.Builder remoteInput = new RemoteInput.Builder("result_key1")
-                .setLabel("label")
-                .setChoices(new CharSequence[] {"choice 1", "choice 2"});
-        remoteInput.getExtras().putString("remoteinput_string", "test");
-        NotificationCompat.Action.Builder action2 = new NotificationCompat.Action.Builder(
-                R.drawable.action_icon, "Test title", mPendingIntent)
-                .addRemoteInput(remoteInput.build())
-                .extend(new NotificationCompat.Action.WearableExtender()
-                        .setAvailableOffline(false)
-                        .setInProgressLabel("In Progress Label")
-                        .setConfirmLabel("Confirmation Label")
-                        .setCancelLabel("Cancelation Label"));
-        // Add an arbitrary key/value.
-        action2.getExtras().putFloat("action_float", 10.5f);
-
-        Notification page2 = new Notification.Builder(getContext())
-                .setContentTitle("page2 title")
-                .extend(new Notification.WearableExtender()
-                        .setContentIcon(R.drawable.content_icon))
-                .build();
-
-        NotificationCompat.WearableExtender compatExtender =
-                new NotificationCompat.WearableExtender()
-                        .addAction(new NotificationCompat.Action(R.drawable.action_icon2, "Action1",
-                                mPendingIntent))
-                        .addAction(action2.build())
-                        .setContentIntentAvailableOffline(false)
-                        .setHintHideIcon(true)
-                        .setHintShowBackgroundOnly(true)
-                        .setStartScrollBottom(true)
-                        .setDisplayIntent(mPendingIntent)
-                        .addPage(page2)
-                        .setContentIcon(R.drawable.content_icon2)
-                        .setContentIconGravity(Gravity.START)
-                        .setContentAction(5 /* arbitrary content action index */)
-                        .setCustomSizePreset(NotificationCompat.WearableExtender.SIZE_MEDIUM)
-                        .setCustomContentHeight(mCustomContentHeightPx)
-                        .setGravity(Gravity.TOP);
-
-        Notification notif = new NotificationCompat.Builder(getContext())
-                .extend(compatExtender).build();
-        assertExtendersEqual(new Notification.WearableExtender(notif), compatExtender);
-        assertExtendersEqual(new Notification.WearableExtender(notif),
-                new NotificationCompat.WearableExtender(notif));
-    }
-
-    public void testCompatReadRealValue() throws Exception {
-        android.app.RemoteInput.Builder remoteInput = new android.app.RemoteInput.Builder(
-                "result_key1")
-                .setLabel("label")
-                .setChoices(new CharSequence[] {"choice 1", "choice 2"});
-        remoteInput.getExtras().putString("remoteinput_string", "test");
-        Notification.Action.Builder action2 = new Notification.Action.Builder(
-                R.drawable.action_icon, "Test title", mPendingIntent)
-                .addRemoteInput(remoteInput.build())
-                .extend(new Notification.Action.WearableExtender()
-                        .setAvailableOffline(false)
-                        .setInProgressLabel("In Progress Label")
-                        .setConfirmLabel("Confirmation Label")
-                        .setCancelLabel("Cancelation Label"));
-        // Add an arbitrary key/value.
-        action2.getExtras().putFloat("action_float", 10.5f);
-
-        Notification page2 = new Notification.Builder(getContext())
-                .setContentTitle("page2 title")
-                .extend(new Notification.WearableExtender()
-                        .setContentIcon(R.drawable.content_icon))
-                .build();
-
-        Notification.WearableExtender realExtender =
-                new Notification.WearableExtender()
-                        .addAction(new Notification.Action(R.drawable.action_icon2, "Action1",
-                                mPendingIntent))
-                        .addAction(action2.build())
-                        .setContentIntentAvailableOffline(false)
-                        .setHintHideIcon(true)
-                        .setHintShowBackgroundOnly(true)
-                        .setStartScrollBottom(true)
-                        .setDisplayIntent(mPendingIntent)
-                        .addPage(page2)
-                        .setContentIcon(R.drawable.content_icon2)
-                        .setContentIconGravity(Gravity.START)
-                        .setContentAction(5 /* arbitrary content action index */)
-                        .setCustomSizePreset(NotificationCompat.WearableExtender.SIZE_MEDIUM)
-                        .setCustomContentHeight(mCustomContentHeightPx)
-                        .setGravity(Gravity.TOP);
-
-        Notification notif = new Notification.Builder(getContext())
-                .extend(realExtender).build();
-        assertExtendersEqual(realExtender, new NotificationCompat.WearableExtender(notif));
-        assertExtendersEqual(new Notification.WearableExtender(notif),
-                new NotificationCompat.WearableExtender(notif));
-    }
-
-    private void assertExtendersEqual(Notification.WearableExtender real,
-            NotificationCompat.WearableExtender compat) {
-        assertActionsEquals(real.getActions(), compat.getActions());
-        assertEquals(real.getContentIntentAvailableOffline(),
-                compat.getContentIntentAvailableOffline());
-        assertEquals(real.getHintHideIcon(), compat.getHintHideIcon());
-        assertEquals(real.getHintShowBackgroundOnly(), compat.getHintShowBackgroundOnly());
-        assertEquals(real.getStartScrollBottom(), compat.getStartScrollBottom());
-        assertEquals(real.getDisplayIntent(), compat.getDisplayIntent());
-        assertPagesEquals(real.getPages(), compat.getPages());
-        assertEquals(real.getBackground(), compat.getBackground());
-        assertEquals(real.getContentIcon(), compat.getContentIcon());
-        assertEquals(real.getContentIconGravity(), compat.getContentIconGravity());
-        assertEquals(real.getContentAction(), compat.getContentAction());
-        assertEquals(real.getCustomSizePreset(), compat.getCustomSizePreset());
-        assertEquals(real.getCustomContentHeight(), compat.getCustomContentHeight());
-        assertEquals(real.getGravity(), compat.getGravity());
-    }
-
-    private void assertPagesEquals(List<Notification> pages1, List<Notification> pages2) {
-        assertEquals(pages1.size(), pages2.size());
-        for (int i = 0; i < pages1.size(); i++) {
-            assertNotificationsEqual(pages1.get(i), pages2.get(i));
-        }
-    }
-
-    private void assertNotificationsEqual(Notification n1, Notification n2) {
-        assertEquals(n1.icon, n2.icon);
-        assertBundlesEqual(n1.extras, n2.extras);
-        assertExtendersEqual(new Notification.WearableExtender(n1),
-                new NotificationCompat.WearableExtender(n2));
-    }
-
-    private void assertActionsEquals(List<Notification.Action> realArray,
-            List<NotificationCompat.Action> compatArray) {
-        assertEquals(realArray.size(), compatArray.size());
-        for (int i = 0; i < realArray.size(); i++) {
-            assertActionsEqual(realArray.get(i), compatArray.get(i));
-        }
-    }
-
-    private void assertActionsEqual(Notification.Action real, NotificationCompat.Action compat) {
-        assertEquals(real.icon, compat.icon);
-        assertEquals(real.title, compat.title);
-        assertEquals(real.actionIntent, compat.actionIntent);
-        assertRemoteInputsEquals(real.getRemoteInputs(), compat.getRemoteInputs());
-        assertBundlesEqual(real.getExtras(), compat.getExtras());
-    }
-
-    private void assertRemoteInputsEquals(android.app.RemoteInput[] realArray,
-            RemoteInput[] compatArray) {
-        assertEquals(realArray == null, compatArray == null);
-        if (realArray != null) {
-            assertEquals(realArray.length, compatArray.length);
-            for (int i = 0; i < realArray.length; i++) {
-                assertRemoteInputsEqual(realArray[i], compatArray[i]);
-            }
-        }
-    }
-
-    private void assertRemoteInputsEqual(android.app.RemoteInput real,
-            RemoteInput compat) {
-        assertEquals(real.getResultKey(), compat.getResultKey());
-        assertEquals(real.getLabel(), compat.getLabel());
-        assertCharSequencesEquals(real.getChoices(), compat.getChoices());
-        assertEquals(real.getAllowFreeFormInput(), compat.getAllowFreeFormInput());
-        assertBundlesEqual(real.getExtras(), compat.getExtras());
-    }
-
-    private void assertCharSequencesEquals(CharSequence[] array1, CharSequence[] array2) {
-        if (!Arrays.deepEquals(array1, array2)) {
-            fail("Arrays not equal: " + Arrays.toString(array1) + " != " + Arrays.toString(array2));
-        }
-    }
-
-    private void assertBundlesEqual(Bundle bundle1, Bundle bundle2) {
-        assertEquals(bundle1.size(), bundle2.size());
-        for (String key : bundle1.keySet()) {
-            Object value1 = bundle1.get(key);
-            Object value2 = bundle2.get(key);
-            if (value1 instanceof Bundle && value2 instanceof Bundle) {
-                assertBundlesEqual((Bundle) value1, (Bundle) value2);
-            } else {
-                assertEquals(value1, value2);
-            }
-        }
-    }
-}
diff --git a/compat/tests/java/android/support/v4/graphics/TestTintAwareDrawable.java b/compat/tests/java/android/support/v4/graphics/TestTintAwareDrawable.java
index e1cdfa1..6a7ed76 100644
--- a/compat/tests/java/android/support/v4/graphics/TestTintAwareDrawable.java
+++ b/compat/tests/java/android/support/v4/graphics/TestTintAwareDrawable.java
@@ -21,9 +21,6 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.support.v4.graphics.drawable.TintAwareDrawable;
 
-/**
- * @hide
- */
 public class TestTintAwareDrawable extends BitmapDrawable implements TintAwareDrawable {
 
     public TestTintAwareDrawable() {
diff --git a/compat/tests/java/android/support/v4/text/IcuCompatTest.java b/compat/tests/java/android/support/v4/text/IcuCompatTest.java
index 0eb4ba1..20aaa9b 100644
--- a/compat/tests/java/android/support/v4/text/IcuCompatTest.java
+++ b/compat/tests/java/android/support/v4/text/IcuCompatTest.java
@@ -16,6 +16,7 @@
 
 package android.support.v4.text;
 
+import android.os.Build;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import junit.framework.TestCase;
@@ -26,6 +27,11 @@
 public class IcuCompatTest extends TestCase {
     public void testMaximizeAndGetScript() {
         assertEquals("Latn", ICUCompat.maximizeAndGetScript(new Locale("en", "US")));
-        assertEquals("Visp", ICUCompat.maximizeAndGetScript(Locale.forLanguageTag("en-Visp-US")));
+
+        // Script tags were added to java.util.Locale only on API 21.
+        if (Build.VERSION.SDK_INT >= 21) {
+            assertEquals(
+                    "Visp", ICUCompat.maximizeAndGetScript(Locale.forLanguageTag("en-Visp-US")));
+        }
     }
 }
diff --git a/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java b/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
index 452b033..197f96e 100644
--- a/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
+++ b/core-ui/java/android/support/v4/app/ActionBarDrawerToggle.java
@@ -110,6 +110,9 @@
     }
 
     private static class ActionBarDrawerToggleImplBase implements ActionBarDrawerToggleImpl {
+        ActionBarDrawerToggleImplBase() {
+        }
+
         @Override
         public Drawable getThemeUpIndicator(Activity activity) {
             return null;
@@ -130,6 +133,9 @@
     }
 
     private static class ActionBarDrawerToggleImplHC implements ActionBarDrawerToggleImpl {
+        ActionBarDrawerToggleImplHC() {
+        }
+
         @Override
         public Drawable getThemeUpIndicator(Activity activity) {
             return ActionBarDrawerToggleHoneycomb.getThemeUpIndicator(activity);
@@ -151,6 +157,9 @@
 
     private static class ActionBarDrawerToggleImplJellybeanMR2
             implements ActionBarDrawerToggleImpl {
+        ActionBarDrawerToggleImplJellybeanMR2() {
+        }
+
         @Override
         public Drawable getThemeUpIndicator(Activity activity) {
             return ActionBarDrawerToggleJellybeanMR2.getThemeUpIndicator(activity);
@@ -189,7 +198,7 @@
     // android.R.id.home as defined by public API in v11
     private static final int ID_HOME = 0x0102002c;
 
-    private final Activity mActivity;
+    final Activity mActivity;
     private final Delegate mActivityImpl;
     private final DrawerLayout mDrawerLayout;
     private boolean mDrawerIndicatorEnabled = true;
@@ -505,7 +514,7 @@
         private float mPosition;
         private float mOffset;
 
-        private SlideDrawable(Drawable wrapped) {
+        SlideDrawable(Drawable wrapped) {
             super(wrapped, 0);
         }
 
diff --git a/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java b/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
index 21aaae5..e638d05 100644
--- a/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
+++ b/core-ui/java/android/support/v4/view/AsyncLayoutInflater.java
@@ -67,9 +67,9 @@
 public final class AsyncLayoutInflater {
     private static final String TAG = "AsyncLayoutInflater";
 
-    private LayoutInflater mInflater;
-    private Handler mHandler;
-    private InflateThread mInflateThread;
+    LayoutInflater mInflater;
+    Handler mHandler;
+    InflateThread mInflateThread;
 
     public AsyncLayoutInflater(@NonNull Context context) {
         mInflater = new BasicInflater(context);
@@ -116,6 +116,9 @@
         int resid;
         View view;
         OnInflateFinishedListener callback;
+
+        InflateRequest() {
+        }
     }
 
     private static class BasicInflater extends LayoutInflater {
diff --git a/core-ui/java/android/support/v4/view/PagerTitleStrip.java b/core-ui/java/android/support/v4/view/PagerTitleStrip.java
index 65fdff7..d569cd4 100644
--- a/core-ui/java/android/support/v4/view/PagerTitleStrip.java
+++ b/core-ui/java/android/support/v4/view/PagerTitleStrip.java
@@ -55,7 +55,7 @@
     TextView mNextText;
 
     private int mLastKnownCurrentPage = -1;
-    private float mLastKnownPositionOffset = -1;
+    float mLastKnownPositionOffset = -1;
     private int mScaledTextSpacing;
     private int mGravity;
 
@@ -481,6 +481,9 @@
             ViewPager.OnAdapterChangeListener {
         private int mScrollState;
 
+        PageListener() {
+        }
+
         @Override
         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
             if (positionOffset > 0.5f) {
diff --git a/core-ui/java/android/support/v4/view/ViewPager.java b/core-ui/java/android/support/v4/view/ViewPager.java
index 8735151..50b16fc 100644
--- a/core-ui/java/android/support/v4/view/ViewPager.java
+++ b/core-ui/java/android/support/v4/view/ViewPager.java
@@ -122,7 +122,7 @@
 
     private static final int MIN_FLING_VELOCITY = 400; // dips
 
-    private static final int[] LAYOUT_ATTRS = new int[] {
+    static final int[] LAYOUT_ATTRS = new int[] {
         android.R.attr.layout_gravity
     };
 
@@ -160,8 +160,8 @@
 
     private final Rect mTempRect = new Rect();
 
-    private PagerAdapter mAdapter;
-    private int mCurItem;   // Index of currently displayed page.
+    PagerAdapter mAdapter;
+    int mCurItem;   // Index of currently displayed page.
     private int mRestoredCurItem = -1;
     private Parcelable mRestoredAdapterState = null;
     private ClassLoader mRestoredClassLoader = null;
@@ -488,7 +488,7 @@
         super.onDetachedFromWindow();
     }
 
-    private void setScrollState(int newState) {
+    void setScrollState(int newState) {
         if (mScrollState == newState) {
             return;
         }
@@ -3109,6 +3109,9 @@
     }
 
     private class PagerObserver extends DataSetObserver {
+        PagerObserver() {
+        }
+
         @Override
         public void onChanged() {
             dataSetChanged();
diff --git a/core-ui/java/android/support/v4/widget/AutoScrollHelper.java b/core-ui/java/android/support/v4/widget/AutoScrollHelper.java
index bf4f1e4..4291a25 100644
--- a/core-ui/java/android/support/v4/widget/AutoScrollHelper.java
+++ b/core-ui/java/android/support/v4/widget/AutoScrollHelper.java
@@ -134,13 +134,13 @@
     private static final int VERTICAL = 1;
 
     /** Scroller used to control acceleration toward maximum velocity. */
-    private final ClampedScroller mScroller = new ClampedScroller();
+    final ClampedScroller mScroller = new ClampedScroller();
 
     /** Interpolator used to scale velocity with touch position. */
     private final Interpolator mEdgeInterpolator = new AccelerateInterpolator();
 
     /** The view to auto-scroll. Might not be the source of touch events. */
-    private final View mTarget;
+    final View mTarget;
 
     /** Runnable used to animate scrolling. */
     private Runnable mRunnable;
@@ -170,13 +170,13 @@
     private boolean mAlreadyDelayed;
 
     /** Whether to reset the scroller start time on the next animation. */
-    private boolean mNeedsReset;
+    boolean mNeedsReset;
 
     /** Whether to send a cancel motion event to the target view. */
-    private boolean mNeedsCancel;
+    boolean mNeedsCancel;
 
     /** Whether the auto-scroller is actively scrolling. */
-    private boolean mAnimating;
+    boolean mAnimating;
 
     /** Whether the auto-scroller is enabled. */
     private boolean mEnabled;
@@ -488,7 +488,7 @@
     /**
      * @return whether the target is able to scroll in the requested direction
      */
-    private boolean shouldAnimate() {
+    boolean shouldAnimate() {
         final ClampedScroller scroller = mScroller;
         final int verticalDirection = scroller.getVerticalDirection();
         final int horizontalDirection = scroller.getHorizontalDirection();
@@ -649,7 +649,7 @@
         return 0;
     }
 
-    private static int constrain(int value, int min, int max) {
+    static int constrain(int value, int min, int max) {
         if (value > max) {
             return max;
         } else if (value < min) {
@@ -659,7 +659,7 @@
         }
     }
 
-    private static float constrain(float value, float min, float max) {
+    static float constrain(float value, float min, float max) {
         if (value > max) {
             return max;
         } else if (value < min) {
@@ -673,7 +673,7 @@
      * Sends a {@link MotionEvent#ACTION_CANCEL} event to the target view,
      * canceling any ongoing touch events.
      */
-    private void cancelTargetTouch() {
+    void cancelTargetTouch() {
         final long eventTime = SystemClock.uptimeMillis();
         final MotionEvent cancel = MotionEvent.obtain(
                 eventTime, eventTime, MotionEvent.ACTION_CANCEL, 0, 0, 0);
@@ -682,6 +682,9 @@
     }
 
     private class ScrollAnimationRunnable implements Runnable {
+        ScrollAnimationRunnable() {
+        }
+
         @Override
         public void run() {
             if (!mAnimating) {
diff --git a/core-ui/java/android/support/v4/widget/CircleImageView.java b/core-ui/java/android/support/v4/widget/CircleImageView.java
index a83fb5c..e582882 100644
--- a/core-ui/java/android/support/v4/widget/CircleImageView.java
+++ b/core-ui/java/android/support/v4/widget/CircleImageView.java
@@ -33,8 +33,6 @@
  * Private class created to work around issues with AnimationListeners being
  * called before the animation is actually complete and support shadows on older
  * platforms.
- *
- * @hide
  */
 class CircleImageView extends ImageView {
 
@@ -47,7 +45,7 @@
     private static final int SHADOW_ELEVATION = 4;
 
     private Animation.AnimationListener mListener;
-    private int mShadowRadius;
+    int mShadowRadius;
 
     CircleImageView(Context context, int color) {
         super(context);
diff --git a/core-ui/java/android/support/v4/widget/ContentLoadingProgressBar.java b/core-ui/java/android/support/v4/widget/ContentLoadingProgressBar.java
index 3335b9f..98b63a4 100644
--- a/core-ui/java/android/support/v4/widget/ContentLoadingProgressBar.java
+++ b/core-ui/java/android/support/v4/widget/ContentLoadingProgressBar.java
@@ -31,13 +31,13 @@
     private static final int MIN_SHOW_TIME = 500; // ms
     private static final int MIN_DELAY = 500; // ms
 
-    private long mStartTime = -1;
+    long mStartTime = -1;
 
-    private boolean mPostedHide = false;
+    boolean mPostedHide = false;
 
-    private boolean mPostedShow = false;
+    boolean mPostedShow = false;
 
-    private boolean mDismissed = false;
+    boolean mDismissed = false;
 
     private final Runnable mDelayedHide = new Runnable() {
 
diff --git a/core-ui/java/android/support/v4/widget/CursorAdapter.java b/core-ui/java/android/support/v4/widget/CursorAdapter.java
index d95f048..249f21c 100644
--- a/core-ui/java/android/support/v4/widget/CursorAdapter.java
+++ b/core-ui/java/android/support/v4/widget/CursorAdapter.java
@@ -21,6 +21,7 @@
 import android.database.Cursor;
 import android.database.DataSetObserver;
 import android.os.Handler;
+import android.support.annotation.RestrictTo;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewGroup;
@@ -29,6 +30,8 @@
 import android.widget.FilterQueryProvider;
 import android.widget.Filterable;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Static library support version of the framework's {@link android.widget.CursorAdapter}.
  * Used to write apps that run on platforms prior to Android 3.0.  When running
@@ -42,46 +45,55 @@
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected boolean mDataValid;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected boolean mAutoRequery;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected Cursor mCursor;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected Context mContext;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected int mRowIDColumn;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected ChangeObserver mChangeObserver;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected DataSetObserver mDataSetObserver;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected CursorFilter mCursorFilter;
     /**
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected FilterQueryProvider mFilterQueryProvider;
 
     /**
@@ -476,6 +488,9 @@
     }
 
     private class MyDataSetObserver extends DataSetObserver {
+        MyDataSetObserver() {
+        }
+
         @Override
         public void onChanged() {
             mDataValid = true;
diff --git a/core-ui/java/android/support/v4/widget/DrawerLayout.java b/core-ui/java/android/support/v4/widget/DrawerLayout.java
index a41fce3..7a564bb 100644
--- a/core-ui/java/android/support/v4/widget/DrawerLayout.java
+++ b/core-ui/java/android/support/v4/widget/DrawerLayout.java
@@ -115,7 +115,6 @@
      */
     public static final int STATE_SETTLING = ViewDragHelper.STATE_SETTLING;
 
-    /** @hide */
     @IntDef({LOCK_MODE_UNLOCKED, LOCK_MODE_LOCKED_CLOSED, LOCK_MODE_LOCKED_OPEN,
             LOCK_MODE_UNDEFINED})
     @Retention(RetentionPolicy.SOURCE)
@@ -143,7 +142,6 @@
      */
     public static final int LOCK_MODE_UNDEFINED = 3;
 
-    /** @hide */
     @IntDef({Gravity.LEFT, Gravity.RIGHT, GravityCompat.START, GravityCompat.END})
     @Retention(RetentionPolicy.SOURCE)
     private @interface EdgeGravity {}
@@ -173,12 +171,12 @@
 
     private static final float TOUCH_SLOP_SENSITIVITY = 1.f;
 
-    private static final int[] LAYOUT_ATTRS = new int[] {
+    static final int[] LAYOUT_ATTRS = new int[] {
             android.R.attr.layout_gravity
     };
 
     /** Whether we can use NO_HIDE_DESCENDANTS accessibility importance. */
-    private static final boolean CAN_HIDE_DESCENDANTS = Build.VERSION.SDK_INT >= 19;
+    static final boolean CAN_HIDE_DESCENDANTS = Build.VERSION.SDK_INT >= 19;
 
     /** Whether the drawer shadow comes from setting elevation on the drawer. */
     private static final boolean SET_DRAWER_SHADOW_FROM_ELEVATION =
@@ -884,8 +882,6 @@
             if (hasWindowFocus()) {
                 sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
             }
-
-            drawerView.requestFocus();
         }
     }
 
@@ -1864,7 +1860,7 @@
         return findVisibleDrawer() != null;
     }
 
-    private View findVisibleDrawer() {
+    View findVisibleDrawer() {
         final int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             final View child = getChildAt(i);
@@ -1995,7 +1991,7 @@
         }
     }
 
-    private static boolean includeChildForAccessibility(View child) {
+    static boolean includeChildForAccessibility(View child) {
         // If the child is not important for accessibility we make
         // sure this hides the entire subtree rooted at it as the
         // IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDATS is not
@@ -2146,7 +2142,7 @@
             postDelayed(mPeekRunnable, PEEK_DELAY);
         }
 
-        private void peekDrawer() {
+        void peekDrawer() {
             final View toCapture;
             final int childLeft;
             final int peekDistance = mDragger.getEdgeSize();
@@ -2226,9 +2222,9 @@
         private static final int FLAG_IS_CLOSING = 0x4;
 
         public int gravity = Gravity.NO_GRAVITY;
-        private float onScreen;
-        private boolean isPeeking;
-        private int openState;
+        float onScreen;
+        boolean isPeeking;
+        int openState;
 
         public LayoutParams(Context c, AttributeSet attrs) {
             super(c, attrs);
diff --git a/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java b/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
index 8cb3b0a..bb43456 100644
--- a/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
+++ b/core-ui/java/android/support/v4/widget/ExploreByTouchHelper.java
@@ -717,7 +717,7 @@
      *         about the specified item
      */
     @NonNull
-    private AccessibilityNodeInfoCompat obtainAccessibilityNodeInfo(int virtualViewId) {
+    AccessibilityNodeInfoCompat obtainAccessibilityNodeInfo(int virtualViewId) {
         if (virtualViewId == HOST_ID) {
             return createNodeForHost();
         }
@@ -867,7 +867,7 @@
         return node;
     }
 
-    private boolean performAction(int virtualViewId, int action, Bundle arguments) {
+    boolean performAction(int virtualViewId, int action, Bundle arguments) {
         switch (virtualViewId) {
             case HOST_ID:
                 return performActionForHost(action, arguments);
@@ -1221,6 +1221,9 @@
      * Exposes a virtual view hierarchy to the accessibility framework.
      */
     private class MyNodeProvider extends AccessibilityNodeProviderCompat {
+        MyNodeProvider() {
+        }
+
         @Override
         public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) {
             // The caller takes ownership of the node and is expected to
diff --git a/core-ui/java/android/support/v4/widget/MaterialProgressDrawable.java b/core-ui/java/android/support/v4/widget/MaterialProgressDrawable.java
index 6affe47..12b3a74 100644
--- a/core-ui/java/android/support/v4/widget/MaterialProgressDrawable.java
+++ b/core-ui/java/android/support/v4/widget/MaterialProgressDrawable.java
@@ -45,17 +45,17 @@
 
 /**
  * Fancy progress indicator for Material theme.
- *
- * @hide
  */
 class MaterialProgressDrawable extends Drawable implements Animatable {
     private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
-    private static final Interpolator MATERIAL_INTERPOLATOR = new FastOutSlowInInterpolator();
+    static final Interpolator MATERIAL_INTERPOLATOR = new FastOutSlowInInterpolator();
 
     private static final float FULL_ROTATION = 1080.0f;
+
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({LARGE, DEFAULT})
     public @interface ProgressDrawableSize {}
+
     // Maps to ProgressBar.Large style
     static final int LARGE = 0;
     // Maps to ProgressBar default style
@@ -110,7 +110,7 @@
     private Resources mResources;
     private View mParent;
     private Animation mAnimation;
-    private float mRotationCount;
+    float mRotationCount;
     private double mWidth;
     private double mHeight;
     boolean mFinishing;
@@ -299,7 +299,7 @@
         mRing.resetOriginals();
     }
 
-    private float getMinProgressArc(Ring ring) {
+    float getMinProgressArc(Ring ring) {
         return (float) Math.toRadians(
                 ring.getStrokeWidth() / (2 * Math.PI * ring.getCenterRadius()));
     }
@@ -329,7 +329,7 @@
      * The new ring color will be a translation from the starting ring color to
      * the next color.
      */
-    private void updateRingColor(float interpolatedTime, Ring ring) {
+    void updateRingColor(float interpolatedTime, Ring ring) {
         if (interpolatedTime > COLOR_START_DELAY_OFFSET) {
             // scale the interpolatedTime so that the full
             // transformation from 0 - 1 takes place in the
@@ -340,7 +340,7 @@
         }
     }
 
-    private void applyFinishTranslation(float interpolatedTime, Ring ring) {
+    void applyFinishTranslation(float interpolatedTime, Ring ring) {
         // shrink back down and complete a full rotation before
         // starting other circles
         // Rotation goes between [0..1].
diff --git a/core-ui/java/android/support/v4/widget/NestedScrollView.java b/core-ui/java/android/support/v4/widget/NestedScrollView.java
index 3e4c55f..53e971f 100644
--- a/core-ui/java/android/support/v4/widget/NestedScrollView.java
+++ b/core-ui/java/android/support/v4/widget/NestedScrollView.java
@@ -24,6 +24,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.AccessibilityDelegateCompat;
 import android.support.v4.view.InputDeviceCompat;
 import android.support.v4.view.MotionEventCompat;
@@ -55,6 +56,8 @@
 
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * NestedScrollView is just like {@link android.widget.ScrollView}, but it supports acting
  * as both a nested scrolling parent and child on both new and old versions of Android.
@@ -998,7 +1001,7 @@
         return clampedX || clampedY;
     }
 
-    private int getScrollRange() {
+    int getScrollRange() {
         int scrollRange = 0;
         if (getChildCount() > 0) {
             View child = getChildAt(0);
@@ -1331,6 +1334,7 @@
      * children.</p>
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public int computeVerticalScrollRange() {
         final int count = getChildCount();
@@ -1352,30 +1356,35 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public int computeVerticalScrollOffset() {
         return Math.max(0, super.computeVerticalScrollOffset());
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public int computeVerticalScrollExtent() {
         return super.computeVerticalScrollExtent();
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public int computeHorizontalScrollRange() {
         return super.computeHorizontalScrollRange();
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public int computeHorizontalScrollOffset() {
         return super.computeHorizontalScrollOffset();
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public int computeHorizontalScrollExtent() {
         return super.computeHorizontalScrollExtent();
diff --git a/core-ui/java/android/support/v4/widget/SimpleCursorAdapter.java b/core-ui/java/android/support/v4/widget/SimpleCursorAdapter.java
index 7ef7aa1..7050734 100644
--- a/core-ui/java/android/support/v4/widget/SimpleCursorAdapter.java
+++ b/core-ui/java/android/support/v4/widget/SimpleCursorAdapter.java
@@ -19,10 +19,13 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.net.Uri;
+import android.support.annotation.RestrictTo;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Static library support version of the framework's {@link android.widget.SimpleCursorAdapter}.
  * Used to write apps that run on platforms prior to Android 3.0.  When running
@@ -36,12 +39,14 @@
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected int[] mFrom;
     /**
      * A list of View ids representing the views to which the data must be bound.
      * This field should be made private, so it is hidden from the SDK.
      * {@hide}
      */
+    @RestrictTo(GROUP_ID)
     protected int[] mTo;
 
     private int mStringConversionColumn = -1;
diff --git a/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java b/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
index 49e1976..1e5479b 100644
--- a/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
+++ b/core-ui/java/android/support/v4/widget/SlidingPaneLayout.java
@@ -147,13 +147,13 @@
     /**
      * The child view that can slide, if any.
      */
-    private View mSlideableView;
+    View mSlideableView;
 
     /**
      * How far the panel is offset from its closed position.
      * range [0, 1] where 0 = closed, 1 = open.
      */
-    private float mSlideOffset;
+    float mSlideOffset;
 
     /**
      * How far the non-sliding panel is parallaxed from its usual position when open.
@@ -164,13 +164,13 @@
     /**
      * How far in pixels the slideable panel may move.
      */
-    private int mSlideRange;
+    int mSlideRange;
 
     /**
      * A panel view is locked into internal scrolling or another condition that
      * is preventing a drag.
      */
-    private boolean mIsUnableToDrag;
+    boolean mIsUnableToDrag;
 
     /**
      * Distance in pixels to parallax the fixed pane by when fully closed
@@ -182,19 +182,19 @@
 
     private PanelSlideListener mPanelSlideListener;
 
-    private final ViewDragHelper mDragHelper;
+    final ViewDragHelper mDragHelper;
 
     /**
      * Stores whether or not the pane was open the last time it was slideable.
      * If open/close operations are invoked this state is modified. Used by
      * instance state save/restore.
      */
-    private boolean mPreservedOpenState;
+    boolean mPreservedOpenState;
     private boolean mFirstLayout = true;
 
     private final Rect mTmpRect = new Rect();
 
-    private final ArrayList<DisableLayerRunnable> mPostedRunnables =
+    final ArrayList<DisableLayerRunnable> mPostedRunnables =
             new ArrayList<DisableLayerRunnable>();
 
     static final SlidingPanelLayoutImpl IMPL;
@@ -946,7 +946,7 @@
         return mCanSlide;
     }
 
-    private void onPanelDragged(int newLeft) {
+    void onPanelDragged(int newLeft) {
         if (mSlideableView == null) {
             // This can happen if we're aborting motion during layout because everything now fits.
             mSlideOffset = 0;
@@ -1044,7 +1044,7 @@
         return result;
     }
 
-    private void invalidateChildRegion(View v) {
+    void invalidateChildRegion(View v) {
         IMPL.invalidateChildRegion(this, v);
     }
 
@@ -1312,6 +1312,9 @@
 
     private class DragHelperCallback extends ViewDragHelper.Callback {
 
+        DragHelperCallback() {
+        }
+
         @Override
         public boolean tryCaptureView(View child, int pointerId) {
             if (mIsUnableToDrag) {
@@ -1467,7 +1470,7 @@
             super(superState);
         }
 
-        private SavedState(Parcel in, ClassLoader loader) {
+        SavedState(Parcel in, ClassLoader loader) {
             super(in, loader);
             isOpen = in.readInt() != 0;
         }
@@ -1658,7 +1661,7 @@
         }
     }
 
-    private boolean isLayoutRtlSupport() {
+    boolean isLayoutRtlSupport() {
         return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL;
     }
 }
diff --git a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
index 998de64..4ebdeed 100644
--- a/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
+++ b/core-ui/java/android/support/v4/widget/SwipeRefreshLayout.java
@@ -103,8 +103,8 @@
     private static final int DEFAULT_CIRCLE_TARGET = 64;
 
     private View mTarget; // the target of the gesture
-    private OnRefreshListener mListener;
-    private boolean mRefreshing = false;
+    OnRefreshListener mListener;
+    boolean mRefreshing = false;
     private int mTouchSlop;
     private float mTotalDragDistance = -1;
 
@@ -119,14 +119,14 @@
     private boolean mNestedScrollInProgress;
 
     private int mMediumAnimationDuration;
-    private int mCurrentTargetOffsetTop;
+    int mCurrentTargetOffsetTop;
 
     private float mInitialMotionY;
     private float mInitialDownY;
     private boolean mIsBeingDragged;
     private int mActivePointerId = INVALID_POINTER;
     // Whether this item is scaled up rather than clipped
-    private boolean mScale;
+    boolean mScale;
 
     // Target is returning to its start offset because it was cancelled or a
     // refresh was triggered.
@@ -136,18 +136,18 @@
         android.R.attr.enabled
     };
 
-    private CircleImageView mCircleView;
+    CircleImageView mCircleView;
     private int mCircleViewIndex = -1;
 
     protected int mFrom;
 
-    private float mStartingScale;
+    float mStartingScale;
 
     protected int mOriginalOffsetTop;
 
-    private int mSpinnerOffsetEnd;
+    int mSpinnerOffsetEnd;
 
-    private MaterialProgressDrawable mProgress;
+    MaterialProgressDrawable mProgress;
 
     private Animation mScaleAnimation;
 
@@ -159,12 +159,12 @@
 
     private Animation mScaleDownToStartAnimation;
 
-    private boolean mNotify;
+    boolean mNotify;
 
     private int mCircleDiameter;
 
     // Whether the client has set a custom starting position;
-    private boolean mUsingCustomStart;
+    boolean mUsingCustomStart;
 
     private OnChildScrollUpCallback mChildScrollUpCallback;
 
@@ -195,7 +195,7 @@
         }
     };
 
-    private void reset() {
+    void reset() {
         mCircleView.clearAnimation();
         mProgress.stop();
         mCircleView.setVisibility(View.GONE);
@@ -339,10 +339,6 @@
         setWillNotDraw(false);
         mDecelerateInterpolator = new DecelerateInterpolator(DECELERATE_INTERPOLATION_FACTOR);
 
-        final TypedArray a = context.obtainStyledAttributes(attrs, LAYOUT_ATTRS);
-        setEnabled(a.getBoolean(0, true));
-        a.recycle();
-
         final DisplayMetrics metrics = getResources().getDisplayMetrics();
         mCircleDiameter = (int) (CIRCLE_DIAMETER * metrics.density);
 
@@ -358,6 +354,10 @@
 
         mOriginalOffsetTop = mCurrentTargetOffsetTop = -mCircleDiameter;
         moveToStart(1.0f);
+
+        final TypedArray a = context.obtainStyledAttributes(attrs, LAYOUT_ATTRS);
+        setEnabled(a.getBoolean(0, true));
+        a.recycle();
     }
 
     @Override
@@ -451,7 +451,7 @@
      * Pre API 11, this does an alpha animation.
      * @param progress
      */
-    private void setAnimationProgress(float progress) {
+    void setAnimationProgress(float progress) {
         if (isAlphaUsedForScale()) {
             setColorViewAlpha((int) (progress * MAX_ALPHA));
         } else {
@@ -473,7 +473,7 @@
         }
     }
 
-    private void startScaleDownAnimation(Animation.AnimationListener listener) {
+    void startScaleDownAnimation(Animation.AnimationListener listener) {
         mScaleDownAnimation = new Animation() {
             @Override
             public void applyTransformation(float interpolatedTime, Transformation t) {
@@ -1141,7 +1141,7 @@
         }
     };
 
-    private void moveToStart(float interpolatedTime) {
+    void moveToStart(float interpolatedTime) {
         int targetTop = 0;
         targetTop = (mFrom + (int) ((mOriginalOffsetTop - mFrom) * interpolatedTime));
         int offset = targetTop - mCircleView.getTop();
@@ -1179,7 +1179,7 @@
         mCircleView.startAnimation(mScaleDownToStartAnimation);
     }
 
-    private void setTargetOffsetTopAndBottom(int offset, boolean requiresUpdate) {
+    void setTargetOffsetTopAndBottom(int offset, boolean requiresUpdate) {
         mCircleView.bringToFront();
         ViewCompat.offsetTopAndBottom(mCircleView, offset);
         mCurrentTargetOffsetTop = mCircleView.getTop();
diff --git a/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutActions.java b/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutActions.java
index 27b7be6..b337ec8 100644
--- a/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutActions.java
+++ b/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutActions.java
@@ -74,4 +74,28 @@
             }
         };
     }
+
+    public static ViewAction setEnabled(final boolean enabled) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(SwipeRefreshLayout.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "Set SwipeRefreshLayout enabled state";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) view;
+                swipeRefreshLayout.setEnabled(enabled);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
 }
diff --git a/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java b/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
index 3f9ed9c..0d0ac22 100644
--- a/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
+++ b/core-ui/tests/java/android/support/v4/widget/SwipeRefreshLayoutTest.java
@@ -18,6 +18,7 @@
 
 import static android.support.test.espresso.Espresso.onView;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.v4.widget.SwipeRefreshLayoutActions.setEnabled;
 import static android.support.v4.widget.SwipeRefreshLayoutActions.setRefreshing;
 import static android.support.v4.widget.SwipeRefreshLayoutActions.setSize;
 
@@ -26,6 +27,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.*;
 
+import android.app.Activity;
 import android.support.test.espresso.action.ViewActions;
 import android.support.coreui.test.R;
 import android.support.v4.BaseInstrumentationTestCase;
@@ -96,19 +98,7 @@
     public void testSwipeDownToRefresh() throws Throwable {
         assertFalse(mSwipeRefresh.isRefreshing());
 
-        final CountDownLatch latch = new CountDownLatch(1);
-        SwipeRefreshLayout.OnRefreshListener listener = new SwipeRefreshLayout.OnRefreshListener() {
-            @Override
-            public void onRefresh() {
-                latch.countDown();
-                assertTrue(mSwipeRefresh.isRefreshing());
-                mSwipeRefresh.setRefreshing(false);
-            }
-        };
-        mSwipeRefresh.setOnRefreshListener(listener);
-        onView(withId(R.id.content)).perform(ViewActions.swipeDown());
-        assertTrue("SwipeRefreshLayout never started refreshing",
-                latch.await(500, TimeUnit.MILLISECONDS));
+        swipeToRefreshVerifyThenStopRefreshing(true);
     }
 
     @Test
@@ -145,4 +135,47 @@
         assertFalse(mSwipeRefresh.canChildScrollUp());
         assertFalse(mSwipeRefresh.canChildScrollUp());
     }
+
+    @Test
+    @SmallTest
+    public void testSwipeDownToRefreshInitiallyDisabled() throws Throwable {
+        mActivityTestRule.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mActivityTestRule.getActivity().setContentView(
+                        R.layout.swipe_refresh_layout_disabled_activity);
+            }
+        });
+        mSwipeRefresh = (SwipeRefreshLayout) mActivityTestRule.getActivity().findViewById(
+                R.id.swipe_refresh);
+
+        assertFalse(mSwipeRefresh.isRefreshing());
+
+        swipeToRefreshVerifyThenStopRefreshing(false);
+
+        onView(withId(R.id.swipe_refresh)).perform(setEnabled(true));
+
+        swipeToRefreshVerifyThenStopRefreshing(true);
+    }
+
+    private void swipeToRefreshVerifyThenStopRefreshing(boolean expectRefreshing) throws Throwable {
+        final CountDownLatch latch = new CountDownLatch(1);
+        SwipeRefreshLayout.OnRefreshListener listener = new SwipeRefreshLayout.OnRefreshListener() {
+            @Override
+            public void onRefresh() {
+                latch.countDown();
+                assertTrue(mSwipeRefresh.isRefreshing());
+                mSwipeRefresh.setRefreshing(false);
+            }
+        };
+        mSwipeRefresh.setOnRefreshListener(listener);
+        onView(withId(R.id.content)).perform(ViewActions.swipeDown());
+        if (expectRefreshing) {
+            assertTrue("SwipeRefreshLayout never started refreshing",
+                    latch.await(500, TimeUnit.MILLISECONDS));
+        } else {
+            assertFalse("SwipeRefreshLayout unexpectedly started refreshing",
+                    latch.await(500, TimeUnit.MILLISECONDS));
+        }
+    }
 }
diff --git a/core-ui/tests/res/layout/swipe_refresh_layout_disabled_activity.xml b/core-ui/tests/res/layout/swipe_refresh_layout_disabled_activity.xml
new file mode 100644
index 0000000..fe5b364
--- /dev/null
+++ b/core-ui/tests/res/layout/swipe_refresh_layout_disabled_activity.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<android.support.v4.widget.SwipeRefreshLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/swipe_refresh"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:enabled="false">
+<!-- some full screen pullable view that will be the offsetable content -->
+    <ListView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:id="@+id/content"/>
+</android.support.v4.widget.SwipeRefreshLayout>
\ No newline at end of file
diff --git a/core-utils/java/android/support/v4/content/AsyncTaskLoader.java b/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
index 17d7416..da24c7f 100644
--- a/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
+++ b/core-utils/java/android/support/v4/content/AsyncTaskLoader.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.SystemClock;
+import android.support.annotation.RestrictTo;
 import android.support.v4.os.OperationCanceledException;
 import android.support.v4.util.TimeUtils;
 import android.util.Log;
@@ -28,6 +29,8 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Static library support version of the framework's {@link android.content.AsyncTaskLoader}.
  * Used to write apps that run on platforms prior to Android 3.0.  When running
@@ -331,6 +334,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void waitForLoader() {
         LoadTask task = mTask;
         if (task != null) {
diff --git a/core-utils/java/android/support/v4/content/res/TypedArrayUtils.java b/core-utils/java/android/support/v4/content/res/TypedArrayUtils.java
index 0cc5885..5d2a2ad 100644
--- a/core-utils/java/android/support/v4/content/res/TypedArrayUtils.java
+++ b/core-utils/java/android/support/v4/content/res/TypedArrayUtils.java
@@ -19,14 +19,18 @@
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.AnyRes;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleableRes;
 import android.util.TypedValue;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Compat methods for accessing TypedArray values.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class TypedArrayUtils {
     public static boolean getBoolean(TypedArray a, @StyleableRes int index,
             @StyleableRes int fallbackIndex, boolean defaultValue) {
diff --git a/core-utils/java/android/support/v4/text/BidiFormatter.java b/core-utils/java/android/support/v4/text/BidiFormatter.java
index 0eb86b2..b3b8b1c 100644
--- a/core-utils/java/android/support/v4/text/BidiFormatter.java
+++ b/core-utils/java/android/support/v4/text/BidiFormatter.java
@@ -17,6 +17,7 @@
 package android.support.v4.text;
 
 import android.support.v4.view.ViewCompat;
+import android.text.SpannableStringBuilder;
 
 import java.util.Locale;
 
@@ -280,20 +281,21 @@
 
     /**
      * Returns a Unicode bidi mark matching the context directionality (LRM or RLM) if either the
-     * overall or the exit directionality of a given string is opposite to the context directionality.
-     * Putting this after the string (including its directionality declaration wrapping) prevents it
-     * from "sticking" to other opposite-directionality text or a number appearing after it inline
-     * with only neutral content in between. Otherwise returns the empty string. While the exit
-     * directionality is determined by scanning the end of the string, the overall directionality is
-     * given explicitly by a heuristic to estimate the {@code str}'s directionality.
+     * overall or the exit directionality of a given CharSequence is opposite to the context
+     * directionality. Putting this after the CharSequence (including its directionality
+     * declaration wrapping) prevents it from "sticking" to other opposite-directionality text or a
+     * number appearing after it inline with only neutral content in between. Otherwise returns
+     * the empty string. While the exit directionality is determined by scanning the end of the
+     * CharSequence, the overall directionality is given explicitly by a heuristic to estimate the
+     * {@code str}'s directionality.
      *
-     * @param str String after which the mark may need to appear.
+     * @param str CharSequence after which the mark may need to appear.
      * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s
      *                  directionality.
      * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context;
-     *     else, the empty string.
+     *     else, the empty .
      */
-    private String markAfter(String str, TextDirectionHeuristicCompat heuristic) {
+    private String markAfter(CharSequence str, TextDirectionHeuristicCompat heuristic) {
         final boolean isRtl = heuristic.isRtl(str, 0, str.length());
         // getExitDir() is called only if needed (short-circuit).
         if (!mIsRtlContext && (isRtl || getExitDir(str) == DIR_RTL)) {
@@ -307,20 +309,21 @@
 
     /**
      * Returns a Unicode bidi mark matching the context directionality (LRM or RLM) if either the
-     * overall or the entry directionality of a given string is opposite to the context
-     * directionality. Putting this before the string (including its directionality declaration
-     * wrapping) prevents it from "sticking" to other opposite-directionality text appearing before
-     * it inline with only neutral content in between. Otherwise returns the empty string. While the
-     * entry directionality is determined by scanning the beginning of the string, the overall
-     * directionality is given explicitly by a heuristic to estimate the {@code str}'s directionality.
+     * overall or the entry directionality of a given CharSequence is opposite to the context
+     * directionality. Putting this before the CharSequence (including its directionality
+     * declaration wrapping) prevents it from "sticking" to other opposite-directionality text
+     * appearing before it inline with only neutral content in between. Otherwise returns the
+     * empty string. While the entry directionality is determined by scanning the beginning of the
+     * CharSequence, the overall directionality is given explicitly by a heuristic to estimate the
+     * {@code str}'s directionality.
      *
-     * @param str String before which the mark may need to appear.
+     * @param str CharSequence before which the mark may need to appear.
      * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s
      *                  directionality.
      * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context;
      *     else, the empty string.
      */
-    private String markBefore(String str, TextDirectionHeuristicCompat heuristic) {
+    private String markBefore(CharSequence str, TextDirectionHeuristicCompat heuristic) {
         final boolean isRtl = heuristic.isRtl(str, 0, str.length());
         // getEntryDir() is called only if needed (short-circuit).
         if (!mIsRtlContext && (isRtl || getEntryDir(str) == DIR_RTL)) {
@@ -340,6 +343,17 @@
      *          false.
      */
     public boolean isRtl(String str) {
+        return isRtl((CharSequence) str);
+    }
+
+    /**
+     * Operates like {@link #isRtl(String)}, but takes a CharSequence instead of a string.
+     *
+     * @param str CharSequence whose directionality is to be estimated.
+     * @return true if {@code str}'s estimated overall directionality is RTL. Otherwise returns
+     *          false.
+     */
+    public boolean isRtl(CharSequence str) {
         return mDefaultTextDirectionHeuristicCompat.isRtl(str, 0, str.length());
     }
 
@@ -374,8 +388,28 @@
      */
     public String unicodeWrap(String str, TextDirectionHeuristicCompat heuristic, boolean isolate) {
         if (str == null) return null;
+        return unicodeWrap((CharSequence) str, heuristic, isolate).toString();
+    }
+
+    /**
+     * Operates like {@link #unicodeWrap(String,
+     * android.support.v4.text.TextDirectionHeuristicCompat, boolean)}, but takes a CharSequence
+     * instead of a string
+     *
+     * @param str The input CharSequence.
+     * @param heuristic The algorithm to be used to estimate the CharSequence's overall direction.
+     *        See {@link android.support.v4.text.TextDirectionHeuristicsCompat} for pre-defined
+     *        heuristics.
+     * @param isolate Whether to directionally isolate the CharSequence to prevent it from garbling
+     *     the content around it
+     * @return Input CharSequence after applying the above processing. {@code null} if {@code str}
+     *     is {@code null}.
+     */
+    public CharSequence unicodeWrap(CharSequence str, TextDirectionHeuristicCompat heuristic,
+            boolean isolate) {
+        if (str == null) return null;
         final boolean isRtl = heuristic.isRtl(str, 0, str.length());
-        StringBuilder result = new StringBuilder();
+        SpannableStringBuilder result = new SpannableStringBuilder();
         if (getStereoReset() && isolate) {
             result.append(markBefore(str,
                     isRtl ? TextDirectionHeuristicsCompat.RTL : TextDirectionHeuristicsCompat.LTR));
@@ -391,7 +425,7 @@
             result.append(markAfter(str,
                     isRtl ? TextDirectionHeuristicsCompat.RTL : TextDirectionHeuristicsCompat.LTR));
         }
-        return result.toString();
+        return result;
     }
 
     /**
@@ -407,6 +441,21 @@
     }
 
     /**
+     * Operates like {@link #unicodeWrap(CharSequence,
+     * android.support.v4.text.TextDirectionHeuristicCompat, boolean)}, but assumes {@code isolate}
+     * is true.
+     *
+     * @param str The input CharSequence.
+     * @param heuristic The algorithm to be used to estimate the CharSequence's overall direction.
+     *        See {@link android.support.v4.text.TextDirectionHeuristicsCompat} for pre-defined
+     *        heuristics.
+     * @return Input CharSequence after applying the above processing.
+     */
+    public CharSequence unicodeWrap(CharSequence str, TextDirectionHeuristicCompat heuristic) {
+        return unicodeWrap(str, heuristic, true /* isolate */);
+    }
+
+    /**
      * Operates like {@link #unicodeWrap(String, android.support.v4.text.TextDirectionHeuristicCompat, boolean)}, but uses the
      * formatter's default direction estimation algorithm.
      *
@@ -420,6 +469,20 @@
     }
 
     /**
+     * Operates like {@link #unicodeWrap(CharSequence,
+     * android.support.v4.text.TextDirectionHeuristicCompat, boolean)}, but uses the formatter's
+     * default direction estimation algorithm.
+     *
+     * @param str The input CharSequence.
+     * @param isolate Whether to directionally isolate the CharSequence to prevent it from garbling
+     *     the content around it
+     * @return Input CharSequence after applying the above processing.
+     */
+    public CharSequence unicodeWrap(CharSequence str, boolean isolate) {
+        return unicodeWrap(str, mDefaultTextDirectionHeuristicCompat, isolate);
+    }
+
+    /**
      * Operates like {@link #unicodeWrap(String, android.support.v4.text.TextDirectionHeuristicCompat, boolean)}, but uses the
      * formatter's default direction estimation algorithm and assumes {@code isolate} is true.
      *
@@ -431,6 +494,18 @@
     }
 
     /**
+     * Operates like {@link #unicodeWrap(CharSequence,
+     * android.support.v4.text.TextDirectionHeuristicCompat, boolean)}, but uses the formatter's
+     * default direction estimation algorithm and assumes {@code isolate} is true.
+     *
+     * @param str The input CharSequence.
+     * @return Input CharSequence after applying the above processing.
+     */
+    public CharSequence unicodeWrap(CharSequence str) {
+        return unicodeWrap(str, mDefaultTextDirectionHeuristicCompat, true /* isolate */);
+    }
+
+    /**
      * Helper method to return true if the Locale directionality is RTL.
      *
      * @param locale The Locale whose directionality will be checked to be RTL or LTR
@@ -461,7 +536,7 @@
      *
      * @param str the string to check.
      */
-    private static int getExitDir(String str) {
+    private static int getExitDir(CharSequence str) {
         return new DirectionalityEstimator(str, false /* isHtml */).getExitDir();
     }
 
@@ -478,7 +553,7 @@
      *
      * @param str the string to check.
      */
-    private static int getEntryDir(String str) {
+    private static int getEntryDir(CharSequence str) {
         return new DirectionalityEstimator(str, false /* isHtml */).getEntryDir();
     }
 
@@ -516,7 +591,7 @@
         /**
          * The text to be scanned.
          */
-        private final String text;
+        private final CharSequence text;
 
         /**
          * Whether the text to be scanned is to be treated as HTML, i.e. skipping over tags and
@@ -549,7 +624,7 @@
          * @param isHtml Whether the text to be scanned is to be treated as HTML, i.e. skipping over
          *     tags and entities.
          */
-        DirectionalityEstimator(String text, boolean isHtml) {
+        DirectionalityEstimator(CharSequence text, boolean isHtml) {
             this.text = text;
             this.isHtml = isHtml;
             length = text.length();
diff --git a/core-utils/tests/java/android/support/v4/text/BidiFormatterTest.java b/core-utils/tests/java/android/support/v4/text/BidiFormatterTest.java
index 6dc2042..e6e35fc 100644
--- a/core-utils/tests/java/android/support/v4/text/BidiFormatterTest.java
+++ b/core-utils/tests/java/android/support/v4/text/BidiFormatterTest.java
@@ -18,6 +18,9 @@
 
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.style.RelativeSizeSpan;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -39,7 +42,7 @@
             new BidiFormatter.Builder(true /* RTL context */).stereoReset(false).build();
 
     private static final String EN = "abba";
-    private static final String HE = "\u05e0\u05e1";
+    private static final String HE = "\u05E0\u05E1";
 
     private static final String LRM = "\u200E";
     private static final String RLM = "\u200F";
@@ -191,4 +194,49 @@
                 RTL_FMT_EXIT_RESET.unicodeWrap(HE + EN + HE, TextDirectionHeuristicsCompat.LTR,
                         false));
     }
+
+    @Test
+    public void testCharSequenceApis() {
+        final CharSequence CS_HE = new SpannableString(HE);
+        assertEquals(true, BidiFormatter.getInstance(true).isRtl(CS_HE));
+
+        final SpannableString CS_EN_HE = new SpannableString(EN + HE);
+        final Object RELATIVE_SIZE_SPAN = new RelativeSizeSpan(1.2f);
+        CS_EN_HE.setSpan(RELATIVE_SIZE_SPAN, 0, EN.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+
+        Spanned wrapped;
+        Object[] spans;
+
+        wrapped = (Spanned) LTR_FMT.unicodeWrap(CS_EN_HE);
+        assertEquals(EN + HE + LRM, wrapped.toString());
+        spans = wrapped.getSpans(0, wrapped.length(), Object.class);
+        assertEquals(1, spans.length);
+        assertEquals(RELATIVE_SIZE_SPAN, spans[0]);
+        assertEquals(0, wrapped.getSpanStart(RELATIVE_SIZE_SPAN));
+        assertEquals(EN.length(), wrapped.getSpanEnd(RELATIVE_SIZE_SPAN));
+
+        wrapped = (Spanned) LTR_FMT.unicodeWrap(CS_EN_HE, TextDirectionHeuristicsCompat.LTR);
+        assertEquals(EN + HE + LRM, wrapped.toString());
+        spans = wrapped.getSpans(0, wrapped.length(), Object.class);
+        assertEquals(1, spans.length);
+        assertEquals(RELATIVE_SIZE_SPAN, spans[0]);
+        assertEquals(0, wrapped.getSpanStart(RELATIVE_SIZE_SPAN));
+        assertEquals(EN.length(), wrapped.getSpanEnd(RELATIVE_SIZE_SPAN));
+
+        wrapped = (Spanned) LTR_FMT.unicodeWrap(CS_EN_HE, false);
+        assertEquals(EN + HE, wrapped.toString());
+        spans = wrapped.getSpans(0, wrapped.length(), Object.class);
+        assertEquals(1, spans.length);
+        assertEquals(RELATIVE_SIZE_SPAN, spans[0]);
+        assertEquals(0, wrapped.getSpanStart(RELATIVE_SIZE_SPAN));
+        assertEquals(EN.length(), wrapped.getSpanEnd(RELATIVE_SIZE_SPAN));
+
+        wrapped = (Spanned) LTR_FMT.unicodeWrap(CS_EN_HE, TextDirectionHeuristicsCompat.LTR, false);
+        assertEquals(EN + HE, wrapped.toString());
+        spans = wrapped.getSpans(0, wrapped.length(), Object.class);
+        assertEquals(1, spans.length);
+        assertEquals(RELATIVE_SIZE_SPAN, spans[0]);
+        assertEquals(0, wrapped.getSpanStart(RELATIVE_SIZE_SPAN));
+        assertEquals(EN.length(), wrapped.getSpanEnd(RELATIVE_SIZE_SPAN));
+    }
 }
diff --git a/customtabs/src/android/support/customtabs/CustomTabsClient.java b/customtabs/src/android/support/customtabs/CustomTabsClient.java
index 6bd8896..73f17a2 100644
--- a/customtabs/src/android/support/customtabs/CustomTabsClient.java
+++ b/customtabs/src/android/support/customtabs/CustomTabsClient.java
@@ -26,11 +26,14 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.text.TextUtils;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Class to communicate with a {@link CustomTabsService} and create
  * {@link CustomTabsSession} from it.
@@ -40,6 +43,7 @@
     private final ComponentName mServiceComponentName;
 
     /**@hide*/
+    @RestrictTo(GROUP_ID)
     CustomTabsClient(ICustomTabsService service, ComponentName componentName) {
         mService = service;
         mServiceComponentName = componentName;
diff --git a/customtabs/src/android/support/customtabs/CustomTabsSessionToken.java b/customtabs/src/android/support/customtabs/CustomTabsSessionToken.java
index 189d6fa..fdb5f91 100644
--- a/customtabs/src/android/support/customtabs/CustomTabsSessionToken.java
+++ b/customtabs/src/android/support/customtabs/CustomTabsSessionToken.java
@@ -46,7 +46,6 @@
         return new CustomTabsSessionToken(ICustomTabsCallback.Stub.asInterface(binder));
     }
 
-    /**@hide*/
     CustomTabsSessionToken(ICustomTabsCallback callbackBinder) {
         mCallbackBinder = callbackBinder;
         mCallback = new CustomTabsCallback() {
@@ -62,7 +61,6 @@
         };
     }
 
-    /**@hide*/
     IBinder getCallbackBinder() {
         return mCallbackBinder.asBinder();
     }
diff --git a/design/Android.mk b/design/Android.mk
index e9ba5b6..38ca592 100644
--- a/design/Android.mk
+++ b/design/Android.mk
@@ -101,7 +101,8 @@
     android-support-design-res \
     android-support-v4 \
     android-support-v7-appcompat \
-    android-support-v7-recyclerview
+    android-support-v7-recyclerview \
+    android-support-transition
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
@@ -115,7 +116,8 @@
     android-support-design-res \
     android-support-v4 \
     android-support-v7-appcompat \
-    android-support-v7-recyclerview
+    android-support-v7-recyclerview \
+    android-support-transition
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
diff --git a/design/AndroidManifest.xml b/design/AndroidManifest.xml
index 82f19db..d51186d 100644
--- a/design/AndroidManifest.xml
+++ b/design/AndroidManifest.xml
@@ -14,7 +14,9 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          xmlns:tools="http://schemas.android.com/tools"
           package="android.support.design">
-    <uses-sdk android:minSdkVersion="9"/>
+    <uses-sdk android:minSdkVersion="9"
+              tools:overrideLibrary="android.support.transition"/>
     <application />
 </manifest>
diff --git a/design/base/android/support/design/internal/BottomNavigationAnimationHelperBase.java b/design/base/android/support/design/internal/BottomNavigationAnimationHelperBase.java
new file mode 100644
index 0000000..22501c1
--- /dev/null
+++ b/design/base/android/support/design/internal/BottomNavigationAnimationHelperBase.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.design.internal;
+
+import android.view.ViewGroup;
+
+class BottomNavigationAnimationHelperBase {
+    void beginDelayedTransition(ViewGroup view) {
+        // Do nothing.
+    }
+}
diff --git a/design/base/android/support/design/widget/StateListAnimator.java b/design/base/android/support/design/widget/StateListAnimator.java
index 7ef944e..4378ef9 100644
--- a/design/base/android/support/design/widget/StateListAnimator.java
+++ b/design/base/android/support/design/widget/StateListAnimator.java
@@ -25,7 +25,7 @@
     private final ArrayList<Tuple> mTuples = new ArrayList<>();
 
     private Tuple mLastMatch = null;
-    private ValueAnimatorCompat mRunningAnimator = null;
+    ValueAnimatorCompat mRunningAnimator = null;
 
     private final ValueAnimatorCompat.AnimatorListener mAnimationListener
             = new ValueAnimatorCompat.AnimatorListenerAdapter() {
@@ -105,7 +105,7 @@
         final int[] mSpecs;
         final ValueAnimatorCompat mAnimator;
 
-        private Tuple(int[] specs, ValueAnimatorCompat animator) {
+        Tuple(int[] specs, ValueAnimatorCompat animator) {
             mSpecs = specs;
             mAnimator = animator;
         }
diff --git a/design/build.gradle b/design/build.gradle
index 4407ba9..8ae45d7 100644
--- a/design/build.gradle
+++ b/design/build.gradle
@@ -6,6 +6,7 @@
     compile project(':support-v4')
     compile project(':support-appcompat-v7')
     compile project(':support-recyclerview-v7')
+    compile project(':support-transition')
 
     androidTestCompile ("com.android.support.test:runner:${project.rootProject.ext.testRunnerVersion}") {
         exclude module: 'support-annotations'
diff --git a/design/gingerbread/android/support/design/widget/FloatingActionButtonGingerbread.java b/design/gingerbread/android/support/design/widget/FloatingActionButtonGingerbread.java
index 7d50e76..d17691c 100644
--- a/design/gingerbread/android/support/design/widget/FloatingActionButtonGingerbread.java
+++ b/design/gingerbread/android/support/design/widget/FloatingActionButtonGingerbread.java
@@ -246,6 +246,9 @@
     }
 
     private class ResetElevationAnimation extends ShadowAnimatorImpl {
+        ResetElevationAnimation() {
+        }
+
         @Override
         protected float getTargetShadowSize() {
             return mElevation;
@@ -253,6 +256,9 @@
     }
 
     private class ElevateToTranslationZAnimation extends ShadowAnimatorImpl {
+        ElevateToTranslationZAnimation() {
+        }
+
         @Override
         protected float getTargetShadowSize() {
             return mElevation + mPressedTranslationZ;
@@ -260,6 +266,9 @@
     }
 
     private class DisabledElevationAnimation extends ShadowAnimatorImpl {
+        DisabledElevationAnimation() {
+        }
+
         @Override
         protected float getTargetShadowSize() {
             return 0f;
diff --git a/design/ics/android/support/design/internal/BottomNavigationAnimationHelperIcs.java b/design/ics/android/support/design/internal/BottomNavigationAnimationHelperIcs.java
new file mode 100644
index 0000000..6681d0b
--- /dev/null
+++ b/design/ics/android/support/design/internal/BottomNavigationAnimationHelperIcs.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.design.internal;
+
+import android.support.transition.AutoTransition;
+import android.support.transition.TransitionManager;
+import android.support.transition.TransitionSet;
+import android.support.v4.view.animation.FastOutSlowInInterpolator;
+import android.view.ViewGroup;
+
+class BottomNavigationAnimationHelperIcs extends BottomNavigationAnimationHelperBase {
+    private static final long ACTIVE_ANIMATION_DURATION_MS = 115L;
+
+    private final TransitionSet mSet;
+
+    BottomNavigationAnimationHelperIcs() {
+        mSet = new AutoTransition();
+        mSet.setOrdering(TransitionSet.ORDERING_TOGETHER);
+        mSet.setDuration(ACTIVE_ANIMATION_DURATION_MS);
+        mSet.setInterpolator(new FastOutSlowInInterpolator());
+        TextScale textScale = new TextScale();
+        mSet.addTransition(textScale);
+    }
+
+    void beginDelayedTransition(ViewGroup view) {
+        TransitionManager.beginDelayedTransition(view, mSet);
+    }
+}
diff --git a/design/ics/android/support/design/internal/TextScale.java b/design/ics/android/support/design/internal/TextScale.java
new file mode 100644
index 0000000..219353e
--- /dev/null
+++ b/design/ics/android/support/design/internal/TextScale.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.design.internal;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.support.transition.Transition;
+import android.support.transition.TransitionValues;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import java.util.Map;
+
+/**
+ * @hide
+ */
+public class TextScale extends Transition {
+    private static final String PROPNAME_SCALE = "android:textscale:scale";
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        if (transitionValues.view instanceof TextView) {
+            TextView textview = (TextView) transitionValues.view;
+            transitionValues.values.put(PROPNAME_SCALE, textview.getScaleX());
+        }
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        if (startValues == null || endValues == null || !(startValues.view instanceof TextView)
+                || !(endValues.view instanceof TextView)) {
+            return null;
+        }
+        final TextView view = (TextView) endValues.view;
+        Map<String, Object> startVals = startValues.values;
+        Map<String, Object> endVals = endValues.values;
+        final float startSize = startVals.get(PROPNAME_SCALE) != null ? (float) startVals.get(
+                PROPNAME_SCALE) : 1f;
+        final float endSize = endVals.get(PROPNAME_SCALE) != null ? (float) endVals.get(
+                PROPNAME_SCALE) : 1f;
+        if (startSize == endSize) {
+            return null;
+        }
+
+        ValueAnimator animator = ValueAnimator.ofFloat(startSize, endSize);
+
+        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator valueAnimator) {
+                float animatedValue = (float) valueAnimator.getAnimatedValue();
+                view.setScaleX(animatedValue);
+                view.setScaleY(animatedValue);
+            }
+        });
+        return animator;
+    }
+}
diff --git a/design/res/layout/design_bottom_navigation_item.xml b/design/res/layout/design_bottom_navigation_item.xml
index d877fea..cc7bb5f 100644
--- a/design/res/layout/design_bottom_navigation_item.xml
+++ b/design/res/layout/design_bottom_navigation_item.xml
@@ -21,14 +21,26 @@
         android:layout_height="24dp"
         android:layout_gravity="center_horizontal"
         android:layout_marginTop="@dimen/design_bottom_navigation_margin"
+        android:layout_marginBottom="@dimen/design_bottom_navigation_margin"
         android:duplicateParentState="true" />
-    <TextView
-        android:id="@+id/label"
-        android:layout_width="match_parent"
+    <android.support.design.internal.BaselineLayout
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/design_bottom_navigation_margin"
-        android:layout_gravity="bottom"
-        android:textSize="@dimen/design_bottom_navigation_text_size"
-        android:gravity="center_horizontal"
-        android:duplicateParentState="true" />
+        android:layout_gravity="bottom|center_horizontal"
+        android:duplicateParentState="true">
+        <TextView
+            android:id="@+id/smallLabel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:textSize="@dimen/design_bottom_navigation_text_size"
+            android:duplicateParentState="true" />
+        <TextView
+            android:id="@+id/largeLabel"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:visibility="invisible"
+            android:textSize="@dimen/design_bottom_navigation_active_text_size"
+            android:duplicateParentState="true" />
+    </android.support.design.internal.BaselineLayout>
 </merge>
\ No newline at end of file
diff --git a/design/res/layout/design_bottom_sheet_dialog.xml b/design/res/layout/design_bottom_sheet_dialog.xml
index 27bb806..c99caa6 100644
--- a/design/res/layout/design_bottom_sheet_dialog.xml
+++ b/design/res/layout/design_bottom_sheet_dialog.xml
@@ -24,6 +24,7 @@
             android:id="@+id/touch_outside"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
+            android:importantForAccessibility="no"
             android:soundEffectsEnabled="false"/>
 
     <FrameLayout
diff --git a/design/res/values/dimens.xml b/design/res/values/dimens.xml
index 546d137..63e98b8 100644
--- a/design/res/values/dimens.xml
+++ b/design/res/values/dimens.xml
@@ -62,6 +62,7 @@
     <dimen name="design_bottom_navigation_text_size">12sp</dimen>
     <dimen name="design_bottom_navigation_active_text_size">14sp</dimen>
     <dimen name="design_bottom_navigation_margin">8dp</dimen>
+    <dimen name="design_bottom_navigation_item_min_width">56dp</dimen>
     <dimen name="design_bottom_navigation_item_max_width">96dp</dimen>
     <dimen name="design_bottom_navigation_active_item_max_width">168dp</dimen>
 
diff --git a/design/src/android/support/design/internal/BaselineLayout.java b/design/src/android/support/design/internal/BaselineLayout.java
new file mode 100644
index 0000000..eac3542
--- /dev/null
+++ b/design/src/android/support/design/internal/BaselineLayout.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.design.internal;
+
+import android.content.Context;
+import android.support.v4.view.ViewCompat;
+import android.support.v7.widget.ViewUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A simple ViewGroup that aligns all the views inside on a baseline.
+ *
+ * @hide
+ */
+public class BaselineLayout extends ViewGroup {
+    private int mBaseline = -1;
+
+    public BaselineLayout(Context context) {
+        super(context, null, 0);
+    }
+
+    public BaselineLayout(Context context, AttributeSet attrs) {
+        super(context, attrs, 0);
+    }
+
+    public BaselineLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int count = getChildCount();
+        int maxWidth = 0;
+        int maxHeight = 0;
+        int maxChildBaseline = -1;
+        int maxChildDescent = -1;
+        int childState = 0;
+
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+
+            measureChild(child, widthMeasureSpec, heightMeasureSpec);
+            final int baseline = child.getBaseline();
+            if (baseline != -1) {
+                maxChildBaseline = Math.max(maxChildBaseline, baseline);
+                maxChildDescent = Math.max(maxChildDescent, child.getMeasuredHeight() - baseline);
+            }
+            maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
+            maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
+            childState = ViewUtils.combineMeasuredStates(childState,
+                    ViewCompat.getMeasuredState(child));
+        }
+        if (maxChildBaseline != -1) {
+            maxHeight = Math.max(maxHeight, maxChildBaseline + maxChildDescent);
+            mBaseline = maxChildBaseline;
+        }
+        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+        setMeasuredDimension(
+                ViewCompat.resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+                ViewCompat.resolveSizeAndState(maxHeight, heightMeasureSpec,
+                        childState << MEASURED_HEIGHT_STATE_SHIFT));
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        final int count = getChildCount();
+        final int parentLeft = getPaddingLeft();
+        final int parentRight = right - left - getPaddingRight();
+        final int parentContentWidth = parentRight - parentLeft;
+        final int parentTop = getPaddingTop();
+
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+
+            final int width = child.getMeasuredWidth();
+            final int height = child.getMeasuredHeight();
+
+            final int childLeft = parentLeft + (parentContentWidth - width) / 2;
+            final int childTop;
+            if (mBaseline != -1 && child.getBaseline() != -1) {
+                childTop = parentTop + mBaseline - child.getBaseline();
+            } else {
+                childTop = parentTop;
+            }
+
+            child.layout(childLeft, childTop, childLeft + width, childTop + height);
+        }
+    }
+
+    @Override
+    public int getBaseline() {
+        return mBaseline;
+    }
+}
diff --git a/design/src/android/support/design/internal/BottomNavigationItemView.java b/design/src/android/support/design/internal/BottomNavigationItemView.java
index 18c6036..ea22399 100644
--- a/design/src/android/support/design/internal/BottomNavigationItemView.java
+++ b/design/src/android/support/design/internal/BottomNavigationItemView.java
@@ -16,45 +16,47 @@
 
 package android.support.design.internal;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.design.R;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v4.view.ViewCompat;
-import android.support.v4.view.animation.LinearOutSlowInInterpolator;
 import android.support.v7.view.menu.MenuItemImpl;
 import android.support.v7.view.menu.MenuView;
 import android.util.AttributeSet;
-import android.util.TypedValue;
+import android.view.Gravity;
 import android.view.LayoutInflater;
-import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class BottomNavigationItemView extends FrameLayout implements MenuView.ItemView {
-    public static final int INVALID_ITEM_POSTION = -1;
+    public static final int INVALID_ITEM_POSITION = -1;
 
     private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
-    private static final long ACTIVE_ANIMATION_DURATION_MS = 115L;
 
-    private final float mShiftAmount;
+    private final int mDefaultMargin;
+    private final int mShiftAmount;
     private final float mScaleUpFactor;
     private final float mScaleDownFactor;
-    private final float mInactiveLabelSize;
-    private final float mActiveLabelSize;
+
+    private boolean mShiftingMode;
 
     private ImageView mIcon;
-    private TextView mLabel;
-    private int mItemPosition = INVALID_ITEM_POSTION;
+    private final TextView mSmallLabel;
+    private final TextView mLargeLabel;
+    private int mItemPosition = INVALID_ITEM_POSITION;
 
     private MenuItemImpl mItemData;
 
@@ -70,25 +72,29 @@
 
     public BottomNavigationItemView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mInactiveLabelSize =
-                getResources().getDimension(R.dimen.design_bottom_navigation_text_size);
-        mActiveLabelSize =
-                getResources().getDimension(R.dimen.design_bottom_navigation_active_text_size);
-        mShiftAmount = mInactiveLabelSize - mActiveLabelSize;
-        mScaleUpFactor = mActiveLabelSize / mInactiveLabelSize;
-        mScaleDownFactor = mInactiveLabelSize / mActiveLabelSize;
+        final Resources res = getResources();
+        int inactiveLabelSize =
+                res.getDimensionPixelSize(R.dimen.design_bottom_navigation_text_size);
+        int activeLabelSize = res.getDimensionPixelSize(
+                R.dimen.design_bottom_navigation_active_text_size);
+        mDefaultMargin = res.getDimensionPixelSize(R.dimen.design_bottom_navigation_margin);
+        mShiftAmount = inactiveLabelSize - activeLabelSize;
+        mScaleUpFactor = 1f * activeLabelSize / inactiveLabelSize;
+        mScaleDownFactor = 1f * inactiveLabelSize / activeLabelSize;
 
         LayoutInflater.from(context).inflate(R.layout.design_bottom_navigation_item, this, true);
         setBackgroundResource(R.drawable.design_bottom_navigation_item_background);
         mIcon = (ImageView) findViewById(R.id.icon);
-        mLabel = (TextView) findViewById(R.id.label);
+        mSmallLabel = (TextView) findViewById(R.id.smallLabel);
+        mLargeLabel = (TextView) findViewById(R.id.largeLabel);
+
     }
 
     @Override
     public void initialize(MenuItemImpl itemData, int menuType) {
         mItemData = itemData;
         setCheckable(itemData.isCheckable());
-        setChecked(itemData.isChecked(), false);
+        setChecked(itemData.isChecked());
         setEnabled(itemData.isEnabled());
         setIcon(itemData.getIcon());
         setTitle(itemData.getTitle());
@@ -103,6 +109,10 @@
         return mItemPosition;
     }
 
+    public void setShiftingMode(boolean enabled) {
+        mShiftingMode = enabled;
+    }
+
     @Override
     public MenuItemImpl getItemData() {
         return mItemData;
@@ -110,7 +120,8 @@
 
     @Override
     public void setTitle(CharSequence title) {
-        mLabel.setText(title);
+        mSmallLabel.setText(title);
+        mLargeLabel.setText(title);
     }
 
     @Override
@@ -120,19 +131,56 @@
 
     @Override
     public void setChecked(boolean checked) {
-        setChecked(checked, true);
-    }
-
-    public void setChecked(boolean checked, boolean animate) {
         mItemData.setChecked(checked);
 
-        mLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
-                checked ? mActiveLabelSize : mInactiveLabelSize);
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
-            if (animate) {
-                animate(checked);
+        ViewCompat.setPivotX(mLargeLabel, mLargeLabel.getWidth() / 2);
+        ViewCompat.setPivotY(mLargeLabel, mLargeLabel.getBaseline());
+        ViewCompat.setPivotX(mSmallLabel, mSmallLabel.getWidth() / 2);
+        ViewCompat.setPivotY(mSmallLabel, mSmallLabel.getBaseline());
+        if (mShiftingMode) {
+            if (checked) {
+                LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
+                iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+                iconParams.topMargin = mDefaultMargin;
+                mIcon.setLayoutParams(iconParams);
+                mLargeLabel.setVisibility(VISIBLE);
+                ViewCompat.setScaleX(mLargeLabel, 1f);
+                ViewCompat.setScaleY(mLargeLabel, 1f);
             } else {
-                mIcon.setTranslationY(checked ? mShiftAmount : 0f);
+                LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
+                iconParams.gravity = Gravity.CENTER;
+                iconParams.topMargin = mDefaultMargin;
+                mIcon.setLayoutParams(iconParams);
+                mLargeLabel.setVisibility(INVISIBLE);
+                ViewCompat.setScaleX(mLargeLabel, 0.5f);
+                ViewCompat.setScaleY(mLargeLabel, 0.5f);
+            }
+            mSmallLabel.setVisibility(INVISIBLE);
+        } else {
+            if (checked) {
+                LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
+                iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+                iconParams.topMargin = mDefaultMargin + mShiftAmount;
+                mIcon.setLayoutParams(iconParams);
+                mLargeLabel.setVisibility(VISIBLE);
+                mSmallLabel.setVisibility(INVISIBLE);
+
+                ViewCompat.setScaleX(mLargeLabel, 1f);
+                ViewCompat.setScaleY(mLargeLabel, 1f);
+                ViewCompat.setScaleX(mSmallLabel, mScaleUpFactor);
+                ViewCompat.setScaleY(mSmallLabel, mScaleUpFactor);
+            } else {
+                LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
+                iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
+                iconParams.topMargin = mDefaultMargin;
+                mIcon.setLayoutParams(iconParams);
+                mLargeLabel.setVisibility(INVISIBLE);
+                mSmallLabel.setVisibility(VISIBLE);
+
+                ViewCompat.setScaleX(mLargeLabel, mScaleDownFactor);
+                ViewCompat.setScaleY(mLargeLabel, mScaleDownFactor);
+                ViewCompat.setScaleX(mSmallLabel, 1f);
+                ViewCompat.setScaleY(mSmallLabel, 1f);
             }
         }
 
@@ -142,7 +190,8 @@
     @Override
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
-        mLabel.setEnabled(enabled);
+        mSmallLabel.setEnabled(enabled);
+        mLargeLabel.setEnabled(enabled);
         mIcon.setEnabled(enabled);
     }
 
@@ -188,7 +237,8 @@
     }
 
     public void setTextColor(ColorStateList color) {
-        mLabel.setTextColor(color);
+        mSmallLabel.setTextColor(color);
+        mLargeLabel.setTextColor(color);
     }
 
     public void setItemBackground(int background) {
@@ -196,26 +246,4 @@
                 ? null : ContextCompat.getDrawable(getContext(), background);
         ViewCompat.setBackground(this, backgroundDrawable);
     }
-
-    @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
-    private void animate(final boolean active) {
-        final float startingTextScale = active ? mScaleDownFactor : mScaleUpFactor;
-
-        // Grow or shrink the text of the tab.
-        mLabel.setScaleX(startingTextScale);
-        mLabel.setScaleY(startingTextScale);
-        ViewPropertyAnimator textAnimator = mLabel.animate()
-                .setDuration(ACTIVE_ANIMATION_DURATION_MS)
-                .setInterpolator(new LinearOutSlowInInterpolator())
-                .scaleX(1f)
-                .scaleY(1f);
-
-        ViewPropertyAnimator translationAnimation = mIcon.animate()
-                .setDuration(ACTIVE_ANIMATION_DURATION_MS)
-                .setInterpolator(new LinearOutSlowInInterpolator())
-                .translationY(active ? mShiftAmount : 0);
-
-        textAnimator.start();
-        translationAnimation.start();
-    }
 }
diff --git a/design/src/android/support/design/internal/BottomNavigationMenu.java b/design/src/android/support/design/internal/BottomNavigationMenu.java
index d813ea2..8832097 100644
--- a/design/src/android/support/design/internal/BottomNavigationMenu.java
+++ b/design/src/android/support/design/internal/BottomNavigationMenu.java
@@ -17,13 +17,17 @@
 package android.support.design.internal;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v7.view.menu.MenuBuilder;
 import android.view.MenuItem;
 import android.view.SubMenu;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class BottomNavigationMenu extends MenuBuilder {
     public static final int MAX_ITEM_COUNT = 5;
 
diff --git a/design/src/android/support/design/internal/BottomNavigationMenuView.java b/design/src/android/support/design/internal/BottomNavigationMenuView.java
index 7080d2e..158dda7 100644
--- a/design/src/android/support/design/internal/BottomNavigationMenuView.java
+++ b/design/src/android/support/design/internal/BottomNavigationMenuView.java
@@ -18,28 +18,38 @@
 
 import android.content.Context;
 import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.os.Build;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.design.R;
 import android.support.v4.util.Pools;
+import android.support.v4.view.ViewCompat;
 import android.support.v7.view.menu.MenuBuilder;
 import android.support.v7.view.menu.MenuItemImpl;
 import android.support.v7.view.menu.MenuView;
 import android.util.AttributeSet;
-import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.LinearLayout;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
- * @hide
+ * @hide For internal use only.
  */
-public class BottomNavigationMenuView extends LinearLayout implements MenuView {
+@RestrictTo(GROUP_ID)
+public class BottomNavigationMenuView extends ViewGroup implements MenuView {
     private final int mInactiveItemMaxWidth;
+    private final int mInactiveItemMinWidth;
     private final int mActiveItemMaxWidth;
+    private final int mItemHeight;
     private final OnClickListener mOnClickListener;
+    private final BottomNavigationAnimationHelperBase mAnimationHelper;
     private static final Pools.Pool<BottomNavigationItemView> sItemPool =
             new Pools.SynchronizedPool<>(5);
 
+    private boolean mShiftingMode = true;
+
     private BottomNavigationItemView[] mButtons;
     private int mActiveButton = 0;
     private ColorStateList mItemIconTint;
@@ -55,13 +65,20 @@
 
     public BottomNavigationMenuView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        setGravity(Gravity.CENTER);
-        setOrientation(HORIZONTAL);
-
-        mInactiveItemMaxWidth = getResources().getDimensionPixelSize(
+        final Resources res = getResources();
+        mInactiveItemMaxWidth = res.getDimensionPixelSize(
                 R.dimen.design_bottom_navigation_item_max_width);
-        mActiveItemMaxWidth = getResources()
-                .getDimensionPixelSize(R.dimen.design_bottom_navigation_active_item_max_width);
+        mInactiveItemMinWidth = res.getDimensionPixelSize(
+                R.dimen.design_bottom_navigation_item_min_width);
+        mActiveItemMaxWidth = res.getDimensionPixelSize(
+                R.dimen.design_bottom_navigation_active_item_max_width);
+        mItemHeight = res.getDimensionPixelSize(R.dimen.design_bottom_navigation_height);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            mAnimationHelper = new BottomNavigationAnimationHelperIcs();
+        } else {
+            mAnimationHelper = new BottomNavigationAnimationHelperBase();
+        }
 
         mOnClickListener = new OnClickListener() {
             @Override
@@ -84,6 +101,81 @@
     }
 
     @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        final int width = MeasureSpec.getSize(widthMeasureSpec);
+        final int count = getChildCount();
+
+        final int childState = 0;
+        final int heightSpec = MeasureSpec.makeMeasureSpec(mItemHeight, MeasureSpec.EXACTLY);
+
+        final int[] childWidths = new int[count];
+        if (mShiftingMode) {
+            final int inactiveCount = count - 1;
+            final int activeMaxAvailable = width - inactiveCount * mInactiveItemMinWidth;
+            final int activeWidth = Math.min(activeMaxAvailable, mActiveItemMaxWidth);
+            final int inactiveMaxAvailable = (width - activeWidth) / inactiveCount;
+            final int inactiveWidth = Math.min(inactiveMaxAvailable, mInactiveItemMaxWidth);
+            int extra = width - activeWidth - inactiveWidth * inactiveCount;
+            for (int i = 0; i < count; i++) {
+                childWidths[i] = (i == mActiveButton) ? activeWidth : inactiveWidth;
+                if (extra > 0) {
+                    childWidths[i]++;
+                    extra--;
+                }
+            }
+        } else {
+            final int maxAvailable = width / count;
+            final int childWidth = Math.min(maxAvailable, mActiveItemMaxWidth);
+            int extra = width - childWidth * count;
+            for (int i = 0; i < count; i++) {
+                childWidths[i] = childWidth;
+                if (extra > 0) {
+                    childWidths[i]++;
+                    extra--;
+                }
+            }
+        }
+
+        int totalWidth = 0;
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+            child.measure(MeasureSpec.makeMeasureSpec(childWidths[i], MeasureSpec.EXACTLY),
+                    heightSpec);
+            ViewGroup.LayoutParams params = child.getLayoutParams();
+            params.width = child.getMeasuredWidth();
+            totalWidth += child.getMeasuredWidth();
+        }
+        setMeasuredDimension(
+                ViewCompat.resolveSizeAndState(totalWidth,
+                        MeasureSpec.makeMeasureSpec(totalWidth, MeasureSpec.EXACTLY), childState),
+                ViewCompat.resolveSizeAndState(mItemHeight, heightSpec,
+                        childState << MEASURED_HEIGHT_STATE_SHIFT));
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        final int count = getChildCount();
+        final int width = right - left;
+        final int height = bottom - top;
+        int used = 0;
+        for (int i = 0; i < count; i++) {
+            final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
+            if (ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL) {
+                child.layout(width - used - child.getMeasuredWidth(), 0, width - used, height);
+            } else {
+                child.layout(used, 0, child.getMeasuredWidth() + used, height);
+            }
+            used += child.getMeasuredWidth();
+        }
+    }
+
+    @Override
     public int getWindowAnimations() {
         return 0;
     }
@@ -137,6 +229,7 @@
         }
         removeAllViews();
         mButtons = new BottomNavigationItemView[mMenu.size()];
+        mShiftingMode = mMenu.size() > 3;
         for (int i = 0; i < mMenu.size(); i++) {
             mPresenter.setUpdateSuspended(true);
             mMenu.getItem(i).setCheckable(true);
@@ -146,6 +239,7 @@
             child.setIconTintList(mItemIconTint);
             child.setTextColor(mItemTextColor);
             child.setItemBackground(mItemBackgroundRes);
+            child.setShiftingMode(mShiftingMode);
             child.initialize((MenuItemImpl) mMenu.getItem(i), 0);
             child.setItemPosition(i);
             child.setOnClickListener(mOnClickListener);
@@ -170,6 +264,8 @@
     private void activateNewButton(int newButton) {
         if (mActiveButton == newButton) return;
 
+        mAnimationHelper.beginDelayedTransition(this);
+
         mPresenter.setUpdateSuspended(true);
         mButtons[mActiveButton].setChecked(false);
         mButtons[newButton].setChecked(true);
@@ -178,28 +274,6 @@
         mActiveButton = newButton;
     }
 
-    public boolean updateOnSizeChange(int width) {
-        if (getChildCount() == 0) {
-            return false;
-        }
-        int available = width / getChildCount();
-        int itemWidth = Math.min(available, mActiveItemMaxWidth);
-
-        boolean changed = false;
-
-        for (int i = 0; i < mButtons.length; i++) {
-            ViewGroup.LayoutParams params = mButtons[i].getLayoutParams();
-            if (params.width == itemWidth) {
-                continue;
-            }
-            changed = true;
-            params.width = itemWidth;
-            params.height = ViewGroup.LayoutParams.MATCH_PARENT;
-            mButtons[i].setLayoutParams(params);
-        }
-        return changed;
-    }
-
     private BottomNavigationItemView getNewItem() {
         BottomNavigationItemView item = sItemPool.acquire();
         if (item == null) {
diff --git a/design/src/android/support/design/internal/BottomNavigationPresenter.java b/design/src/android/support/design/internal/BottomNavigationPresenter.java
index 8dc0549..07e52e3 100644
--- a/design/src/android/support/design/internal/BottomNavigationPresenter.java
+++ b/design/src/android/support/design/internal/BottomNavigationPresenter.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v7.view.menu.MenuBuilder;
 import android.support.v7.view.menu.MenuItemImpl;
 import android.support.v7.view.menu.MenuPresenter;
@@ -25,9 +26,12 @@
 import android.support.v7.view.menu.SubMenuBuilder;
 import android.view.ViewGroup;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class BottomNavigationPresenter implements MenuPresenter {
     private MenuBuilder mMenu;
     private BottomNavigationMenuView mMenuView;
diff --git a/design/src/android/support/design/internal/ForegroundLinearLayout.java b/design/src/android/support/design/internal/ForegroundLinearLayout.java
index eff89e3..48a04a6 100644
--- a/design/src/android/support/design/internal/ForegroundLinearLayout.java
+++ b/design/src/android/support/design/internal/ForegroundLinearLayout.java
@@ -22,14 +22,18 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.design.R;
 import android.support.v7.widget.LinearLayoutCompat;
 import android.util.AttributeSet;
 import android.view.Gravity;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ForegroundLinearLayout extends LinearLayoutCompat {
 
     private Drawable mForeground;
diff --git a/design/src/android/support/design/internal/NavigationMenu.java b/design/src/android/support/design/internal/NavigationMenu.java
index 2821d36..f0931b0 100644
--- a/design/src/android/support/design/internal/NavigationMenu.java
+++ b/design/src/android/support/design/internal/NavigationMenu.java
@@ -17,17 +17,21 @@
 package android.support.design.internal;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v7.view.menu.MenuBuilder;
 import android.support.v7.view.menu.MenuItemImpl;
 import android.support.v7.view.menu.SubMenuBuilder;
 import android.view.SubMenu;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This is a {@link MenuBuilder} that returns an instance of {@link NavigationSubMenu} instead of
  * {@link SubMenuBuilder} when a sub menu is created.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class NavigationMenu extends MenuBuilder {
 
     public NavigationMenu(Context context) {
diff --git a/design/src/android/support/design/internal/NavigationMenuItemView.java b/design/src/android/support/design/internal/NavigationMenuItemView.java
index 39e5165..195791d 100644
--- a/design/src/android/support/design/internal/NavigationMenuItemView.java
+++ b/design/src/android/support/design/internal/NavigationMenuItemView.java
@@ -22,6 +22,7 @@
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
+import android.support.annotation.RestrictTo;
 import android.support.design.R;
 import android.support.v4.content.res.ResourcesCompat;
 import android.support.v4.graphics.drawable.DrawableCompat;
@@ -40,9 +41,12 @@
 import android.widget.CheckedTextView;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class NavigationMenuItemView extends ForegroundLinearLayout implements MenuView.ItemView {
 
     private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};
@@ -51,7 +55,7 @@
 
     private boolean mNeedsEmptyIcon;
 
-    private boolean mCheckable;
+    boolean mCheckable;
 
     private final CheckedTextView mTextView;
 
diff --git a/design/src/android/support/design/internal/NavigationMenuPresenter.java b/design/src/android/support/design/internal/NavigationMenuPresenter.java
index 455199f..d1f0c22 100644
--- a/design/src/android/support/design/internal/NavigationMenuPresenter.java
+++ b/design/src/android/support/design/internal/NavigationMenuPresenter.java
@@ -26,6 +26,7 @@
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.design.R;
 import android.support.v4.view.ViewCompat;
@@ -46,29 +47,32 @@
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class NavigationMenuPresenter implements MenuPresenter {
 
     private static final String STATE_HIERARCHY = "android:menu:list";
     private static final String STATE_ADAPTER = "android:menu:adapter";
 
     private NavigationMenuView mMenuView;
-    private LinearLayout mHeaderLayout;
+    LinearLayout mHeaderLayout;
 
     private Callback mCallback;
-    private MenuBuilder mMenu;
+    MenuBuilder mMenu;
     private int mId;
 
-    private NavigationMenuAdapter mAdapter;
-    private LayoutInflater mLayoutInflater;
+    NavigationMenuAdapter mAdapter;
+    LayoutInflater mLayoutInflater;
 
-    private int mTextAppearance;
-    private boolean mTextAppearanceSet;
-    private ColorStateList mTextColor;
-    private ColorStateList mIconTintList;
-    private Drawable mItemBackground;
+    int mTextAppearance;
+    boolean mTextAppearanceSet;
+    ColorStateList mTextColor;
+    ColorStateList mIconTintList;
+    Drawable mItemBackground;
 
     /**
      * Padding to be inserted at the top of the list to avoid the first menu item
@@ -79,7 +83,7 @@
     /**
      * Padding for separators between items
      */
-    private int mPaddingSeparator;
+    int mPaddingSeparator;
 
     @Override
     public void initForMenu(Context context, MenuBuilder menu) {
@@ -318,7 +322,7 @@
     /**
      * Handles click events for the menu items. The items has to be {@link NavigationMenuItemView}.
      */
-    private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
+    final View.OnClickListener mOnClickListener = new View.OnClickListener() {
 
         @Override
         public void onClick(View v) {
@@ -612,7 +616,7 @@
 
         boolean needsEmptyIcon;
 
-        private NavigationMenuTextItem(MenuItemImpl item) {
+        NavigationMenuTextItem(MenuItemImpl item) {
             mMenuItem = item;
         }
 
@@ -650,6 +654,8 @@
      * Header (not subheader) items.
      */
     private static class NavigationMenuHeaderItem implements NavigationMenuItem {
+        NavigationMenuHeaderItem() {
+        }
         // The actual content is hold by NavigationMenuPresenter#mHeaderLayout.
     }
 
diff --git a/design/src/android/support/design/internal/NavigationMenuView.java b/design/src/android/support/design/internal/NavigationMenuView.java
index c7c90c3..628f7a8 100644
--- a/design/src/android/support/design/internal/NavigationMenuView.java
+++ b/design/src/android/support/design/internal/NavigationMenuView.java
@@ -17,15 +17,19 @@
 package android.support.design.internal;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v7.view.menu.MenuBuilder;
 import android.support.v7.view.menu.MenuView;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.util.AttributeSet;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class NavigationMenuView extends RecyclerView implements MenuView {
 
     public NavigationMenuView(Context context) {
diff --git a/design/src/android/support/design/internal/NavigationSubMenu.java b/design/src/android/support/design/internal/NavigationSubMenu.java
index f17536f..6c62033 100644
--- a/design/src/android/support/design/internal/NavigationSubMenu.java
+++ b/design/src/android/support/design/internal/NavigationSubMenu.java
@@ -17,16 +17,20 @@
 package android.support.design.internal;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v7.view.menu.MenuBuilder;
 import android.support.v7.view.menu.MenuItemImpl;
 import android.support.v7.view.menu.SubMenuBuilder;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This is a {@link SubMenuBuilder} that it notifies the parent {@link NavigationMenu} of its menu
  * updates.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class NavigationSubMenu extends SubMenuBuilder {
 
     public NavigationSubMenu(Context context, NavigationMenu menu, MenuItemImpl item) {
diff --git a/design/src/android/support/design/internal/ParcelableSparseArray.java b/design/src/android/support/design/internal/ParcelableSparseArray.java
index 588950b..05870b0 100644
--- a/design/src/android/support/design/internal/ParcelableSparseArray.java
+++ b/design/src/android/support/design/internal/ParcelableSparseArray.java
@@ -18,13 +18,17 @@
 
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.os.ParcelableCompat;
 import android.support.v4.os.ParcelableCompatCreatorCallbacks;
 import android.util.SparseArray;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ParcelableSparseArray extends SparseArray<Parcelable> implements Parcelable {
 
     public ParcelableSparseArray() {
diff --git a/design/src/android/support/design/internal/ScrimInsetsFrameLayout.java b/design/src/android/support/design/internal/ScrimInsetsFrameLayout.java
index 80aee76..80010a9 100644
--- a/design/src/android/support/design/internal/ScrimInsetsFrameLayout.java
+++ b/design/src/android/support/design/internal/ScrimInsetsFrameLayout.java
@@ -22,6 +22,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.design.R;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.WindowInsetsCompat;
@@ -29,14 +30,17 @@
 import android.view.View;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ScrimInsetsFrameLayout extends FrameLayout {
 
-    private Drawable mInsetForeground;
+    Drawable mInsetForeground;
 
-    private Rect mInsets;
+    Rect mInsets;
 
     private Rect mTempRect = new Rect();
 
diff --git a/design/src/android/support/design/internal/package-info.java b/design/src/android/support/design/internal/package-info.java
new file mode 100644
index 0000000..92fc776
--- /dev/null
+++ b/design/src/android/support/design/internal/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * @hide
+ */
+@RestrictTo(GROUP_ID)
+package android.support.design.internal;
+
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
diff --git a/design/src/android/support/design/widget/AppBarLayout.java b/design/src/android/support/design/widget/AppBarLayout.java
index 0e48be5..aa76a6b 100644
--- a/design/src/android/support/design/widget/AppBarLayout.java
+++ b/design/src/android/support/design/widget/AppBarLayout.java
@@ -25,6 +25,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.VisibleForTesting;
 import android.support.design.R;
 import android.support.v4.os.ParcelableCompat;
@@ -44,6 +45,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.design.widget.ViewUtils.objectEquals;
 
 /**
@@ -103,10 +105,10 @@
 @CoordinatorLayout.DefaultBehavior(AppBarLayout.Behavior.class)
 public class AppBarLayout extends LinearLayout {
 
-    private static final int PENDING_ACTION_NONE = 0x0;
-    private static final int PENDING_ACTION_EXPANDED = 0x1;
-    private static final int PENDING_ACTION_COLLAPSED = 0x2;
-    private static final int PENDING_ACTION_ANIMATE_ENABLED = 0x4;
+    static final int PENDING_ACTION_NONE = 0x0;
+    static final int PENDING_ACTION_EXPANDED = 0x1;
+    static final int PENDING_ACTION_COLLAPSED = 0x2;
+    static final int PENDING_ACTION_ANIMATE_ENABLED = 0x4;
 
     /**
      * Interface definition for a callback to be invoked when an {@link AppBarLayout}'s vertical
@@ -325,7 +327,7 @@
         return new LayoutParams(p);
     }
 
-    private boolean hasChildWithInterpolator() {
+    boolean hasChildWithInterpolator() {
         return mHaveChildWithInterpolator;
     }
 
@@ -366,21 +368,21 @@
         return mTotalScrollRange = Math.max(0, range - getTopInset());
     }
 
-    private boolean hasScrollableChildren() {
+    boolean hasScrollableChildren() {
         return getTotalScrollRange() != 0;
     }
 
     /**
      * Return the scroll range when scrolling up from a nested pre-scroll.
      */
-    private int getUpNestedPreScrollRange() {
+    int getUpNestedPreScrollRange() {
         return getTotalScrollRange();
     }
 
     /**
      * Return the scroll range when scrolling down from a nested pre-scroll.
      */
-    private int getDownNestedPreScrollRange() {
+    int getDownNestedPreScrollRange() {
         if (mDownPreScrollRange != INVALID_SCROLL_RANGE) {
             // If we already have a valid value, return it
             return mDownPreScrollRange;
@@ -419,7 +421,7 @@
     /**
      * Return the scroll range when scrolling down from a nested scroll.
      */
-    private int getDownNestedScrollRange() {
+    int getDownNestedScrollRange() {
         if (mDownScrollRange != INVALID_SCROLL_RANGE) {
             // If we already have a valid value, return it
             return mDownScrollRange;
@@ -454,7 +456,7 @@
         return mDownScrollRange = Math.max(0, range);
     }
 
-    private void dispatchOffsetUpdates(int offset) {
+    void dispatchOffsetUpdates(int offset) {
         // Iterate backwards through the list so that most recently added listeners
         // get the first chance to decide
         if (mListeners != null) {
@@ -519,7 +521,7 @@
      *
      * @return true if the collapsed state changed
      */
-    private boolean setCollapsedState(boolean collapsed) {
+    boolean setCollapsedState(boolean collapsed) {
         if (mCollapsed != collapsed) {
             mCollapsed = collapsed;
             refreshDrawableState();
@@ -553,11 +555,11 @@
         return 0;
     }
 
-    private int getPendingAction() {
+    int getPendingAction() {
         return mPendingAction;
     }
 
-    private void resetPendingAction() {
+    void resetPendingAction() {
         mPendingAction = PENDING_ACTION_NONE;
     }
 
@@ -566,7 +568,7 @@
         return mLastInsets != null ? mLastInsets.getSystemWindowInsetTop() : 0;
     }
 
-    private WindowInsetsCompat onWindowInsetChanged(final WindowInsetsCompat insets) {
+    WindowInsetsCompat onWindowInsetChanged(final WindowInsetsCompat insets) {
         WindowInsetsCompat newInsets = null;
 
         if (ViewCompat.getFitsSystemWindows(this)) {
@@ -586,6 +588,7 @@
     public static class LayoutParams extends LinearLayout.LayoutParams {
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         @IntDef(flag=true, value={
                 SCROLL_FLAG_SCROLL,
                 SCROLL_FLAG_EXIT_UNTIL_COLLAPSED,
@@ -742,7 +745,7 @@
         /**
          * Returns true if the scroll flags are compatible for 'collapsing'
          */
-        private boolean isCollapsible() {
+        boolean isCollapsible() {
             return (mScrollFlags & SCROLL_FLAG_SCROLL) == SCROLL_FLAG_SCROLL
                     && (mScrollFlags & COLLAPSIBLE_FLAGS) != 0;
         }
@@ -1280,20 +1283,20 @@
         }
 
         @Override
-        public Parcelable onSaveInstanceState(CoordinatorLayout parent, AppBarLayout appBarLayout) {
-            final Parcelable superState = super.onSaveInstanceState(parent, appBarLayout);
+        public Parcelable onSaveInstanceState(CoordinatorLayout parent, AppBarLayout abl) {
+            final Parcelable superState = super.onSaveInstanceState(parent, abl);
             final int offset = getTopAndBottomOffset();
 
             // Try and find the first visible child...
-            for (int i = 0, count = appBarLayout.getChildCount(); i < count; i++) {
-                View child = appBarLayout.getChildAt(i);
+            for (int i = 0, count = abl.getChildCount(); i < count; i++) {
+                View child = abl.getChildAt(i);
                 final int visBottom = child.getBottom() + offset;
 
                 if (child.getTop() + offset <= 0 && visBottom >= 0) {
                     final SavedState ss = new SavedState(superState);
                     ss.firstVisibleChildIndex = i;
                     ss.firstVisibleChildAtMinimumHeight =
-                            visBottom == ViewCompat.getMinimumHeight(child);
+                            visBottom == (ViewCompat.getMinimumHeight(child) + abl.getTopInset());
                     ss.firstVisibleChildPercentageShown = visBottom / (float) child.getHeight();
                     return ss;
                 }
diff --git a/design/src/android/support/design/widget/BottomNavigationView.java b/design/src/android/support/design/widget/BottomNavigationView.java
index c5e6ea1..476889f 100644
--- a/design/src/android/support/design/widget/BottomNavigationView.java
+++ b/design/src/android/support/design/widget/BottomNavigationView.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.res.ColorStateList;
-import android.os.Parcelable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
@@ -32,12 +31,12 @@
 import android.support.v7.widget.TintTypedArray;
 import android.util.AttributeSet;
 import android.util.TypedValue;
+import android.view.Gravity;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
 
 /**
  * <p>
@@ -96,8 +95,9 @@
         mMenu = new BottomNavigationMenu(context);
 
         mMenuView = new BottomNavigationMenuView(context);
-        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
-                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+        params.gravity = Gravity.CENTER;
         mMenuView.setLayoutParams(params);
 
         mPresenter.setBottomNavigationMenuView(mMenuView);
@@ -133,7 +133,7 @@
         }
         a.recycle();
 
-        addView(mMenuView);
+        addView(mMenuView, params);
 
         mMenu.setCallback(new MenuBuilder.Callback() {
             @Override
@@ -156,14 +156,6 @@
         mListener = listener;
     }
 
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        if (mMenuView.updateOnSizeChange(getMeasuredWidth())) {
-            // updateOnSizeChanged has changed LPs, so we need to remeasure
-            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        }
-    }
-
     /**
      * Returns the {@link Menu} instance associated with this bottom navigation bar.
      */
@@ -275,7 +267,7 @@
          *
          * @return true to display the item as the selected item
          */
-        public boolean onNavigationItemSelected(@NonNull MenuItem item);
+        boolean onNavigationItemSelected(@NonNull MenuItem item);
     }
 
     private MenuInflater getMenuInflater() {
diff --git a/design/src/android/support/design/widget/BottomSheetBehavior.java b/design/src/android/support/design/widget/BottomSheetBehavior.java
index 80689ef..c3362a8 100644
--- a/design/src/android/support/design/widget/BottomSheetBehavior.java
+++ b/design/src/android/support/design/widget/BottomSheetBehavior.java
@@ -22,6 +22,7 @@
 import android.os.Parcelable;
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.VisibleForTesting;
 import android.support.design.R;
 import android.support.v4.os.ParcelableCompat;
@@ -45,6 +46,8 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 
 /**
  * An interaction behavior plugin for a child view of {@link CoordinatorLayout} to make it work as
@@ -105,6 +108,7 @@
     public static final int STATE_HIDDEN = 5;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({STATE_EXPANDED, STATE_COLLAPSED, STATE_DRAGGING, STATE_SETTLING, STATE_HIDDEN})
     @Retention(RetentionPolicy.SOURCE)
     public @interface State {}
@@ -129,18 +133,18 @@
 
     private int mPeekHeightMin;
 
-    private int mMinOffset;
+    int mMinOffset;
 
-    private int mMaxOffset;
+    int mMaxOffset;
 
-    private boolean mHideable;
+    boolean mHideable;
 
     private boolean mSkipCollapsed;
 
     @State
-    private int mState = STATE_COLLAPSED;
+    int mState = STATE_COLLAPSED;
 
-    private ViewDragHelper mViewDragHelper;
+    ViewDragHelper mViewDragHelper;
 
     private boolean mIgnoreEvents;
 
@@ -148,21 +152,21 @@
 
     private boolean mNestedScrolled;
 
-    private int mParentHeight;
+    int mParentHeight;
 
-    private WeakReference<V> mViewRef;
+    WeakReference<V> mViewRef;
 
-    private WeakReference<View> mNestedScrollingChildRef;
+    WeakReference<View> mNestedScrollingChildRef;
 
     private BottomSheetCallback mCallback;
 
     private VelocityTracker mVelocityTracker;
 
-    private int mActivePointerId;
+    int mActivePointerId;
 
     private int mInitialY;
 
-    private boolean mTouchingScrollingChild;
+    boolean mTouchingScrollingChild;
 
     /**
      * Default constructor for instantiating BottomSheetBehaviors.
@@ -254,6 +258,7 @@
     @Override
     public boolean onInterceptTouchEvent(CoordinatorLayout parent, V child, MotionEvent event) {
         if (!child.isShown()) {
+            mIgnoreEvents = true;
             return false;
         }
         int action = MotionEventCompat.getActionMasked(event);
@@ -561,7 +566,7 @@
         return mState;
     }
 
-    private void setStateInternal(@State int state) {
+    void setStateInternal(@State int state) {
         if (mState == state) {
             return;
         }
@@ -580,7 +585,7 @@
         }
     }
 
-    private boolean shouldHide(View child, float yvel) {
+    boolean shouldHide(View child, float yvel) {
         if (mSkipCollapsed) {
             return true;
         }
@@ -613,7 +618,7 @@
         return VelocityTrackerCompat.getYVelocity(mVelocityTracker, mActivePointerId);
     }
 
-    private void startSettlingAnimation(View child, int state) {
+    void startSettlingAnimation(View child, int state) {
         int top;
         if (state == STATE_COLLAPSED) {
             top = mMaxOffset;
@@ -714,11 +719,12 @@
         }
     };
 
-    private void dispatchOnSlide(int top) {
+    void dispatchOnSlide(int top) {
         View bottomSheet = mViewRef.get();
         if (bottomSheet != null && mCallback != null) {
             if (top > mMaxOffset) {
-                mCallback.onSlide(bottomSheet, (float) (mMaxOffset - top) / mPeekHeight);
+                mCallback.onSlide(bottomSheet, (float) (mMaxOffset - top) /
+                        (mParentHeight - mMaxOffset));
             } else {
                 mCallback.onSlide(bottomSheet,
                         (float) (mMaxOffset - top) / ((mMaxOffset - mMinOffset)));
diff --git a/design/src/android/support/design/widget/BottomSheetDialog.java b/design/src/android/support/design/widget/BottomSheetDialog.java
index 0473e54..4c124f3 100644
--- a/design/src/android/support/design/widget/BottomSheetDialog.java
+++ b/design/src/android/support/design/widget/BottomSheetDialog.java
@@ -38,7 +38,7 @@
 
     private BottomSheetBehavior<FrameLayout> mBehavior;
 
-    private boolean mCancelable = true;
+    boolean mCancelable = true;
     private boolean mCanceledOnTouchOutside = true;
     private boolean mCanceledOnTouchOutsideSet;
 
@@ -130,7 +130,7 @@
         return coordinator;
     }
 
-    private boolean shouldWindowCloseOnTouchOutside() {
+    boolean shouldWindowCloseOnTouchOutside() {
         if (!mCanceledOnTouchOutsideSet) {
             if (Build.VERSION.SDK_INT < 11) {
                 mCanceledOnTouchOutside = true;
diff --git a/design/src/android/support/design/widget/CheckableImageButton.java b/design/src/android/support/design/widget/CheckableImageButton.java
index 2e7612b..13e99b2 100644
--- a/design/src/android/support/design/widget/CheckableImageButton.java
+++ b/design/src/android/support/design/widget/CheckableImageButton.java
@@ -17,6 +17,7 @@
 package android.support.design.widget;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.AccessibilityDelegateCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
@@ -27,9 +28,12 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.Checkable;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class CheckableImageButton extends AppCompatImageButton implements Checkable {
 
     private static final int[] DRAWABLE_STATE_CHECKED = new int[]{android.R.attr.state_checked};
diff --git a/design/src/android/support/design/widget/CollapsingToolbarLayout.java b/design/src/android/support/design/widget/CollapsingToolbarLayout.java
index 6d95dec..39ad03b 100644
--- a/design/src/android/support/design/widget/CollapsingToolbarLayout.java
+++ b/design/src/android/support/design/widget/CollapsingToolbarLayout.java
@@ -30,6 +30,7 @@
 import android.support.annotation.IntRange;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.design.R;
 import android.support.v4.content.ContextCompat;
@@ -49,6 +50,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.design.widget.MathUtils.constrain;
 import static android.support.design.widget.ViewUtils.objectEquals;
 
@@ -114,12 +116,12 @@
     private int mExpandedMarginBottom;
 
     private final Rect mTmpRect = new Rect();
-    private final CollapsingTextHelper mCollapsingTextHelper;
+    final CollapsingTextHelper mCollapsingTextHelper;
     private boolean mCollapsingTitleEnabled;
     private boolean mDrawCollapsingTitle;
 
     private Drawable mContentScrim;
-    private Drawable mStatusBarScrim;
+    Drawable mStatusBarScrim;
     private int mScrimAlpha;
     private boolean mScrimsAreShown;
     private ValueAnimatorCompat mScrimAnimator;
@@ -128,9 +130,9 @@
 
     private AppBarLayout.OnOffsetChangedListener mOnOffsetChangedListener;
 
-    private int mCurrentOffset;
+    int mCurrentOffset;
 
-    private WindowInsetsCompat mLastInsets;
+    WindowInsetsCompat mLastInsets;
 
     public CollapsingToolbarLayout(Context context) {
         this(context, null);
@@ -258,7 +260,7 @@
         super.onDetachedFromWindow();
     }
 
-    private WindowInsetsCompat onWindowInsetChanged(final WindowInsetsCompat insets) {
+    WindowInsetsCompat onWindowInsetChanged(final WindowInsetsCompat insets) {
         WindowInsetsCompat newInsets = null;
 
         if (ViewCompat.getFitsSystemWindows(this)) {
@@ -272,7 +274,9 @@
             requestLayout();
         }
 
-        return insets;
+        // Consume the insets. This is done so that child views with fitSystemWindows=true do not
+        // get the default padding functionality from View
+        return insets.consumeSystemWindowInsets();
     }
 
     @Override
@@ -409,20 +413,19 @@
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
         super.onLayout(changed, left, top, right, bottom);
 
-        // Update our child view offset helpers
-        for (int i = 0, z = getChildCount(); i < z; i++) {
-            final View child = getChildAt(i);
-
-            if (mLastInsets != null && !ViewCompat.getFitsSystemWindows(child)) {
-                final int insetTop = mLastInsets.getSystemWindowInsetTop();
-                if (child.getTop() < insetTop) {
-                    // If the child isn't set to fit system windows but is drawing within the inset
-                    // offset it down
-                    ViewCompat.offsetTopAndBottom(child, insetTop);
+        if (mLastInsets != null) {
+            // Shift down any views which are not set to fit system windows
+            final int insetTop = mLastInsets.getSystemWindowInsetTop();
+            for (int i = 0, z = getChildCount(); i < z; i++) {
+                final View child = getChildAt(i);
+                if (!ViewCompat.getFitsSystemWindows(child)) {
+                    if (child.getTop() < insetTop) {
+                        // If the child isn't set to fit system windows but is drawing within
+                        // the inset offset it down
+                        ViewCompat.offsetTopAndBottom(child, insetTop);
+                    }
                 }
             }
-
-            getViewOffsetHelper(child).onViewLayout();
         }
 
         // Update the collapsed bounds by getting it's transformed bounds
@@ -453,7 +456,7 @@
                 // Update the expanded bounds
                 mCollapsingTextHelper.setExpandedBounds(
                         isRtl ? mExpandedMarginEnd : mExpandedMarginStart,
-                        mExpandedMarginTop,
+                        mTmpRect.top + mExpandedMarginTop,
                         right - left - (isRtl ? mExpandedMarginStart : mExpandedMarginEnd),
                         bottom - top - mExpandedMarginBottom);
                 // Now recalculate using the new bounds
@@ -461,6 +464,12 @@
             }
         }
 
+        // Update our child view offset helpers. This needs to be done after the title has been
+        // setup, so that any Toolbars are in their original position
+        for (int i = 0, z = getChildCount(); i < z; i++) {
+            getViewOffsetHelper(getChildAt(i)).onViewLayout();
+        }
+
         // Finally, set our minimum height to enable proper AppBarLayout collapsing
         if (mToolbar != null) {
             if (mCollapsingTitleEnabled && TextUtils.isEmpty(mCollapsingTextHelper.getText())) {
@@ -490,7 +499,7 @@
         return view.getHeight();
     }
 
-    private static ViewOffsetHelper getViewOffsetHelper(View view) {
+    static ViewOffsetHelper getViewOffsetHelper(View view) {
         ViewOffsetHelper offsetHelper = (ViewOffsetHelper) view.getTag(R.id.view_offset_helper);
         if (offsetHelper == null) {
             offsetHelper = new ViewOffsetHelper(view);
@@ -609,7 +618,7 @@
         mScrimAnimator.start();
     }
 
-    private void setScrimAlpha(int alpha) {
+    void setScrimAlpha(int alpha) {
         if (alpha != mScrimAlpha) {
             final Drawable contentScrim = mContentScrim;
             if (contentScrim != null && mToolbar != null) {
@@ -1050,7 +1059,7 @@
      * Returns the amount of visible height in pixels used to define when to trigger a scrim
      * visibility change.
      *
-     * @see #setScrimTriggerOffset(int)
+     * @see #setScrimVisibleHeightTrigger(int)
      */
     public int getScrimVisibleHeightTrigger() {
         if (mScrimVisibleHeightTrigger >= 0) {
@@ -1115,6 +1124,7 @@
         private static final float DEFAULT_PARALLAX_MULTIPLIER = 0.5f;
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         @IntDef({
                 COLLAPSE_MODE_OFF,
                 COLLAPSE_MODE_PIN,
@@ -1241,6 +1251,9 @@
     }
 
     private class OffsetUpdateListener implements AppBarLayout.OnOffsetChangedListener {
+        OffsetUpdateListener() {
+        }
+
         @Override
         public void onOffsetChanged(AppBarLayout layout, int verticalOffset) {
             mCurrentOffset = verticalOffset;
diff --git a/design/src/android/support/design/widget/CoordinatorLayout.java b/design/src/android/support/design/widget/CoordinatorLayout.java
index 268dbe3..f916e5f 100644
--- a/design/src/android/support/design/widget/CoordinatorLayout.java
+++ b/design/src/android/support/design/widget/CoordinatorLayout.java
@@ -37,6 +37,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.VisibleForTesting;
 import android.support.design.R;
 import android.support.v4.content.ContextCompat;
@@ -71,6 +72,7 @@
 import java.util.List;
 import java.util.Map;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.design.widget.ViewUtils.objectEquals;
 
 /**
@@ -132,11 +134,12 @@
             new ThreadLocal<>();
 
 
-    private static final int EVENT_PRE_DRAW = 0;
-    private static final int EVENT_NESTED_SCROLL = 1;
-    private static final int EVENT_VIEW_REMOVED = 2;
+    static final int EVENT_PRE_DRAW = 0;
+    static final int EVENT_NESTED_SCROLL = 1;
+    static final int EVENT_VIEW_REMOVED = 2;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({EVENT_PRE_DRAW, EVENT_NESTED_SCROLL, EVENT_VIEW_REMOVED})
     public @interface DispatchChangeEvent {}
@@ -172,7 +175,7 @@
     private boolean mDrawStatusBarBackground;
     private Drawable mStatusBarBackground;
 
-    private OnHierarchyChangeListener mOnHierarchyChangeListener;
+    OnHierarchyChangeListener mOnHierarchyChangeListener;
     private android.support.v4.view.OnApplyWindowInsetsListener mApplyWindowInsetsListener;
 
     private final NestedScrollingParentHelper mNestedScrollingParentHelper =
@@ -1137,8 +1140,6 @@
         GravityCompat.apply(resolveGravity(lp.gravity), child.getMeasuredWidth(),
                 child.getMeasuredHeight(), parent, out, layoutDirection);
         child.layout(out.left, out.top, out.right, out.bottom);
-        ViewCompat.offsetLeftAndRight(child, lp.mInsetOffsetX);
-        ViewCompat.offsetTopAndBottom(child, lp.mInsetOffsetY);
     }
 
     /**
@@ -1255,7 +1256,7 @@
             }
 
             // Dodge inset edges if necessary
-            if (lp.dodgeInsetEdges != Gravity.NO_GRAVITY) {
+            if (lp.dodgeInsetEdges != Gravity.NO_GRAVITY && child.getVisibility() == View.VISIBLE) {
                 offsetChildByInset(child, inset, layoutDirection);
             }
 
@@ -1307,7 +1308,7 @@
         }
     }
 
-    private void offsetChildByInset(View child, Rect inset, int layoutDirection) {
+    private void offsetChildByInset(final View child, final Rect inset, final int layoutDirection) {
         final LayoutParams lp = (LayoutParams) child.getLayoutParams();
         final int absDodgeInsetEdges = GravityCompat.getAbsoluteGravity(lp.dodgeInsetEdges,
                 layoutDirection);
@@ -1316,11 +1317,19 @@
         final Rect rect = mTempRect3;
         if (behavior != null && behavior.getInsetDodgeRect(this, child, rect)) {
             // Make sure that it intersects the views bounds
-            rect.intersect(child.getLeft(), child.getTop(), child.getRight(), child.getBottom());
+            if (!rect.intersect(child.getLeft(), child.getTop(),
+                    child.getRight(), child.getBottom())) {
+                throw new IllegalArgumentException("Rect should intersect with child's bounds.");
+            }
         } else {
             rect.set(child.getLeft(), child.getTop(), child.getRight(), child.getBottom());
         }
 
+        if (rect.isEmpty()) {
+            // Rect is empty so there is nothing to dodge against, skip...
+            return;
+        }
+
         boolean offsetY = false;
         if ((absDodgeInsetEdges & Gravity.TOP) == Gravity.TOP) {
             int distance = rect.top - lp.topMargin - lp.mInsetOffsetY;
@@ -2423,8 +2432,8 @@
          * Called when a view is set to dodge view insets.
          *
          * <p>This method allows a behavior to update the rectangle that should be dodged.
-         * The rectangle should be in the parents coordinate system, and within the child's
-         * bounds.</p>
+         * The rectangle should be in the parent's coordinate system and within the child's
+         * bounds. If not, a {@link IllegalArgumentException} is thrown.</p>
          *
          * @param parent the CoordinatorLayout parent of the view this Behavior is
          *               associated with
@@ -2489,8 +2498,8 @@
          */
         public int dodgeInsetEdges = Gravity.NO_GRAVITY;
 
-        private int mInsetOffsetX;
-        private int mInsetOffsetY;
+        int mInsetOffsetX;
+        int mInsetOffsetY;
 
         View mAnchorView;
         View mAnchorDirectChild;
@@ -2838,6 +2847,9 @@
     }
 
     private class HierarchyChangeListener implements OnHierarchyChangeListener {
+        HierarchyChangeListener() {
+        }
+
         @Override
         public void onChildViewAdded(View parent, View child) {
             if (mOnHierarchyChangeListener != null) {
diff --git a/design/src/android/support/design/widget/FloatingActionButton.java b/design/src/android/support/design/widget/FloatingActionButton.java
index 6433aae..09269a7 100644
--- a/design/src/android/support/design/widget/FloatingActionButton.java
+++ b/design/src/android/support/design/widget/FloatingActionButton.java
@@ -30,6 +30,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.VisibleForTesting;
 import android.support.design.R;
 import android.support.design.widget.FloatingActionButtonImpl.InternalVisibilityChangedListener;
@@ -48,6 +49,8 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Floating action buttons are used for a special type of promoted action. They are distinguished
  * by a circled icon floating above the UI and have special motion behaviors related to morphing,
@@ -120,6 +123,7 @@
     private static final int AUTO_MINI_LARGEST_SCREEN_WIDTH = 470;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({SIZE_MINI, SIZE_NORMAL, SIZE_AUTO})
     public @interface Size {}
@@ -130,11 +134,11 @@
     private int mBorderWidth;
     private int mRippleColor;
     private int mSize;
-    private int mImagePadding;
+    int mImagePadding;
     private int mMaxImageSize;
 
-    private boolean mCompatPadding;
-    private final Rect mShadowPadding = new Rect();
+    boolean mCompatPadding;
+    final Rect mShadowPadding = new Rect();
     private final Rect mTouchArea = new Rect();
 
     private AppCompatImageHelper mImageHelper;
@@ -321,7 +325,7 @@
         show(listener, true);
     }
 
-    private void show(OnVisibilityChangedListener listener, boolean fromUser) {
+    void show(OnVisibilityChangedListener listener, boolean fromUser) {
         getImpl().show(wrapOnVisibilityChangedListener(listener), fromUser);
     }
 
@@ -343,7 +347,7 @@
         hide(listener, true);
     }
 
-    private void hide(@Nullable OnVisibilityChangedListener listener, boolean fromUser) {
+    void hide(@Nullable OnVisibilityChangedListener listener, boolean fromUser) {
         getImpl().hide(wrapOnVisibilityChangedListener(listener), fromUser);
     }
 
@@ -426,7 +430,7 @@
         };
     }
 
-    private int getSizeDimension() {
+    int getSizeDimension() {
         return getSizeDimension(mSize);
     }
 
@@ -802,6 +806,9 @@
     }
 
     private class ShadowDelegateImpl implements ShadowViewDelegate {
+        ShadowDelegateImpl() {
+        }
+
         @Override
         public float getRadius() {
             return getSizeDimension() / 2f;
diff --git a/design/src/android/support/design/widget/HeaderBehavior.java b/design/src/android/support/design/widget/HeaderBehavior.java
index 7dd2700..5e555de 100644
--- a/design/src/android/support/design/widget/HeaderBehavior.java
+++ b/design/src/android/support/design/widget/HeaderBehavior.java
@@ -37,7 +37,7 @@
     private static final int INVALID_POINTER = -1;
 
     private Runnable mFlingRunnable;
-    private ScrollerCompat mScroller;
+    ScrollerCompat mScroller;
 
     private boolean mIsBeingDragged;
     private int mActivePointerId = INVALID_POINTER;
diff --git a/design/src/android/support/design/widget/NavigationView.java b/design/src/android/support/design/widget/NavigationView.java
index 7d78ffb..8e5d31c 100644
--- a/design/src/android/support/design/widget/NavigationView.java
+++ b/design/src/android/support/design/widget/NavigationView.java
@@ -27,6 +27,7 @@
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.design.R;
 import android.support.design.internal.NavigationMenu;
@@ -50,6 +51,8 @@
 import android.view.MenuItem;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Represents a standard navigation menu for application. The menu contents can be populated
  * by a menu resource file.
@@ -84,7 +87,7 @@
     private final NavigationMenu mMenu;
     private final NavigationMenuPresenter mPresenter = new NavigationMenuPresenter();
 
-    private OnNavigationItemSelectedListener mListener;
+    OnNavigationItemSelectedListener mListener;
     private int mMaxWidth;
 
     private MenuInflater mMenuInflater;
@@ -229,6 +232,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     protected void onInsetsChanged(WindowInsetsCompat insets) {
         mPresenter.dispatchApplyWindowInsets(insets);
diff --git a/design/src/android/support/design/widget/Snackbar.java b/design/src/android/support/design/widget/Snackbar.java
index bc5df7f..782cc4f 100644
--- a/design/src/android/support/design/widget/Snackbar.java
+++ b/design/src/android/support/design/widget/Snackbar.java
@@ -27,6 +27,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.IntRange;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringRes;
 import android.support.design.R;
 import android.support.v4.view.OnApplyWindowInsetsListener;
@@ -52,6 +53,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.design.widget.AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR;
 
 /**
@@ -89,6 +91,7 @@
         public static final int DISMISS_EVENT_CONSECUTIVE = 4;
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         @IntDef({DISMISS_EVENT_SWIPE, DISMISS_EVENT_ACTION, DISMISS_EVENT_TIMEOUT,
                 DISMISS_EVENT_MANUAL, DISMISS_EVENT_CONSECUTIVE})
         @Retention(RetentionPolicy.SOURCE)
@@ -124,6 +127,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef({LENGTH_INDEFINITE, LENGTH_SHORT, LENGTH_LONG})
     @IntRange(from = 1)
     @Retention(RetentionPolicy.SOURCE)
@@ -154,9 +158,9 @@
     static final int ANIMATION_DURATION = 250;
     static final int ANIMATION_FADE_DURATION = 180;
 
-    private static final Handler sHandler;
-    private static final int MSG_SHOW = 0;
-    private static final int MSG_DISMISS = 1;
+    static final Handler sHandler;
+    static final int MSG_SHOW = 0;
+    static final int MSG_DISMISS = 1;
 
     static {
         sHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@@ -177,7 +181,7 @@
 
     private final ViewGroup mTargetParent;
     private final Context mContext;
-    private final SnackbarLayout mView;
+    final SnackbarLayout mView;
     private int mDuration;
     private Callback mCallback;
 
@@ -401,7 +405,7 @@
         dispatchDismiss(Callback.DISMISS_EVENT_MANUAL);
     }
 
-    private void dispatchDismiss(@Callback.DismissEvent int event) {
+    void dispatchDismiss(@Callback.DismissEvent int event) {
         SnackbarManager.getInstance().dismiss(mManagerCallback, event);
     }
 
@@ -429,7 +433,7 @@
         return SnackbarManager.getInstance().isCurrentOrNext(mManagerCallback);
     }
 
-    private final SnackbarManager.Callback mManagerCallback = new SnackbarManager.Callback() {
+    final SnackbarManager.Callback mManagerCallback = new SnackbarManager.Callback() {
         @Override
         public void show() {
             sHandler.sendMessage(sHandler.obtainMessage(MSG_SHOW, Snackbar.this));
@@ -531,7 +535,7 @@
         }
     }
 
-    private void animateViewIn() {
+    void animateViewIn() {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
             ViewCompat.setTranslationY(mView, mView.getHeight());
             ViewCompat.animate(mView)
@@ -618,14 +622,14 @@
         }
     }
 
-    private void onViewShown() {
+    void onViewShown() {
         SnackbarManager.getInstance().onShown(mManagerCallback);
         if (mCallback != null) {
             mCallback.onShown(this);
         }
     }
 
-    private void onViewHidden(int event) {
+    void onViewHidden(int event) {
         // First tell the SnackbarManager that it has been dismissed
         SnackbarManager.getInstance().onDismissed(mManagerCallback);
         // Now call the dismiss listener (if available)
@@ -650,13 +654,14 @@
     /**
      * Returns true if we should animate the Snackbar view in/out.
      */
-    private boolean shouldAnimate() {
+    boolean shouldAnimate() {
         return !mAccessibilityManager.isEnabled();
     }
 
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class SnackbarLayout extends LinearLayout {
         private TextView mMessageView;
         private Button mActionView;
diff --git a/design/src/android/support/design/widget/SnackbarManager.java b/design/src/android/support/design/widget/SnackbarManager.java
index e0c3922..b391a3a 100644
--- a/design/src/android/support/design/widget/SnackbarManager.java
+++ b/design/src/android/support/design/widget/SnackbarManager.java
@@ -27,7 +27,7 @@
  */
 class SnackbarManager {
 
-    private static final int MSG_TIMEOUT = 0;
+    static final int MSG_TIMEOUT = 0;
 
     private static final int SHORT_DURATION_MS = 1500;
     private static final int LONG_DURATION_MS = 2750;
@@ -166,8 +166,8 @@
     }
 
     private static class SnackbarRecord {
-        private final WeakReference<Callback> callback;
-        private int duration;
+        final WeakReference<Callback> callback;
+        int duration;
 
         SnackbarRecord(int duration, Callback callback) {
             this.callback = new WeakReference<>(callback);
@@ -229,7 +229,7 @@
         mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_TIMEOUT, r), durationMs);
     }
 
-    private void handleTimeout(SnackbarRecord record) {
+    void handleTimeout(SnackbarRecord record) {
         synchronized (mLock) {
             if (mCurrentSnackbar == record || mNextSnackbar == record) {
                 cancelSnackbarLocked(record, Snackbar.Callback.DISMISS_EVENT_TIMEOUT);
diff --git a/design/src/android/support/design/widget/SwipeDismissBehavior.java b/design/src/android/support/design/widget/SwipeDismissBehavior.java
index ae1ef86..2d1cebe 100644
--- a/design/src/android/support/design/widget/SwipeDismissBehavior.java
+++ b/design/src/android/support/design/widget/SwipeDismissBehavior.java
@@ -18,6 +18,7 @@
 
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.MotionEventCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.widget.ViewDragHelper;
@@ -29,6 +30,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * An interaction behavior plugin for child views of {@link CoordinatorLayout} to provide support
  * for the 'swipe-to-dismiss' gesture.
@@ -53,6 +56,7 @@
     public static final int STATE_SETTLING = ViewDragHelper.STATE_SETTLING;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({SWIPE_DIRECTION_START_TO_END, SWIPE_DIRECTION_END_TO_START, SWIPE_DIRECTION_ANY})
     @Retention(RetentionPolicy.SOURCE)
     private @interface SwipeDirection {}
@@ -78,17 +82,17 @@
     private static final float DEFAULT_ALPHA_START_DISTANCE = 0f;
     private static final float DEFAULT_ALPHA_END_DISTANCE = DEFAULT_DRAG_DISMISS_THRESHOLD;
 
-    private ViewDragHelper mViewDragHelper;
-    private OnDismissListener mListener;
+    ViewDragHelper mViewDragHelper;
+    OnDismissListener mListener;
     private boolean mInterceptingEvents;
 
     private float mSensitivity = 0f;
     private boolean mSensitivitySet;
 
-    private int mSwipeDirection = SWIPE_DIRECTION_ANY;
-    private float mDragDismissThreshold = DEFAULT_DRAG_DISMISS_THRESHOLD;
-    private float mAlphaStartSwipeDistance = DEFAULT_ALPHA_START_DISTANCE;
-    private float mAlphaEndSwipeDistance = DEFAULT_ALPHA_END_DISTANCE;
+    int mSwipeDirection = SWIPE_DIRECTION_ANY;
+    float mDragDismissThreshold = DEFAULT_DRAG_DISMISS_THRESHOLD;
+    float mAlphaStartSwipeDistance = DEFAULT_ALPHA_START_DISTANCE;
+    float mAlphaEndSwipeDistance = DEFAULT_ALPHA_END_DISTANCE;
 
     /**
      * Callback interface used to notify the application that the view has been dismissed.
@@ -381,11 +385,11 @@
         }
     }
 
-    private static float clamp(float min, float value, float max) {
+    static float clamp(float min, float value, float max) {
         return Math.min(Math.max(min, value), max);
     }
 
-    private static int clamp(int min, int value, int max) {
+    static int clamp(int min, int value, int max) {
         return Math.min(Math.max(min, value), max);
     }
 
diff --git a/design/src/android/support/design/widget/TabLayout.java b/design/src/android/support/design/widget/TabLayout.java
index 63d9418..bc52ab7 100755
--- a/design/src/android/support/design/widget/TabLayout.java
+++ b/design/src/android/support/design/widget/TabLayout.java
@@ -16,6 +16,7 @@
 
 package android.support.design.widget;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v4.view.ViewPager.SCROLL_STATE_DRAGGING;
 import static android.support.v4.view.ViewPager.SCROLL_STATE_IDLE;
 import static android.support.v4.view.ViewPager.SCROLL_STATE_SETTLING;
@@ -37,6 +38,7 @@
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringRes;
 import android.support.design.R;
 import android.support.v4.util.Pools;
@@ -145,12 +147,12 @@
 public class TabLayout extends HorizontalScrollView {
 
     private static final int DEFAULT_HEIGHT_WITH_TEXT_ICON = 72; // dps
-    private static final int DEFAULT_GAP_TEXT_ICON = 8; // dps
+    static final int DEFAULT_GAP_TEXT_ICON = 8; // dps
     private static final int INVALID_WIDTH = -1;
     private static final int DEFAULT_HEIGHT = 48; // dps
     private static final int TAB_MIN_WIDTH_MARGIN = 56; //dps
-    private static final int FIXED_WRAP_GUTTER_MIN = 16; //dps
-    private static final int MOTION_NON_ADJACENT_OFFSET = 24;
+    static final int FIXED_WRAP_GUTTER_MIN = 16; //dps
+    static final int MOTION_NON_ADJACENT_OFFSET = 24;
 
     private static final int ANIMATION_DURATION = 300;
 
@@ -179,6 +181,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef(value = {MODE_SCROLLABLE, MODE_FIXED})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Mode {}
@@ -203,6 +206,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef(flag = true, value = {GRAVITY_FILL, GRAVITY_CENTER})
     @Retention(RetentionPolicy.SOURCE)
     public @interface TabGravity {}
@@ -240,27 +244,27 @@
 
     private final SlidingTabStrip mTabStrip;
 
-    private int mTabPaddingStart;
-    private int mTabPaddingTop;
-    private int mTabPaddingEnd;
-    private int mTabPaddingBottom;
+    int mTabPaddingStart;
+    int mTabPaddingTop;
+    int mTabPaddingEnd;
+    int mTabPaddingBottom;
 
-    private int mTabTextAppearance;
-    private ColorStateList mTabTextColors;
-    private float mTabTextSize;
-    private float mTabTextMultiLineSize;
+    int mTabTextAppearance;
+    ColorStateList mTabTextColors;
+    float mTabTextSize;
+    float mTabTextMultiLineSize;
 
-    private final int mTabBackgroundResId;
+    final int mTabBackgroundResId;
 
-    private int mTabMaxWidth = Integer.MAX_VALUE;
+    int mTabMaxWidth = Integer.MAX_VALUE;
     private final int mRequestedTabMinWidth;
     private final int mRequestedTabMaxWidth;
     private final int mScrollableTabMinWidth;
 
     private int mContentInsetStart;
 
-    private int mTabGravity;
-    private int mMode;
+    int mTabGravity;
+    int mMode;
 
     private OnTabSelectedListener mSelectedListener;
     private final ArrayList<OnTabSelectedListener> mSelectedListeners = new ArrayList<>();
@@ -268,7 +272,7 @@
 
     private ValueAnimatorCompat mScrollAnimator;
 
-    private ViewPager mViewPager;
+    ViewPager mViewPager;
     private PagerAdapter mPagerAdapter;
     private DataSetObserver mPagerAdapterObserver;
     private TabLayoutOnPageChangeListener mPageChangeListener;
@@ -400,7 +404,7 @@
         setScrollPosition(position, positionOffset, updateSelectedText, true);
     }
 
-    private void setScrollPosition(int position, float positionOffset, boolean updateSelectedText,
+    void setScrollPosition(int position, float positionOffset, boolean updateSelectedText,
             boolean updateIndicatorPosition) {
         final int roundedPosition = Math.round(position + positionOffset);
         if (roundedPosition < 0 || roundedPosition >= mTabStrip.getChildCount()) {
@@ -875,7 +879,7 @@
                 - getPaddingRight());
     }
 
-    private void setPagerAdapter(@Nullable final PagerAdapter adapter, final boolean addObserver) {
+    void setPagerAdapter(@Nullable final PagerAdapter adapter, final boolean addObserver) {
         if (mPagerAdapter != null && mPagerAdapterObserver != null) {
             // If we already have a PagerAdapter, unregister our observer
             mPagerAdapter.unregisterDataSetObserver(mPagerAdapterObserver);
@@ -895,7 +899,7 @@
         populateFromPagerAdapter();
     }
 
-    private void populateFromPagerAdapter() {
+    void populateFromPagerAdapter() {
         removeAllTabs();
 
         if (mPagerAdapter != null) {
@@ -991,7 +995,7 @@
         }
     }
 
-    private int dpToPx(int dps) {
+    int dpToPx(int dps) {
         return Math.round(getResources().getDisplayMetrics().density * dps);
     }
 
@@ -1200,7 +1204,7 @@
         updateTabViews(true);
     }
 
-    private void updateTabViews(final boolean requestLayout) {
+    void updateTabViews(final boolean requestLayout) {
         for (int i = 0; i < mTabStrip.getChildCount(); i++) {
             View child = mTabStrip.getChildAt(i);
             child.setMinimumWidth(getTabMinWidth());
@@ -1230,10 +1234,10 @@
         private int mPosition = INVALID_POSITION;
         private View mCustomView;
 
-        private TabLayout mParent;
-        private TabView mView;
+        TabLayout mParent;
+        TabView mView;
 
-        private Tab() {
+        Tab() {
             // Private constructor
         }
 
@@ -1463,13 +1467,13 @@
             return mContentDesc;
         }
 
-        private void updateView() {
+        void updateView() {
             if (mView != null) {
                 mView.update();
             }
         }
 
-        private void reset() {
+        void reset() {
             mParent = null;
             mView = null;
             mTag = null;
@@ -1626,14 +1630,14 @@
             }
         }
 
-        private void setTab(@Nullable final Tab tab) {
+        void setTab(@Nullable final Tab tab) {
             if (tab != mTab) {
                 mTab = tab;
                 update();
             }
         }
 
-        private void reset() {
+        void reset() {
             setTab(null);
             setSelected(false);
         }
@@ -1803,8 +1807,8 @@
         private int mSelectedIndicatorHeight;
         private final Paint mSelectedIndicatorPaint;
 
-        private int mSelectedPosition = -1;
-        private float mSelectionOffset;
+        int mSelectedPosition = -1;
+        float mSelectionOffset;
 
         private int mIndicatorLeft = -1;
         private int mIndicatorRight = -1;
@@ -1952,7 +1956,7 @@
             setIndicatorPosition(left, right);
         }
 
-        private void setIndicatorPosition(int left, int right) {
+        void setIndicatorPosition(int left, int right) {
             if (left != mIndicatorLeft || right != mIndicatorRight) {
                 // If the indicator's left/right has changed, invalidate
                 mIndicatorLeft = left;
@@ -2089,7 +2093,7 @@
         return generateDefaultLayoutParams();
     }
 
-    private int getTabMaxWidth() {
+    int getTabMaxWidth() {
         return mTabMaxWidth;
     }
 
@@ -2150,7 +2154,7 @@
             }
         }
 
-        private void reset() {
+        void reset() {
             mPreviousScrollState = mScrollState = SCROLL_STATE_IDLE;
         }
     }
@@ -2183,6 +2187,9 @@
     }
 
     private class PagerAdapterObserver extends DataSetObserver {
+        PagerAdapterObserver() {
+        }
+
         @Override
         public void onChanged() {
             populateFromPagerAdapter();
@@ -2197,6 +2204,9 @@
     private class AdapterChangeListener implements ViewPager.OnAdapterChangeListener {
         private boolean mAutoRefresh;
 
+        AdapterChangeListener() {
+        }
+
         @Override
         public void onAdapterChanged(@NonNull ViewPager viewPager,
                 @Nullable PagerAdapter oldAdapter, @Nullable PagerAdapter newAdapter) {
diff --git a/design/src/android/support/design/widget/TextInputLayout.java b/design/src/android/support/design/widget/TextInputLayout.java
index 19f704f..2bbaace 100644
--- a/design/src/android/support/design/widget/TextInputLayout.java
+++ b/design/src/android/support/design/widget/TextInputLayout.java
@@ -102,7 +102,7 @@
     private static final String LOG_TAG = "TextInputLayout";
 
     private final FrameLayout mInputFrame;
-    private EditText mEditText;
+    EditText mEditText;
 
     private boolean mHintEnabled;
     private CharSequence mHint;
@@ -114,12 +114,12 @@
     private int mIndicatorsAdded;
 
     private boolean mErrorEnabled;
-    private TextView mErrorView;
+    TextView mErrorView;
     private int mErrorTextAppearance;
     private boolean mErrorShown;
     private CharSequence mError;
 
-    private boolean mCounterEnabled;
+    boolean mCounterEnabled;
     private TextView mCounterView;
     private int mCounterMaxLength;
     private int mCounterTextAppearance;
@@ -132,6 +132,7 @@
     private CheckableImageButton mPasswordToggleView;
     private boolean mPasswordToggledVisible;
     private Drawable mPasswordToggleDummyDrawable;
+    private Drawable mOriginalEditTextEndDrawable;
 
     private ColorStateList mPasswordToggleTintList;
     private boolean mHasPasswordToggleTintList;
@@ -144,7 +145,7 @@
     // Only used for testing
     private boolean mHintExpanded;
 
-    private final CollapsingTextHelper mCollapsingTextHelper = new CollapsingTextHelper(this);
+    final CollapsingTextHelper mCollapsingTextHelper = new CollapsingTextHelper(this);
 
     private boolean mHintAnimationEnabled;
     private ValueAnimatorCompat mAnimator;
@@ -371,7 +372,7 @@
         }
     }
 
-    private void updateLabelState(boolean animate) {
+    void updateLabelState(boolean animate) {
         final boolean isEnabled = isEnabled();
         final boolean hasText = mEditText != null && !TextUtils.isEmpty(mEditText.getText());
         final boolean isFocused = arrayContains(getDrawableState(), android.R.attr.state_focused);
@@ -782,7 +783,7 @@
         return mCounterMaxLength;
     }
 
-    private void updateCounter(int length) {
+    void updateCounter(int length) {
         boolean wasCounterOverflowed = mCounterOverflowed;
         if (mCounterMaxLength == INVALID_MAX_LENGTH) {
             mCounterView.setText(String.valueOf(length));
@@ -987,6 +988,11 @@
     }
 
     private void updatePasswordToggleView() {
+        if (mEditText == null) {
+            // If there is no EditText, there is nothing to update
+            return;
+        }
+
         if (shouldShowPasswordIcon()) {
             if (mPasswordToggleView == null) {
                 mPasswordToggleView = (CheckableImageButton) LayoutInflater.from(getContext())
@@ -1013,8 +1019,12 @@
             mPasswordToggleDummyDrawable.setBounds(0, 0, mPasswordToggleView.getMeasuredWidth(), 1);
 
             final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(mEditText);
+            // Store the user defined end compound drawable so that we can restore it later
+            if (compounds[2] != mPasswordToggleDummyDrawable) {
+                mOriginalEditTextEndDrawable = compounds[2];
+            }
             TextViewCompat.setCompoundDrawablesRelative(mEditText, compounds[0], compounds[1],
-                    mPasswordToggleDummyDrawable, compounds[2]);
+                    mPasswordToggleDummyDrawable, compounds[3]);
 
             // Copy over the EditText's padding so that we match
             mPasswordToggleView.setPadding(mEditText.getPaddingLeft(),
@@ -1027,8 +1037,10 @@
 
             // Make sure that we remove the dummy end compound drawable
             final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(mEditText);
-            TextViewCompat.setCompoundDrawablesRelative(mEditText, compounds[0], compounds[1],
-                    null, compounds[2]);
+            if (compounds[2] == mPasswordToggleDummyDrawable) {
+                TextViewCompat.setCompoundDrawablesRelative(mEditText, compounds[0], compounds[1],
+                        mOriginalEditTextEndDrawable, compounds[3]);
+            }
         }
     }
 
@@ -1147,7 +1159,7 @@
         if (mPasswordToggleEnabled != enabled) {
             mPasswordToggleEnabled = enabled;
 
-            if (!enabled && mPasswordToggledVisible) {
+            if (!enabled && mPasswordToggledVisible && mEditText != null) {
                 // If the toggle is no longer enabled, but we remove the PasswordTransformation
                 // to make the password visible, add it back
                 mEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
@@ -1193,7 +1205,7 @@
         applyPasswordToggleTint();
     }
 
-   private void passwordVisibilityToggleRequested() {
+   void passwordVisibilityToggleRequested() {
        if (mPasswordToggleEnabled) {
            // Store the current cursor position
            final int selection = mEditText.getSelectionEnd();
@@ -1346,6 +1358,9 @@
     }
 
     private class TextInputAccessibilityDelegate extends AccessibilityDelegateCompat {
+        TextInputAccessibilityDelegate() {
+        }
+
         @Override
         public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
             super.onInitializeAccessibilityEvent(host, event);
diff --git a/design/src/android/support/design/widget/ViewGroupUtils.java b/design/src/android/support/design/widget/ViewGroupUtils.java
index a5d2f8a..bb5e1b6 100644
--- a/design/src/android/support/design/widget/ViewGroupUtils.java
+++ b/design/src/android/support/design/widget/ViewGroupUtils.java
@@ -28,6 +28,9 @@
     }
 
     private static class ViewGroupUtilsImplBase implements ViewGroupUtilsImpl {
+        ViewGroupUtilsImplBase() {
+        }
+
         @Override
         public void offsetDescendantRect(ViewGroup parent, View child, Rect rect) {
             parent.offsetDescendantRectToMyCoords(child, rect);
@@ -39,6 +42,9 @@
     }
 
     private static class ViewGroupUtilsImplHoneycomb implements ViewGroupUtilsImpl {
+        ViewGroupUtilsImplHoneycomb() {
+        }
+
         @Override
         public void offsetDescendantRect(ViewGroup parent, View child, Rect rect) {
             ViewGroupUtilsHoneycomb.offsetDescendantRect(parent, child, rect);
diff --git a/design/tests/res/layout/design_text_input.xml b/design/tests/res/layout/design_text_input.xml
index d7f21a8..f4bd1d1 100644
--- a/design/tests/res/layout/design_text_input.xml
+++ b/design/tests/res/layout/design_text_input.xml
@@ -53,4 +53,9 @@
 
     </android.support.design.widget.TextInputLayout>
 
+    <android.support.design.widget.TextInputLayout
+        android:id="@+id/textinput_noedittext"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"/>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/design/tests/src/android/support/design/testutils/TestUtilsActions.java b/design/tests/src/android/support/design/testutils/TestUtilsActions.java
index f94c253..dcac0ed 100644
--- a/design/tests/src/android/support/design/testutils/TestUtilsActions.java
+++ b/design/tests/src/android/support/design/testutils/TestUtilsActions.java
@@ -16,6 +16,7 @@
 
 package android.support.design.testutils;
 
+import android.graphics.drawable.Drawable;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.Nullable;
 import android.support.annotation.StringRes;
@@ -25,6 +26,7 @@
 import android.support.test.espresso.ViewAction;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.ViewPager;
+import android.support.v4.widget.TextViewCompat;
 import android.support.v7.widget.Toolbar;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -234,4 +236,33 @@
             }
         };
     }
+
+    /**
+     * Sets compound drawables on {@link TextView}
+     */
+    public static ViewAction setCompoundDrawablesRelative(final @Nullable Drawable start,
+            final @Nullable Drawable top, final @Nullable Drawable end,
+            final @Nullable Drawable bottom) {
+        return new ViewAction() {
+            @Override
+            public Matcher<View> getConstraints() {
+                return isAssignableFrom(TextView.class);
+            }
+
+            @Override
+            public String getDescription() {
+                return "TextView set compound drawables relative";
+            }
+
+            @Override
+            public void perform(UiController uiController, View view) {
+                uiController.loopMainThreadUntilIdle();
+
+                TextView textView = (TextView) view;
+                TextViewCompat.setCompoundDrawablesRelative(textView, start, top, end, bottom);
+
+                uiController.loopMainThreadUntilIdle();
+            }
+        };
+    }
 }
diff --git a/design/tests/src/android/support/design/testutils/TestUtilsMatchers.java b/design/tests/src/android/support/design/testutils/TestUtilsMatchers.java
index b4830e5..2d95aa0 100644
--- a/design/tests/src/android/support/design/testutils/TestUtilsMatchers.java
+++ b/design/tests/src/android/support/design/testutils/TestUtilsMatchers.java
@@ -26,6 +26,7 @@
 import android.support.test.espresso.matcher.BoundedMatcher;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
+import android.support.v4.widget.TextViewCompat;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -415,4 +416,28 @@
             }
         };
     }
+
+    /**
+     * Returns a matcher that matches FloatingActionButtons with the specified content height
+     */
+    public static Matcher withCompoundDrawable(final int index, final Drawable expected) {
+        return new BoundedMatcher<View, View>(View.class) {
+            private String failedCheckDescription;
+
+            @Override
+            public void describeTo(final Description description) {
+                description.appendText(failedCheckDescription);
+            }
+
+            @Override
+            public boolean matchesSafely(final View view) {
+                if (!(view instanceof TextView)) {
+                    return false;
+                }
+
+                final TextView textView = (TextView) view;
+                return expected == TextViewCompat.getCompoundDrawablesRelative(textView)[index];
+            }
+        };
+    }
 }
diff --git a/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java b/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
index 4199fa9..d04a510 100644
--- a/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
+++ b/design/tests/src/android/support/design/widget/AppBarWithCollapsingToolbarTest.java
@@ -308,6 +308,13 @@
         final ImageView parallaxImageView =
                 (ImageView) mCoordinatorLayout.findViewById(R.id.app_bar_image);
 
+        // We have not set any padding on the ImageView, so ensure that none is set via
+        // window insets handling
+        assertEquals(0, parallaxImageView.getPaddingLeft());
+        assertEquals(0, parallaxImageView.getPaddingTop());
+        assertEquals(0, parallaxImageView.getPaddingRight());
+        assertEquals(0, parallaxImageView.getPaddingBottom());
+
         CollapsingToolbarLayout.LayoutParams parallaxImageViewLp =
                 (CollapsingToolbarLayout.LayoutParams) parallaxImageView.getLayoutParams();
         assertEquals(CollapsingToolbarLayout.LayoutParams.COLLAPSE_MODE_PARALLAX,
diff --git a/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java b/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
index f1fca21..98851b4 100644
--- a/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
+++ b/design/tests/src/android/support/design/widget/BottomNavigationViewTest.java
@@ -21,6 +21,7 @@
 import static android.support.test.espresso.action.ViewActions.click;
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
 import static android.support.test.espresso.matcher.ViewMatchers.isDescendantOfA;
+import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
 
@@ -96,7 +97,7 @@
 
         // Click one of our items
         onView(allOf(withText(mMenuStringContent.get(R.id.destination_profile)),
-                isDescendantOfA(withId(R.id.bottom_navigation)))).perform(click());
+                isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click());
         // And that our listener has been notified of the click
         verify(mockedListener, times(1)).onNavigationItemSelected(
                 mBottomNavigation.getMenu().findItem(R.id.destination_profile));
@@ -107,7 +108,7 @@
 
         // Click one of our items
         onView(allOf(withText(mMenuStringContent.get(R.id.destination_people)),
-                isDescendantOfA(withId(R.id.bottom_navigation)))).perform(click());
+                isDescendantOfA(withId(R.id.bottom_navigation)), isDisplayed())).perform(click());
         // And that our previous listener has not been notified of the click
         verifyNoMoreInteractions(mockedListener);
     }
diff --git a/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java b/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
index 4c6804f..1b79fb3 100644
--- a/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
+++ b/design/tests/src/android/support/design/widget/BottomSheetBehaviorTest.java
@@ -20,6 +20,8 @@
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.lessThanOrEqualTo;
 
 import android.os.SystemClock;
 import android.support.annotation.LayoutRes;
@@ -55,6 +57,7 @@
 import android.widget.TextView;
 
 import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
 import org.junit.Test;
 
 public class BottomSheetBehaviorTest extends
@@ -85,6 +88,8 @@
 
         @Override
         public void onSlide(@NonNull View bottomSheet, float slideOffset) {
+            assertThat(slideOffset, is(greaterThanOrEqualTo(-1f)));
+            assertThat(slideOffset, is(lessThanOrEqualTo(1f)));
         }
 
         @Override
@@ -183,7 +188,7 @@
 
         @Override
         public Matcher<View> getConstraints() {
-            return ViewMatchers.isDisplayed();
+            return Matchers.any(View.class);
         }
 
         @Override
@@ -213,7 +218,6 @@
                         MotionEvents.sendCancel(uiController, downEvent);
                         throw new RuntimeException("Cannot drag: failed to send a move event.");
                     }
-                    BottomSheetBehavior behavior = BottomSheetBehavior.from(view);
                 }
                 int duration = ViewConfiguration.getPressedStateDuration();
                 if (duration > 0) {
@@ -332,7 +336,6 @@
                                         view.getHeight() - behavior.getPeekHeight()};
                             }
                         }, Press.FINGER), ViewMatchers.isDisplayingAtLeast(5)));
-        // Avoid a deadlock (b/26160710)
         registerIdlingResourceCallback();
         try {
             Espresso.onView(ViewMatchers.withId(R.id.bottom_sheet))
@@ -349,7 +352,6 @@
         Espresso.onView(ViewMatchers.withId(R.id.bottom_sheet))
                 .perform(DesignViewActions.withCustomConstraints(ViewActions.swipeDown(),
                         ViewMatchers.isDisplayingAtLeast(5)));
-        // Avoid a deadlock (b/26160710)
         registerIdlingResourceCallback();
         try {
             Espresso.onView(ViewMatchers.withId(R.id.bottom_sheet))
@@ -416,7 +418,6 @@
                             }
                         }, Press.FINGER),
                         ViewMatchers.isDisplayingAtLeast(5)));
-        // Avoid a deadlock (b/26160710)
         registerIdlingResourceCallback();
         try {
             Espresso.onView(ViewMatchers.withId(R.id.bottom_sheet))
@@ -460,6 +461,46 @@
 
     @Test
     @MediumTest
+    public void testInvisibleThenVisible() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // The bottom sheet is initially invisible
+                getBottomSheet().setVisibility(View.INVISIBLE);
+                // Then it becomes visible when the CoL is touched
+                getCoordinatorLayout().setOnTouchListener(new View.OnTouchListener() {
+                    @Override
+                    public boolean onTouch(View view, MotionEvent e) {
+                        if (e.getAction() == MotionEvent.ACTION_DOWN) {
+                            getBottomSheet().setVisibility(View.VISIBLE);
+                            return true;
+                        }
+                        return false;
+                    }
+                });
+                assertThat(getBehavior().getState(), is(BottomSheetBehavior.STATE_COLLAPSED));
+            }
+        });
+        // Drag over the CoL
+        Espresso.onView(ViewMatchers.withId(R.id.coordinator))
+                // Drag (and not release)
+                .perform(new DragAction(
+                        GeneralLocation.BOTTOM_CENTER,
+                        GeneralLocation.TOP_CENTER,
+                        Press.FINGER))
+                .check(new ViewAssertion() {
+                    @Override
+                    public void check(View view, NoMatchingViewException e) {
+                        // The bottom sheet should not react to the touch events
+                        assertThat(getBottomSheet(), is(ViewMatchers.isDisplayed()));
+                        assertThat(getBehavior().getState(),
+                                is(BottomSheetBehavior.STATE_COLLAPSED));
+                    }
+                });
+    }
+
+    @Test
+    @MediumTest
     public void testNestedScroll() {
         final ViewGroup bottomSheet = getBottomSheet();
         final BottomSheetBehavior behavior = getBehavior();
@@ -547,7 +588,6 @@
                                     }
                                 }, Press.FINGER),
                         ViewMatchers.isDisplayed()));
-        // Avoid a deadlock (b/26160710)
         registerIdlingResourceCallback();
         try {
             Espresso.onView(ViewMatchers.withId(R.id.bottom_sheet))
@@ -627,6 +667,20 @@
     }
 
     @Test
+    @MediumTest
+    public void testAutoPeekHeightHide() {
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                getBehavior().setHideable(true);
+                getBehavior().setPeekHeight(0);
+                getBehavior().setPeekHeight(BottomSheetBehavior.PEEK_HEIGHT_AUTO);
+            }
+        });
+        checkSetState(BottomSheetBehavior.STATE_HIDDEN, not(ViewMatchers.isDisplayed()));
+    }
+
+    @Test
     public void testDynamicContent() {
         registerIdlingResourceCallback();
         try {
@@ -676,7 +730,7 @@
     }
 
     private void registerIdlingResourceCallback() {
-        // TODO(yaraki): Move this to setUp() when b/26160710 is fixed
+        // This cannot be done in setUp(), or swiping action cannot be executed.
         mCallback = new Callback(getBehavior());
         Espresso.registerIdlingResources(mCallback);
     }
diff --git a/design/tests/src/android/support/design/widget/TextInputLayoutTest.java b/design/tests/src/android/support/design/widget/TextInputLayoutTest.java
index 840e8d5..fce619e 100755
--- a/design/tests/src/android/support/design/widget/TextInputLayoutTest.java
+++ b/design/tests/src/android/support/design/widget/TextInputLayoutTest.java
@@ -16,7 +16,9 @@
 
 package android.support.design.widget;
 
+import static android.support.design.testutils.TestUtilsActions.setCompoundDrawablesRelative;
 import static android.support.design.testutils.TestUtilsActions.setEnabled;
+import static android.support.design.testutils.TestUtilsMatchers.withCompoundDrawable;
 import static android.support.design.testutils.TextInputLayoutActions.setError;
 import static android.support.design.testutils.TextInputLayoutActions.setErrorEnabled;
 import static android.support.design.testutils.TextInputLayoutActions
@@ -37,6 +39,9 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.support.design.test.R;
 import android.support.test.espresso.NoMatchingViewException;
 import android.support.test.espresso.ViewAssertion;
@@ -156,6 +161,37 @@
     }
 
     @Test
+    public void testPasswordToggleMaintainsCompoundDrawables() {
+        // Set a known set of test compound drawables on the EditText
+        final Drawable start = new ColorDrawable(Color.RED);
+        final Drawable top = new ColorDrawable(Color.GREEN);
+        final Drawable end = new ColorDrawable(Color.BLUE);
+        final Drawable bottom = new ColorDrawable(Color.BLACK);
+        onView(withId(R.id.textinput_edittext_pwd))
+                .perform(setCompoundDrawablesRelative(start, top, end, bottom));
+
+        // Enable the password toggle and check that the start, top and bottom drawables are
+        // maintained
+        onView(withId(R.id.textinput_password))
+                .perform(setPasswordVisibilityToggleEnabled(true));
+        onView(withId(R.id.textinput_edittext_pwd))
+                .check(matches(withCompoundDrawable(0, start)))
+                .check(matches(withCompoundDrawable(1, top)))
+                .check(matches(not(withCompoundDrawable(2, end))))
+                .check(matches(withCompoundDrawable(3, bottom)));
+
+        // Now disable the password toggle and check that all of the original compound drawables
+        // are set
+        onView(withId(R.id.textinput_password))
+                .perform(setPasswordVisibilityToggleEnabled(false));
+        onView(withId(R.id.textinput_edittext_pwd))
+                .check(matches(withCompoundDrawable(0, start)))
+                .check(matches(withCompoundDrawable(1, top)))
+                .check(matches(withCompoundDrawable(2, end)))
+                .check(matches(withCompoundDrawable(3, bottom)));
+    }
+
+    @Test
     public void testSetEnabledFalse() {
         // First click on the EditText, so that it is focused and the hint collapses...
         onView(withId(R.id.textinput_edittext)).perform(click());
diff --git a/documents-archive/src/android/support/provider/DocumentArchive.java b/documents-archive/src/android/support/provider/DocumentArchive.java
index 5db5b38..91cd5e7 100644
--- a/documents-archive/src/android/support/provider/DocumentArchive.java
+++ b/documents-archive/src/android/support/provider/DocumentArchive.java
@@ -31,6 +31,7 @@
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsProvider;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
 
@@ -57,6 +58,8 @@
 import java.util.zip.ZipFile;
 import java.util.zip.ZipInputStream;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Provides basic implementation for creating, extracting and accessing
  * files within archives exposed by a document provider. The id delimiter
@@ -67,6 +70,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class DocumentArchive implements Closeable {
     private static final String TAG = "DocumentArchive";
 
diff --git a/documents-archive/src/android/support/provider/DocumentArchiveHelper.java b/documents-archive/src/android/support/provider/DocumentArchiveHelper.java
index 6cb4218..fd5ff94 100644
--- a/documents-archive/src/android/support/provider/DocumentArchiveHelper.java
+++ b/documents-archive/src/android/support/provider/DocumentArchiveHelper.java
@@ -28,6 +28,7 @@
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsProvider;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.util.Log;
 import android.util.LruCache;
 
@@ -42,6 +43,8 @@
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Provides basic implementation for creating, extracting and accessing
  * files within archives exposed by a document provider.
@@ -52,6 +55,7 @@
  * TODO: Update the documentation. b/26047732
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class DocumentArchiveHelper implements Closeable {
     /**
      * Cursor column to be used for passing the local file path for documents.
diff --git a/documents-archive/src/android/support/provider/IoUtils.java b/documents-archive/src/android/support/provider/IoUtils.java
index 61047dc..4806575 100644
--- a/documents-archive/src/android/support/provider/IoUtils.java
+++ b/documents-archive/src/android/support/provider/IoUtils.java
@@ -17,15 +17,19 @@
 package android.support.provider;
 
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 
 import java.io.Closeable;
 import java.io.InputStream;
 import java.util.Collection;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Simple static methods to perform common IO operations.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 final class IoUtils {
     static void closeQuietly(@Nullable Closeable closeable) {
        if (closeable != null) {
diff --git a/documents-archive/src/android/support/provider/ParsedDocumentId.java b/documents-archive/src/android/support/provider/ParsedDocumentId.java
index ee2c366..2834455 100644
--- a/documents-archive/src/android/support/provider/ParsedDocumentId.java
+++ b/documents-archive/src/android/support/provider/ParsedDocumentId.java
@@ -16,9 +16,14 @@
 
 package android.support.provider;
 
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 class ParsedDocumentId {
     public final String mArchiveId;
     public final String mPath;
diff --git a/documents-archive/src/android/support/provider/Preconditions.java b/documents-archive/src/android/support/provider/Preconditions.java
index fd62a2e..050ca9a 100644
--- a/documents-archive/src/android/support/provider/Preconditions.java
+++ b/documents-archive/src/android/support/provider/Preconditions.java
@@ -17,15 +17,19 @@
 package android.support.provider;
 
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.text.TextUtils;
 
 import java.util.Collection;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Simple static methods to be called at the start of your own methods to verify
  * correct arguments and state.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 final class Preconditions {
     static void checkArgument(boolean expression, String message) {
         if (!expression) {
diff --git a/fragment/java/android/support/v4/app/BackStackRecord.java b/fragment/java/android/support/v4/app/BackStackRecord.java
index 042cf9d..2e3116f 100644
--- a/fragment/java/android/support/v4/app/BackStackRecord.java
+++ b/fragment/java/android/support/v4/app/BackStackRecord.java
@@ -192,7 +192,7 @@
 }
 
 /**
- * @hide Entry of an operation on the fragment back stack.
+ * Entry of an operation on the fragment back stack.
  */
 final class BackStackRecord extends FragmentTransaction implements
         FragmentManager.BackStackEntry, Runnable {
@@ -348,7 +348,7 @@
                                 writer.println("Removed:");
                             }
                             writer.print(innerPrefix); writer.print("  #"); writer.print(i);
-                                    writer.print(": "); 
+                                    writer.print(": ");
                         }
                         writer.println(op.removed.get(i));
                     }
@@ -678,7 +678,7 @@
         disallowAddToBackStack();
         mManager.execSingleAction(this, true);
     }
-    
+
     int commitInternal(boolean allowStateLoss) {
         if (mCommitted) throw new IllegalStateException("commit already called");
         if (FragmentManagerImpl.DEBUG) {
@@ -1349,7 +1349,7 @@
         }
     }
 
-    private void callSharedElementEnd(TransitionState state, Fragment inFragment,
+    void callSharedElementEnd(TransitionState state, Fragment inFragment,
             Fragment outFragment, boolean isBack, ArrayMap<String, View> namedViews) {
         SharedElementCallback sharedElementCallback = isBack ?
                 outFragment.mEnterTransitionCallback :
@@ -1361,7 +1361,7 @@
         }
     }
 
-    private void setEpicenterIn(ArrayMap<String, View> namedViews, TransitionState state) {
+    void setEpicenterIn(ArrayMap<String, View> namedViews, TransitionState state) {
         if (mSharedElementTargetNames != null && !namedViews.isEmpty()) {
             // now we know the epicenter of the entering transition.
             View epicenter = namedViews
@@ -1372,7 +1372,7 @@
         }
     }
 
-    private ArrayMap<String, View> mapSharedElementsIn(TransitionState state,
+    ArrayMap<String, View> mapSharedElementsIn(TransitionState state,
             boolean isBack, Fragment inFragment) {
         // Now map the shared elements in the incoming fragment
         ArrayMap<String, View> namedViews = mapEnteringSharedElements(state, inFragment, isBack);
@@ -1459,7 +1459,7 @@
         });
     }
 
-    private void excludeHiddenFragments(TransitionState state, int containerId, Object transition) {
+    void excludeHiddenFragments(TransitionState state, int containerId, Object transition) {
         if (mManager.mAdded != null) {
             for (int i = 0; i < mManager.mAdded.size(); i++) {
                 Fragment fragment = mManager.mAdded.get(i);
diff --git a/fragment/java/android/support/v4/app/DialogFragment.java b/fragment/java/android/support/v4/app/DialogFragment.java
index b3a4f87..c67026a 100644
--- a/fragment/java/android/support/v4/app/DialogFragment.java
+++ b/fragment/java/android/support/v4/app/DialogFragment.java
@@ -24,6 +24,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -34,6 +35,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Static library support version of the framework's {@link android.app.DialogFragment}.
  * Used to write apps that run on platforms prior to Android 3.0.  When running
@@ -45,6 +48,7 @@
         implements DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({STYLE_NORMAL, STYLE_NO_TITLE, STYLE_NO_FRAME, STYLE_NO_INPUT})
     @Retention(RetentionPolicy.SOURCE)
     private @interface DialogStyle {}
@@ -298,6 +302,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
         if (!mShowsDialog) {
@@ -317,6 +322,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void setupDialog(Dialog dialog, int style) {
         switch (style) {
             case STYLE_NO_INPUT:
diff --git a/fragment/java/android/support/v4/app/Fragment.java b/fragment/java/android/support/v4/app/Fragment.java
index 3675204..f9fcc45 100644
--- a/fragment/java/android/support/v4/app/Fragment.java
+++ b/fragment/java/android/support/v4/app/Fragment.java
@@ -29,6 +29,7 @@
 import android.support.annotation.CallSuper;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringRes;
 import android.support.v4.util.DebugUtils;
 import android.support.v4.util.SimpleArrayMap;
@@ -51,6 +52,8 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 final class FragmentState implements Parcelable {
     final String mClassName;
     final int mIndex;
@@ -791,11 +794,13 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     final public boolean hasOptionsMenu() {
         return mHasMenu;
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     final public boolean isMenuVisible() {
         return mMenuVisible;
     }
@@ -1112,10 +1117,12 @@
     }
 
     /**
-     * @hide Hack so that DialogFragment can make its Dialog before creating
+     * 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
      */
+    @RestrictTo(GROUP_ID)
     public LayoutInflater getLayoutInflater(Bundle savedInstanceState) {
         LayoutInflater result = mHost.onGetLayoutInflater();
         getChildFragmentManager(); // Init if needed; use raw implementation below.
diff --git a/fragment/java/android/support/v4/app/FragmentActivity.java b/fragment/java/android/support/v4/app/FragmentActivity.java
index aadf938..4542962 100644
--- a/fragment/java/android/support/v4/app/FragmentActivity.java
+++ b/fragment/java/android/support/v4/app/FragmentActivity.java
@@ -29,6 +29,7 @@
 import android.support.annotation.CallSuper;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.media.session.MediaControllerCompat;
 import android.support.v4.util.SimpleArrayMap;
 import android.support.v4.util.SparseArrayCompat;
@@ -44,6 +45,8 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Base class for activities that want to use the support-based
  * {@link android.support.v4.app.Fragment} and
@@ -405,11 +408,11 @@
         if (super.onMenuItemSelected(featureId, item)) {
             return true;
         }
-        
+
         switch (featureId) {
             case Window.FEATURE_OPTIONS_PANEL:
                 return mFragments.dispatchOptionsItemSelected(item);
-                
+
             case Window.FEATURE_CONTEXT_MENU:
                 return mFragments.dispatchContextItemSelected(item);
 
@@ -430,7 +433,7 @@
         }
         super.onPanelClosed(featureId, menu);
     }
-    
+
     /**
      * Dispatch onPause() to fragments.
      */
@@ -527,6 +530,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected boolean onPrepareOptionsPanel(View view, Menu menu) {
         return super.onPreparePanel(Window.FEATURE_OPTIONS_PANEL, view, menu);
     }
@@ -984,7 +988,7 @@
     /**
      * Called by Fragment.requestPermissions() to implement its behavior.
      */
-    private void requestPermissionsFromFragment(Fragment fragment, String[] permissions,
+    void requestPermissionsFromFragment(Fragment fragment, String[] permissions,
             int requestCode) {
         if (requestCode == -1) {
             ActivityCompat.requestPermissions(this, permissions, requestCode);
diff --git a/fragment/java/android/support/v4/app/FragmentManager.java b/fragment/java/android/support/v4/app/FragmentManager.java
index 6f251e7..3baf4f9 100644
--- a/fragment/java/android/support/v4/app/FragmentManager.java
+++ b/fragment/java/android/support/v4/app/FragmentManager.java
@@ -28,6 +28,7 @@
 import android.os.Parcelable;
 import android.support.annotation.CallSuper;
 import android.support.annotation.IdRes;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringRes;
 import android.support.v4.os.BuildCompat;
 import android.support.v4.util.DebugUtils;
@@ -59,6 +60,8 @@
 import java.util.Arrays;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Static library support version of the framework's {@link android.app.FragmentManager}.
  * Used to write apps that run on platforms prior to Android 3.0.  When running
@@ -76,7 +79,7 @@
      * with {@link FragmentTransaction#addToBackStack(String)
      * FragmentTransaction.addToBackStack()}.  Entries can later be
      * retrieved with {@link FragmentManager#getBackStackEntryAt(int)
-     * FragmentManager.getBackStackEntry()}.
+     * FragmentManager.getBackStackEntryAt()}.
      *
      * <p>Note that you should never hold on to a BackStackEntry object;
      * the identifier as returned by {@link #getId} is the only thing that
@@ -137,7 +140,7 @@
     /**
      * Start a series of edit operations on the Fragments associated with
      * this FragmentManager.
-     * 
+     *
      * <p>Note: A fragment transaction can only be created/committed prior
      * to an activity saving its state.  If you try to commit a transaction
      * after {@link FragmentActivity#onSaveInstanceState FragmentActivity.onSaveInstanceState()}
@@ -153,11 +156,12 @@
      * @hide -- remove once prebuilts are in.
      * @deprecated
      */
+    @RestrictTo(GROUP_ID)
     @Deprecated
     public FragmentTransaction openTransaction() {
         return beginTransaction();
     }
-    
+
     /**
      * After a {@link FragmentTransaction} is committed with
      * {@link FragmentTransaction#commit FragmentTransaction.commit()}, it
@@ -230,7 +234,7 @@
      * This function is asynchronous -- it enqueues the
      * request to pop, but the action will not be performed until the application
      * returns to its event loop.
-     * 
+     *
      * @param name If non-null, this is the name of a previous back state
      * to look for; if found, all states up to that state will be popped.  The
      * {@link #POP_BACK_STACK_INCLUSIVE} flag can be used to control whether
@@ -252,7 +256,7 @@
      * This function is asynchronous -- it enqueues the
      * request to pop, but the action will not be performed until the application
      * returns to its event loop.
-     * 
+     *
      * @param id Identifier of the stated to be popped. If no identifier exists,
      * false is returned.
      * The identifier is the number returned by
@@ -322,6 +326,7 @@
      * @return The list of all fragments or null if none.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public abstract List<Fragment> getFragments();
 
     /**
@@ -378,10 +383,10 @@
     FragmentState[] mActive;
     int[] mAdded;
     BackStackState[] mBackStack;
-    
+
     public FragmentManagerState() {
     }
-    
+
     public FragmentManagerState(Parcel in) {
         mActive = in.createTypedArray(FragmentState.CREATOR);
         mAdded = in.createIntArray();
@@ -399,7 +404,7 @@
         dest.writeIntArray(mAdded);
         dest.writeTypedArray(mBackStack, flags);
     }
-    
+
     public static final Parcelable.Creator<FragmentManagerState> CREATOR
             = new Parcelable.Creator<FragmentManagerState>() {
         @Override
@@ -420,7 +425,7 @@
 final class FragmentManagerImpl extends FragmentManager implements LayoutInflaterFactory {
     static boolean DEBUG = false;
     static final String TAG = "FragmentManager";
-    
+
     static final boolean HONEYCOMB = android.os.Build.VERSION.SDK_INT >= 11;
 
     static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
@@ -431,7 +436,7 @@
     static class AnimateOnHWLayerIfNeededListener implements AnimationListener {
         private AnimationListener mOriginalListener;
         private boolean mShouldRunOnHWLayer;
-        private View mView;
+        View mView;
 
         public AnimateOnHWLayerIfNeededListener(final View v, Animation anim) {
             if (v == null || anim == null) {
@@ -499,13 +504,13 @@
     ArrayList<Runnable> mPendingActions;
     Runnable[] mTmpActions;
     boolean mExecutingActions;
-    
+
     ArrayList<Fragment> mActive;
     ArrayList<Fragment> mAdded;
     ArrayList<Integer> mAvailIndices;
     ArrayList<BackStackRecord> mBackStack;
     ArrayList<Fragment> mCreatedMenus;
-    
+
     // Must be accessed while locked.
     ArrayList<BackStackRecord> mBackStackIndices;
     ArrayList<Integer> mAvailBackStackIndices;
@@ -519,17 +524,17 @@
     Fragment mParent;
 
     static Field sAnimationListenerField = null;
-    
+
     boolean mNeedMenuInvalidate;
     boolean mStateSaved;
     boolean mDestroyed;
     String mNoTransactionsBecause;
     boolean mHavePendingDeferredStart;
-    
+
     // Temporary vars for state save and restore.
     Bundle mStateBundle = null;
     SparseArray<Parcelable> mStateArray = null;
-    
+
     Runnable mExecCommit = new Runnable() {
         @Override
         public void run() {
@@ -850,9 +855,9 @@
     static final Interpolator DECELERATE_CUBIC = new DecelerateInterpolator(1.5f);
     static final Interpolator ACCELERATE_QUINT = new AccelerateInterpolator(2.5f);
     static final Interpolator ACCELERATE_CUBIC = new AccelerateInterpolator(1.5f);
-    
+
     static final int ANIM_DUR = 220;
-    
+
     static Animation makeOpenCloseAnimation(Context context, float startScale,
             float endScale, float startAlpha, float endAlpha) {
         AnimationSet set = new AnimationSet(false);
@@ -867,7 +872,7 @@
         set.addAnimation(alpha);
         return set;
     }
-    
+
     static Animation makeFadeAnimation(Context context, float start, float end) {
         AlphaAnimation anim = new AlphaAnimation(start, end);
         anim.setInterpolator(DECELERATE_CUBIC);
@@ -882,18 +887,18 @@
         if (animObj != null) {
             return animObj;
         }
-        
+
         if (fragment.mNextAnim != 0) {
             Animation anim = AnimationUtils.loadAnimation(mHost.getContext(), fragment.mNextAnim);
             if (anim != null) {
                 return anim;
             }
         }
-        
+
         if (transit == 0) {
             return null;
         }
-        
+
         int styleIndex = transitToStyleIndex(transit, enter);
         if (styleIndex < 0) {
             return null;
@@ -913,27 +918,27 @@
             case ANIM_STYLE_FADE_EXIT:
                 return makeFadeAnimation(mHost.getContext(), 1, 0);
         }
-        
+
         if (transitionStyle == 0 && mHost.onHasWindowAnimations()) {
             transitionStyle = mHost.onGetWindowAnimations();
         }
         if (transitionStyle == 0) {
             return null;
         }
-        
+
         //TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle,
         //        com.android.internal.R.styleable.FragmentAnimation);
         //int anim = attrs.getResourceId(styleIndex, 0);
         //attrs.recycle();
-        
+
         //if (anim == 0) {
         //    return null;
         //}
-        
+
         //return AnimatorInflater.loadAnimator(mActivity, anim);
         return null;
     }
-    
+
     public void performPendingDeferredStart(Fragment f) {
         if (f.mDeferStart) {
             if (mExecutingActions) {
@@ -1004,7 +1009,7 @@
             // being reloaded from the layout.
             if (f.mFromLayout && !f.mInLayout) {
                 return;
-            }  
+            }
             if (f.mAnimatingAway != null) {
                 // The fragment is currently being animated...  but!  Now we
                 // want to move our state back up.  Give up on waiting for the
@@ -1263,7 +1268,7 @@
             f.mState = newState;
         }
     }
-    
+
     void moveToState(Fragment f) {
         moveToState(f, mCurState, 0, 0, false);
     }
@@ -1271,7 +1276,7 @@
     void moveToState(int newState, boolean always) {
         moveToState(newState, 0, 0, always);
     }
-    
+
     void moveToState(int newState, int transit, int transitStyle, boolean always) {
         if (mHost == null && newState != Fragment.INITIALIZING) {
             throw new IllegalStateException("No host");
@@ -1315,31 +1320,31 @@
             }
         }
     }
-    
+
     void makeActive(Fragment f) {
         if (f.mIndex >= 0) {
             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);
         }
         if (DEBUG) Log.v(TAG, "Allocated fragment index " + f);
     }
-    
+
     void makeInactive(Fragment f) {
         if (f.mIndex < 0) {
             return;
         }
-        
+
         if (DEBUG) Log.v(TAG, "Freeing fragment index " + f);
         mActive.set(f.mIndex, null);
         if (mAvailIndices == null) {
@@ -1349,7 +1354,7 @@
         mHost.inactivateFragment(f.mWho);
         f.initState();
     }
-    
+
     public void addFragment(Fragment fragment, boolean moveToStateNow) {
         if (mAdded == null) {
             mAdded = new ArrayList<Fragment>();
@@ -1371,7 +1376,7 @@
             }
         }
     }
-    
+
     public void removeFragment(Fragment fragment, int transition, int transitionStyle) {
         if (DEBUG) Log.v(TAG, "remove: " + fragment + " nesting=" + fragment.mBackStackNesting);
         final boolean inactive = !fragment.isInBackStack();
@@ -1388,7 +1393,7 @@
                     transition, transitionStyle, false);
         }
     }
-    
+
     public void hideFragment(Fragment fragment, int transition, int transitionStyle) {
         if (DEBUG) Log.v(TAG, "hide: " + fragment);
         if (!fragment.mHidden) {
@@ -1408,7 +1413,7 @@
             fragment.onHiddenChanged(true);
         }
     }
-    
+
     public void showFragment(Fragment fragment, int transition, int transitionStyle) {
         if (DEBUG) Log.v(TAG, "show: " + fragment);
         if (fragment.mHidden) {
@@ -1428,7 +1433,7 @@
             fragment.onHiddenChanged(false);
         }
     }
-    
+
     public void detachFragment(Fragment fragment, int transition, int transitionStyle) {
         if (DEBUG) Log.v(TAG, "detach: " + fragment);
         if (!fragment.mDetached) {
@@ -1515,7 +1520,7 @@
         }
         return null;
     }
-    
+
     public Fragment findFragmentByWho(String who) {
         if (mActive != null && who != null) {
             for (int i=mActive.size()-1; i>=0; i--) {
@@ -1527,7 +1532,7 @@
         }
         return null;
     }
-    
+
     private void checkStateLoss() {
         if (mStateSaved) {
             throw new IllegalStateException(
@@ -1564,7 +1569,7 @@
             }
         }
     }
-    
+
     public int allocBackStackIndex(BackStackRecord bse) {
         synchronized (this) {
             if (mAvailBackStackIndices == null || mAvailBackStackIndices.size() <= 0) {
@@ -1648,7 +1653,7 @@
         if (mExecutingActions) {
             throw new IllegalStateException("FragmentManager is already executing transactions");
         }
-        
+
         if (Looper.myLooper() != mHost.getHandler().getLooper()) {
             throw new IllegalStateException("Must be called from main thread of fragment host");
         }
@@ -1657,12 +1662,12 @@
 
         while (true) {
             int numActions;
-            
+
             synchronized (this) {
                 if (mPendingActions == null || mPendingActions.size() == 0) {
                     break;
                 }
-                
+
                 numActions = mPendingActions.size();
                 if (mTmpActions == null || mTmpActions.length < numActions) {
                     mTmpActions = new Runnable[numActions];
@@ -1671,7 +1676,7 @@
                 mPendingActions.clear();
                 mHost.getHandler().removeCallbacks(mExecCommit);
             }
-            
+
             mExecutingActions = true;
             for (int i=0; i<numActions; i++) {
                 mTmpActions[i].run();
@@ -1680,7 +1685,7 @@
             mExecutingActions = false;
             didSomething = true;
         }
-        
+
         doPendingDeferredStart();
 
         return didSomething;
@@ -1717,7 +1722,7 @@
         mBackStack.add(state);
         reportBackStackChanged();
     }
-    
+
     @SuppressWarnings("unused")
     boolean popBackStackState(Handler handler, String name, int id, int flags) {
         if (mBackStack == null) {
@@ -1795,7 +1800,7 @@
         }
         return true;
     }
-    
+
     FragmentManagerNonConfig retainNonConfig() {
         ArrayList<Fragment> fragments = null;
         ArrayList<FragmentManagerNonConfig> childFragments = null;
@@ -1837,7 +1842,7 @@
         }
         return new FragmentManagerNonConfig(fragments, childFragments);
     }
-    
+
     void saveFragmentViewState(Fragment f) {
         if (f.mInnerView == null) {
             return;
@@ -1853,7 +1858,7 @@
             mStateArray = null;
         }
     }
-    
+
     Bundle saveFragmentBasicState(Fragment f) {
         Bundle result = null;
 
@@ -1908,7 +1913,7 @@
         if (mActive == null || mActive.size() <= 0) {
             return null;
         }
-        
+
         // First collect all active fragments.
         int N = mActive.size();
         FragmentState[] active = new FragmentState[N];
@@ -1923,10 +1928,10 @@
                 }
 
                 haveFragments = true;
-                
+
                 FragmentState fs = new FragmentState(f);
                 active[i] = fs;
-                
+
                 if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
                     fs.mSavedFragmentState = saveFragmentBasicState(f);
 
@@ -1951,20 +1956,20 @@
                 } else {
                     fs.mSavedFragmentState = f.mSavedFragmentState;
                 }
-                
+
                 if (DEBUG) Log.v(TAG, "Saved state of " + f + ": "
                         + fs.mSavedFragmentState);
             }
         }
-        
+
         if (!haveFragments) {
             if (DEBUG) Log.v(TAG, "saveAllState: no fragments!");
             return null;
         }
-        
+
         int[] added = null;
         BackStackState[] backStack = null;
-        
+
         // Build list of currently added fragments.
         if (mAdded != null) {
             N = mAdded.size();
@@ -1982,7 +1987,7 @@
                 }
             }
         }
-        
+
         // Now save back stack.
         if (mBackStack != null) {
             N = mBackStack.size();
@@ -1995,14 +2000,14 @@
                 }
             }
         }
-        
+
         FragmentManagerState fms = new FragmentManagerState();
         fms.mActive = active;
         fms.mAdded = added;
         fms.mBackStack = backStack;
         return fms;
     }
-    
+
     void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) {
         // If there is no saved state at all, then there can not be
         // any nonConfig fragments either, so that is that.
@@ -2036,7 +2041,7 @@
                 }
             }
         }
-        
+
         // Build the full list of active fragments, instantiating them from
         // their saved state.
         mActive = new ArrayList<>(fms.mActive.length);
@@ -2066,7 +2071,7 @@
                 mAvailIndices.add(i);
             }
         }
-        
+
         // Update the target of all retained fragments.
         if (nonConfig != null) {
             List<Fragment> nonConfigFragments = nonConfig.getFragments();
@@ -2104,7 +2109,7 @@
         } else {
             mAdded = null;
         }
-        
+
         // Build the back stack.
         if (fms.mBackStack != null) {
             mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length);
@@ -2134,35 +2139,35 @@
         mContainer = container;
         mParent = parent;
     }
-    
+
     public void noteStateNotSaved() {
         mStateSaved = false;
     }
-    
+
     public void dispatchCreate() {
         mStateSaved = false;
         moveToState(Fragment.CREATED, false);
     }
-    
+
     public void dispatchActivityCreated() {
         mStateSaved = false;
         moveToState(Fragment.ACTIVITY_CREATED, false);
     }
-    
+
     public void dispatchStart() {
         mStateSaved = false;
         moveToState(Fragment.STARTED, false);
     }
-    
+
     public void dispatchResume() {
         mStateSaved = false;
         moveToState(Fragment.RESUMED, false);
     }
-    
+
     public void dispatchPause() {
         moveToState(Fragment.STARTED, false);
     }
-    
+
     public void dispatchStop() {
         // See saveAllState() for the explanation of this.  We do this for
         // all platform versions, to keep our behavior more consistent between
@@ -2171,7 +2176,7 @@
 
         moveToState(Fragment.STOPPED, false);
     }
-    
+
     public void dispatchReallyStop() {
         moveToState(Fragment.ACTIVITY_CREATED, false);
     }
@@ -2266,7 +2271,7 @@
 
         return show;
     }
-    
+
     public boolean dispatchPrepareOptionsMenu(Menu menu) {
         boolean show = false;
         if (mAdded != null) {
@@ -2281,7 +2286,7 @@
         }
         return show;
     }
-    
+
     public boolean dispatchOptionsItemSelected(MenuItem item) {
         if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
@@ -2295,7 +2300,7 @@
         }
         return false;
     }
-    
+
     public boolean dispatchContextItemSelected(MenuItem item) {
         if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
@@ -2309,7 +2314,7 @@
         }
         return false;
     }
-    
+
     public void dispatchOptionsMenuClosed(Menu menu) {
         if (mAdded != null) {
             for (int i=0; i<mAdded.size(); i++) {
@@ -2335,16 +2340,16 @@
                 break;
         }
         return rev;
-        
+
     }
-    
+
     public static final int ANIM_STYLE_OPEN_ENTER = 1;
     public static final int ANIM_STYLE_OPEN_EXIT = 2;
     public static final int ANIM_STYLE_CLOSE_ENTER = 3;
     public static final int ANIM_STYLE_CLOSE_EXIT = 4;
     public static final int ANIM_STYLE_FADE_ENTER = 5;
     public static final int ANIM_STYLE_FADE_EXIT = 6;
-    
+
     public static int transitToStyleIndex(int transit, boolean enter) {
         int animAttr = -1;
         switch (transit) {
diff --git a/fragment/java/android/support/v4/app/FragmentTabHost.java b/fragment/java/android/support/v4/app/FragmentTabHost.java
index fb0c67b..09b89b7 100644
--- a/fragment/java/android/support/v4/app/FragmentTabHost.java
+++ b/fragment/java/android/support/v4/app/FragmentTabHost.java
@@ -62,10 +62,10 @@
     private boolean mAttached;
 
     static final class TabInfo {
-        private final @NonNull String tag;
-        private final @NonNull Class<?> clss;
-        private final @Nullable Bundle args;
-        private Fragment fragment;
+        final @NonNull String tag;
+        final @NonNull Class<?> clss;
+        final @Nullable Bundle args;
+        Fragment fragment;
 
         TabInfo(@NonNull String _tag, @NonNull Class<?> _class, @Nullable Bundle _args) {
             tag = _tag;
@@ -97,7 +97,7 @@
             super(superState);
         }
 
-        private SavedState(Parcel in) {
+        SavedState(Parcel in) {
             super(in);
             curTab = in.readString();
         }
diff --git a/fragment/java/android/support/v4/app/FragmentTransaction.java b/fragment/java/android/support/v4/app/FragmentTransaction.java
index cea0282..745f7e8 100644
--- a/fragment/java/android/support/v4/app/FragmentTransaction.java
+++ b/fragment/java/android/support/v4/app/FragmentTransaction.java
@@ -20,6 +20,7 @@
 import android.support.annotation.IdRes;
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringRes;
 import android.support.annotation.StyleRes;
 import android.support.v4.util.Pair;
@@ -28,6 +29,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Static library support version of the framework's {@link android.app.FragmentTransaction}.
  * Used to write apps that run on platforms prior to Android 3.0.  When running
@@ -162,6 +165,7 @@
     public static final int TRANSIT_EXIT_MASK = 0x2000;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({TRANSIT_NONE, TRANSIT_FRAGMENT_OPEN, TRANSIT_FRAGMENT_CLOSE, TRANSIT_FRAGMENT_FADE})
     @Retention(RetentionPolicy.SOURCE)
     private @interface Transit {}
diff --git a/fragment/java/android/support/v4/app/LoaderManager.java b/fragment/java/android/support/v4/app/LoaderManager.java
index 634a6bc..72718ae 100644
--- a/fragment/java/android/support/v4/app/LoaderManager.java
+++ b/fragment/java/android/support/v4/app/LoaderManager.java
@@ -33,7 +33,7 @@
  * on Android 3.0 or above, this implementation is still used; it does not try
  * to switch to the framework's implementation.  See the framework SDK
  * documentation for a class overview.
- * 
+ *
  * <p>Your activity must derive from {@link FragmentActivity} to use this.
  */
 public abstract class LoaderManager {
@@ -56,7 +56,7 @@
          * transactions while in this call, since it can happen after an
          * activity's state is saved.  See {@link FragmentManager#beginTransaction()
          * FragmentManager.openTransaction()} for further discussion on this.
-         * 
+         *
          * <p>This function is guaranteed to be called prior to the release of
          * the last data that was supplied for this Loader.  At this point
          * you should remove all use of the old data (since it will be released
@@ -100,7 +100,7 @@
          */
         public void onLoaderReset(Loader<D> loader);
     }
-    
+
     /**
      * Ensures a loader is initialized and active.  If the loader doesn't
      * already exist, one is created and (if the activity/fragment is currently
@@ -184,9 +184,6 @@
     public boolean hasRunningLoaders() { return false; }
 }
 
-/**
- * @hide
- */
 class LoaderManagerImpl extends LoaderManager {
     static final String TAG = "LoaderManager";
     static boolean DEBUG = false;
@@ -207,9 +204,9 @@
     boolean mStarted;
     boolean mRetaining;
     boolean mRetainingStarted;
-    
+
     boolean mCreatingLoader;
-    private FragmentHostCallback mHost;
+    FragmentHostCallback mHost;
 
     final class LoaderInfo implements Loader.OnLoadCompleteListener<Object>,
             Loader.OnLoadCanceledListener<Object> {
@@ -231,13 +228,13 @@
         boolean mListenerRegistered;
 
         LoaderInfo mPendingLoader;
-        
+
         public LoaderInfo(int id, Bundle args, LoaderManager.LoaderCallbacks<Object> callbacks) {
             mId = id;
             mArgs = args;
             mCallbacks = callbacks;
         }
-        
+
         void start() {
             if (mRetaining && mRetainingStarted) {
                 // Our owner is started, but we were being retained from a
@@ -253,7 +250,7 @@
             }
 
             mStarted = true;
-            
+
             if (DEBUG) Log.v(TAG, "  Starting: " + this);
             if (mLoader == null && mCallbacks != null) {
                mLoader = mCallbacks.onCreateLoader(mId, mArgs);
@@ -273,7 +270,7 @@
                 mLoader.startLoading();
             }
         }
-        
+
         void retain() {
             if (DEBUG) Log.v(TAG, "  Retaining: " + this);
             mRetaining = true;
@@ -281,7 +278,7 @@
             mStarted = false;
             mCallbacks = null;
         }
-        
+
         void finishRetain() {
             if (mRetaining) {
                 if (DEBUG) Log.v(TAG, "  Finished Retaining: " + this);
@@ -306,7 +303,7 @@
                 callOnLoadFinished(mLoader, mData);
             }
         }
-        
+
         void reportStart() {
             if (mStarted) {
                 if (mReportNextStart) {
@@ -412,7 +409,7 @@
         @Override
         public void onLoadComplete(Loader<Object> loader, Object data) {
             if (DEBUG) Log.v(TAG, "onLoadComplete: " + this);
-            
+
             if (mDestroyed) {
                 if (DEBUG) Log.v(TAG, "  Ignoring load complete -- destroyed");
                 return;
@@ -424,7 +421,7 @@
                 if (DEBUG) Log.v(TAG, "  Ignoring load complete -- not active");
                 return;
             }
-            
+
             LoaderInfo pending = mPendingLoader;
             if (pending != null) {
                 // There is a new request pending and we were just
@@ -437,7 +434,7 @@
                 installLoader(pending);
                 return;
             }
-            
+
             // Notify of the new data so the app can switch out the old data before
             // we try to destroy it.
             if (mData != data || !mHaveData) {
@@ -485,7 +482,7 @@
                 mDeliveredData = true;
             }
         }
-        
+
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder(64);
@@ -525,17 +522,17 @@
             }
         }
     }
-    
+
     LoaderManagerImpl(String who, FragmentHostCallback host, boolean started) {
         mWho = who;
         mHost = host;
         mStarted = started;
     }
-    
+
     void updateHostController(FragmentHostCallback host) {
         mHost = host;
     }
-    
+
     private LoaderInfo createLoader(int id, Bundle args,
             LoaderManager.LoaderCallbacks<Object> callback) {
         LoaderInfo info = new LoaderInfo(id, args,  callback);
@@ -543,7 +540,7 @@
         info.mLoader = loader;
         return info;
     }
-    
+
     private LoaderInfo createAndInstallLoader(int id, Bundle args,
             LoaderManager.LoaderCallbacks<Object> callback) {
         try {
@@ -555,7 +552,7 @@
             mCreatingLoader = false;
         }
     }
-    
+
     void installLoader(LoaderInfo info) {
         mLoaders.put(info.mId, info);
         if (mStarted) {
@@ -565,23 +562,23 @@
             info.start();
         }
     }
-    
+
     /**
      * Call to initialize a particular ID with a Loader.  If this ID already
      * has a Loader associated with it, it is left unchanged and any previous
      * callbacks replaced with the newly provided ones.  If there is not currently
      * a Loader for the ID, a new one is created and started.
-     * 
+     *
      * <p>This function should generally be used when a component is initializing,
      * to ensure that a Loader it relies on is created.  This allows it to re-use
      * an existing Loader's data if there already is one, so that for example
      * when an {@link Activity} is re-created after a configuration change it
      * does not need to re-create its loaders.
-     * 
+     *
      * <p>Note that in the case where an existing Loader is re-used, the
      * <var>args</var> given here <em>will be ignored</em> because you will
      * continue using the previous Loader.
-     * 
+     *
      * @param id A unique (to this LoaderManager instance) identifier under
      * which to manage the new Loader.
      * @param args Optional arguments that will be propagated to
@@ -596,9 +593,9 @@
         if (mCreatingLoader) {
             throw new IllegalStateException("Called while creating a loader");
         }
-        
+
         LoaderInfo info = mLoaders.get(id);
-        
+
         if (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args);
 
         if (info == null) {
@@ -609,30 +606,30 @@
             if (DEBUG) Log.v(TAG, "  Re-using existing loader " + info);
             info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback;
         }
-        
+
         if (info.mHaveData && mStarted) {
             // If the loader has already generated its data, report it now.
             info.callOnLoadFinished(info.mLoader, info.mData);
         }
-        
+
         return (Loader<D>)info.mLoader;
     }
-    
+
     /**
      * Call to re-create the Loader associated with a particular ID.  If there
      * is currently a Loader associated with this ID, it will be
      * canceled/stopped/destroyed as appropriate.  A new Loader with the given
      * arguments will be created and its data delivered to you once available.
-     * 
+     *
      * <p>This function does some throttling of Loaders.  If too many Loaders
      * have been created for the given ID but not yet generated their data,
      * new calls to this function will create and return a new Loader but not
      * actually start it until some previous loaders have completed.
-     * 
+     *
      * <p>After calling this function, any previous Loaders associated with
      * this ID will be considered invalid, and you will receive no further
      * data updates from them.
-     * 
+     *
      * @param id A unique (to this LoaderManager instance) identifier under
      * which to manage the new Loader.
      * @param args Optional arguments that will be propagated to
@@ -647,7 +644,7 @@
         if (mCreatingLoader) {
             throw new IllegalStateException("Called while creating a loader");
         }
-        
+
         LoaderInfo info = mLoaders.get(id);
         if (DEBUG) Log.v(TAG, "restartLoader in " + this + ": args=" + args);
         if (info != null) {
@@ -686,7 +683,7 @@
                             info.mPendingLoader = null;
                         }
                         if (DEBUG) Log.v(TAG, "  Enqueuing as new pending loader");
-                        info.mPendingLoader = createLoader(id, args, 
+                        info.mPendingLoader = createLoader(id, args,
                                 (LoaderManager.LoaderCallbacks<Object>)callback);
                         return (Loader<D>)info.mPendingLoader.mLoader;
                     }
@@ -699,11 +696,11 @@
                 mInactiveLoaders.put(id, info);
             }
         }
-        
+
         info = createAndInstallLoader(id, args,  (LoaderManager.LoaderCallbacks<Object>)callback);
         return (Loader<D>)info.mLoader;
     }
-    
+
     /**
      * Rip down, tear apart, shred to pieces a current Loader ID.  After returning
      * from this function, any Loader objects associated with this ID are
@@ -716,7 +713,7 @@
         if (mCreatingLoader) {
             throw new IllegalStateException("Called while creating a loader");
         }
-        
+
         if (DEBUG) Log.v(TAG, "destroyLoader in " + this + " of " + id);
         int idx = mLoaders.indexOfKey(id);
         if (idx >= 0) {
@@ -745,7 +742,7 @@
         if (mCreatingLoader) {
             throw new IllegalStateException("Called while creating a loader");
         }
-        
+
         LoaderInfo loaderInfo = mLoaders.get(id);
         if (loaderInfo != null) {
             if (loaderInfo.mPendingLoader != null) {
@@ -755,7 +752,7 @@
         }
         return null;
     }
- 
+
     void doStart() {
         if (DEBUG) Log.v(TAG, "Starting in " + this);
         if (mStarted) {
@@ -764,7 +761,7 @@
             Log.w(TAG, "Called doStart when already started: " + this, e);
             return;
         }
-        
+
         mStarted = true;
 
         // Call out to sub classes so they can start their loaders
@@ -773,7 +770,7 @@
             mLoaders.valueAt(i).start();
         }
     }
-    
+
     void doStop() {
         if (DEBUG) Log.v(TAG, "Stopping in " + this);
         if (!mStarted) {
@@ -788,7 +785,7 @@
         }
         mStarted = false;
     }
-    
+
     void doRetain() {
         if (DEBUG) Log.v(TAG, "Retaining in " + this);
         if (!mStarted) {
@@ -804,7 +801,7 @@
             mLoaders.valueAt(i).retain();
         }
     }
-    
+
     void finishRetain() {
         if (mRetaining) {
             if (DEBUG) Log.v(TAG, "Finished Retaining in " + this);
@@ -815,7 +812,7 @@
             }
         }
     }
-    
+
     void doReportNextStart() {
         for (int i = mLoaders.size()-1; i >= 0; i--) {
             mLoaders.valueAt(i).mReportNextStart = true;
@@ -836,7 +833,7 @@
             }
             mLoaders.clear();
         }
-        
+
         if (DEBUG) Log.v(TAG, "Destroying Inactive in " + this);
         for (int i = mInactiveLoaders.size()-1; i >= 0; i--) {
             mInactiveLoaders.valueAt(i).destroy();
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 f172738..639e906 100644
--- a/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
+++ b/graphics/drawable/animated/src/android/support/graphics/drawable/AnimatedVectorDrawableCompat.java
@@ -50,7 +50,7 @@
 import java.util.List;
 
 /**
- * For API 23 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.
@@ -78,7 +78,7 @@
 
     AnimatedVectorDrawableDelegateState mCachedConstantStateDelegate;
 
-    private AnimatedVectorDrawableCompat() {
+    AnimatedVectorDrawableCompat() {
         this(null, null, null);
     }
 
@@ -118,7 +118,7 @@
     @Nullable
     public static AnimatedVectorDrawableCompat create(@NonNull Context context,
                                                       @DrawableRes int resId) {
-        if (Build.VERSION.SDK_INT >= 23) {
+        if (Build.VERSION.SDK_INT >= 24) {
             final AnimatedVectorDrawableCompat drawable = new AnimatedVectorDrawableCompat(context);
             drawable.mDelegateDrawable = ResourcesCompat.getDrawable(context.getResources(), resId,
                     context.getTheme());
@@ -165,7 +165,7 @@
 
     /**
      * {@inheritDoc}
-     * <strong>Note</strong> that we don't support constant state when SDK < 23.
+     * <strong>Note</strong> that we don't support constant state when SDK < 24.
      * Make sure you check the return value before using it.
      */
     @Override
@@ -510,12 +510,12 @@
 
         @Override
         public Drawable newDrawable() {
-            throw new IllegalStateException("No constant state support for SDK < 23.");
+            throw new IllegalStateException("No constant state support for SDK < 24.");
         }
 
         @Override
         public Drawable newDrawable(Resources res) {
-            throw new IllegalStateException("No constant state support for SDK < 23.");
+            throw new IllegalStateException("No constant state support for SDK < 24.");
         }
 
         @Override
@@ -632,7 +632,7 @@
         }
     }
 
-    private final Callback mCallback = new Callback() {
+    final Callback mCallback = new Callback() {
         @Override
         public void invalidateDrawable(Drawable who) {
             invalidateSelf();
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 2ee43c2..b68d2cb 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/PathParser.java
@@ -40,7 +40,7 @@
      * @throws IllegalArgumentException       if {@code start > end}
      * @throws NullPointerException           if {@code original == null}
      */
-    private static float[] copyOfRange(float[] original, int start, int end) {
+    static float[] copyOfRange(float[] original, int start, int end) {
         if (start > end) {
             throw new IllegalArgumentException();
         }
@@ -183,6 +183,9 @@
         // next float starts with a '-' or a '.'.
         int mEndPosition;
         boolean mEndWithNegOrDot;
+
+        ExtractFloatResult() {
+        }
     }
 
     /**
@@ -294,12 +297,12 @@
         char type;
         float[] params;
 
-        private PathDataNode(char type, float[] params) {
+        PathDataNode(char type, float[] params) {
             this.type = type;
             this.params = params;
         }
 
-        private PathDataNode(PathDataNode n) {
+        PathDataNode(PathDataNode n) {
             type = n.type;
             params = copyOfRange(n.params, 0, n.params.length);
         }
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 24a249f..7dc7b9f 100644
--- a/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
+++ b/graphics/drawable/static/src/android/support/graphics/drawable/VectorDrawableCompat.java
@@ -14,6 +14,7 @@
 
 package android.support.graphics.drawable;
 
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.ResourcesCompat;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import org.xmlpull.v1.XmlPullParser;
@@ -53,8 +54,10 @@
 import java.util.ArrayList;
 import java.util.Stack;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
- * For API 23 and above, this class is delegating to the framework's {@link VectorDrawable}.
+ * For API 24 and above, this class is delegating to the framework's {@link VectorDrawable}.
  * For older API version, this class lets you create a drawable based on an XML vector graphic.
  * <p>
  * VectorDrawableCompat are defined in the same XML format as {@link VectorDrawable}.
@@ -108,11 +111,11 @@
     private final Matrix mTmpMatrix = new Matrix();
     private final Rect mTmpBounds = new Rect();
 
-    private VectorDrawableCompat() {
+    VectorDrawableCompat() {
         mVectorState = new VectorDrawableCompatState();
     }
 
-    private VectorDrawableCompat(@NonNull VectorDrawableCompatState state) {
+    VectorDrawableCompat(@NonNull VectorDrawableCompatState state) {
         mVectorState = state;
         mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
     }
@@ -373,6 +376,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public float getPixelSize() {
         if (mVectorState == null && mVectorState.mVPathRenderer == null ||
                 mVectorState.mVPathRenderer.mBaseWidth == 0 ||
@@ -401,7 +405,7 @@
     @Nullable
     public static VectorDrawableCompat create(@NonNull Resources res, @DrawableRes int resId,
                                               @Nullable Theme theme) {
-        if (Build.VERSION.SDK_INT >= 23) {
+        if (Build.VERSION.SDK_INT >= 24) {
             final VectorDrawableCompat drawable = new VectorDrawableCompat();
             drawable.mDelegateDrawable = ResourcesCompat.getDrawable(res, resId, theme);
             drawable.mCachedConstantStateDelegate = new VectorDrawableDelegateState(
@@ -442,7 +446,7 @@
         return drawable;
     }
 
-    private static int applyAlpha(int color, float alpha) {
+    static int applyAlpha(int color, float alpha) {
         int alphaBytes = Color.alpha(color);
         color &= 0x00FFFFFF;
         color |= ((int) (alphaBytes * alpha)) << 24;
@@ -720,7 +724,7 @@
     }
 
     /**
-     * Constant state for delegating the creating drawable job for SDK >= 23.
+     * Constant state for delegating the creating drawable job for SDK >= 24.
      * Instead of creating a VectorDrawable, create a VectorDrawableCompat instance which contains
      * a delegated VectorDrawable instance.
      */
@@ -920,7 +924,7 @@
         /////////////////////////////////////////////////////
         // Variables below need to be copied (deep copy if applicable) for mutation.
         private int mChangingConfigurations;
-        private final VGroup mRootGroup;
+        final VGroup mRootGroup;
         float mBaseWidth = 0;
         float mBaseHeight = 0;
         float mViewportWidth = 0;
@@ -1136,7 +1140,7 @@
         // Variables below need to be copied (deep copy if applicable) for mutation.
         final ArrayList<Object> mChildren = new ArrayList<Object>();
 
-        private float mRotate = 0;
+        float mRotate = 0;
         private float mPivotX = 0;
         private float mPivotY = 0;
         private float mScaleX = 1;
@@ -1147,7 +1151,7 @@
         // mLocalMatrix is updated based on the update of transformation information,
         // either parsed from the XML or by animation.
         private final Matrix mLocalMatrix = new Matrix();
-        private int mChangingConfigurations;
+        int mChangingConfigurations;
         private int[] mThemeAttrs;
         private String mGroupName = null;
 
diff --git a/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_share_golden.png b/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_share_golden.png
new file mode 100644
index 0000000..a233b1d
--- /dev/null
+++ b/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_share_golden.png
Binary files differ
diff --git a/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_wishlist_golden.png b/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_wishlist_golden.png
new file mode 100644
index 0000000..4ea9aef
--- /dev/null
+++ b/graphics/drawable/static/tests/res/drawable-nodpi/vector_icon_wishlist_golden.png
Binary files differ
diff --git a/graphics/drawable/static/tests/res/drawable/vector_icon_share.xml b/graphics/drawable/static/tests/res/drawable/vector_icon_share.xml
new file mode 100644
index 0000000..155302c
--- /dev/null
+++ b/graphics/drawable/static/tests/res/drawable/vector_icon_share.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+
+<vector android:height="24dp" android:viewportHeight="72.0"
+        android:viewportWidth="72.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <group
+            android:scaleX = "2"
+            android:scaleY = "2"
+            android:translateY = "-16"
+            android:translateX = "-36">
+        <path android:fillColor="#FF000000" android:pathData="M60.64,49.29a11.35,11.35 0,0 0,-9.74 5.54L22,39.65a11.14,11.14 0,0 0,0 -7.72L50.87,17.11a11.47,11.47 0,1 0,-1.17 -2.77l-29,14.93a11.36,11.36 0,1 0,0 13L49.71,57.59A11.35,11.35 0,1 0,60.64 49.29ZM60.64,3a8.36,8.36 0,1 1,-8.36 8.36A8.37,8.37 0,0 1,60.64 3ZM11.36,44.13a8.36,8.36 0,1 1,8.36 -8.36A8.37,8.37 0,0 1,11.36 44.13ZM60.64,69A8.36,8.36 0,1 1,69 60.64,8.37 8.37,0 0,1 60.64,69Z"/>
+    </group>
+</vector>
diff --git a/graphics/drawable/static/tests/res/drawable/vector_icon_wishlist.xml b/graphics/drawable/static/tests/res/drawable/vector_icon_wishlist.xml
new file mode 100644
index 0000000..fd4a52f
--- /dev/null
+++ b/graphics/drawable/static/tests/res/drawable/vector_icon_wishlist.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+-->
+
+<vector android:height="24dp" android:viewportHeight="72.0"
+        android:viewportWidth="72.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <group
+            android:scaleX = "2"
+            android:scaleY = "2"
+            android:translateX = "-72">
+        <path android:fillColor="#FF000000" android:pathData="M36,69.46h0c-1.56,0 -2.79,-1.17 -4.37,-2.81L4.72,34.93l-0.1,-0.13C2.39,31.48 0,27.47 0,22 0,11.25 8.41,2.54 18.75,2.54c6.18,0 11.85,2.59 17.3,7.91 4.5,-4.06 10,-7.91 17.2,-7.91C63.59,2.54 72,11.25 72,22A19.71,19.71 0,0 1,67.31 34.9L40.41,66.58C38.76,68.3 37.53,69.46 36,69.46ZM7.07,33.06L33.82,64.64A6.8,6.8 0,0 0,36 66.46c0.26,0 1,-0.64 2.21,-1.89L65,33a16.64,16.64 0,0 0,4 -11c0,-7.89 -6,-16.41 -15.75,-16.41C46.57,5.54 41.5,9.42 37,13.62a1.5,1.5 0,0 1,-2.11 -0.06c-5.17,-5.4 -10.46,-8 -16.17,-8C9,5.54 3,14.06 3,22 3,26.59 5,30 7.07,33.06Z"/>
+    </group>
+</vector>
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 9049b35..8fb9c2d 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
@@ -71,6 +71,8 @@
             R.drawable.vector_icon_stroke_3,
             R.drawable.vector_icon_scale_1,
             R.drawable.vector_icon_group_clip,
+            R.drawable.vector_icon_share,
+            R.drawable.vector_icon_wishlist,
     };
 
     private static final int[] GOLDEN_IMAGES = new int[]{
@@ -97,6 +99,8 @@
             R.drawable.vector_icon_stroke_3_golden,
             R.drawable.vector_icon_scale_1_golden,
             R.drawable.vector_icon_group_clip_golden,
+            R.drawable.vector_icon_share_golden,
+            R.drawable.vector_icon_wishlist_golden,
     };
 
     private static final int TEST_ICON = R.drawable.vector_icon_create;
diff --git a/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java b/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
index 59e44e2..2a7eaf3 100644
--- a/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
+++ b/media-compat/api21/android/support/v4/media/MediaBrowserServiceCompatApi21.java
@@ -66,8 +66,12 @@
             if (result instanceof List) {
                 mResultObj.sendResult(parcelListToItemList((List<Parcel>)result));
             } else if (result instanceof Parcel) {
-                mResultObj.sendResult(
-                        MediaBrowser.MediaItem.CREATOR.createFromParcel((Parcel) result));
+                Parcel parcel = (Parcel) result;
+                mResultObj.sendResult(MediaBrowser.MediaItem.CREATOR.createFromParcel(parcel));
+                parcel.recycle();
+            } else {
+                // The result is null or an invalid instance.
+                mResultObj.sendResult(null);
             }
         }
 
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
index b06c8e7..1fe0da9 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserCompat.java
@@ -32,6 +32,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.BundleCompat;
 import android.support.v4.media.session.MediaControllerCompat;
 import android.support.v4.media.session.MediaSessionCompat;
@@ -49,6 +50,7 @@
 import java.util.List;
 import java.util.Map;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v4.media.MediaBrowserProtocol.*;
 
 /**
@@ -59,8 +61,8 @@
  * </p>
  */
 public final class MediaBrowserCompat {
-    private static final String TAG = "MediaBrowserCompat";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final String TAG = "MediaBrowserCompat";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     /**
      * Used as an int extra field to denote the page number to subscribe.
@@ -307,6 +309,7 @@
         private final MediaDescriptionCompat mDescription;
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         @Retention(RetentionPolicy.SOURCE)
         @IntDef(flag=true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE })
         public @interface Flags { }
@@ -388,7 +391,7 @@
         /**
          * Private constructor.
          */
-        private MediaItem(Parcel in) {
+        MediaItem(Parcel in) {
             mFlags = in.readInt();
             mDescription = MediaDescriptionCompat.CREATOR.createFromParcel(in);
         }
@@ -470,7 +473,7 @@
      */
     public static class ConnectionCallback {
         final Object mConnectionCallbackObj;
-        private ConnectionCallbackInternal mConnectionCallbackInternal;
+        ConnectionCallbackInternal mConnectionCallbackInternal;
 
         public ConnectionCallback() {
             if (Build.VERSION.SDK_INT >= 21) {
@@ -511,6 +514,9 @@
         }
 
         private class StubApi21 implements MediaBrowserCompatApi21.ConnectionCallback {
+            StubApi21() {
+            }
+
             @Override
             public void onConnected() {
                 if (mConnectionCallbackInternal != null) {
@@ -543,7 +549,7 @@
     public static abstract class SubscriptionCallback {
         private final Object mSubscriptionCallbackObj;
         private final IBinder mToken;
-        private WeakReference<Subscription> mSubscriptionRef;
+        WeakReference<Subscription> mSubscriptionRef;
 
         public SubscriptionCallback() {
             if (Build.VERSION.SDK_INT >= 24 || BuildCompat.isAtLeastN()) {
@@ -614,6 +620,9 @@
         }
 
         private class StubApi21 implements MediaBrowserCompatApi21.SubscriptionCallback {
+            StubApi21() {
+            }
+
             @Override
             public void onChildrenLoaded(@NonNull String parentId, List<?> children) {
                 Subscription sub = mSubscriptionRef == null ? null : mSubscriptionRef.get();
@@ -667,6 +676,9 @@
 
         private class StubApi24 extends StubApi21
                 implements MediaBrowserCompatApi24.SubscriptionCallback {
+            StubApi24() {
+            }
+
             @Override
             public void onChildrenLoaded(@NonNull String parentId, List<?> children,
                     @NonNull Bundle options) {
@@ -712,6 +724,9 @@
         }
 
         private class StubApi23 implements MediaBrowserCompatApi23.ItemCallback {
+            StubApi23() {
+            }
+
             @Override
             public void onItemLoaded(Parcel itemParcel) {
                 itemParcel.setDataPosition(0);
@@ -750,22 +765,22 @@
 
     static class MediaBrowserImplBase
             implements MediaBrowserImpl, MediaBrowserServiceCallbackImpl {
-        private static final int CONNECT_STATE_DISCONNECTED = 0;
-        private static final int CONNECT_STATE_CONNECTING = 1;
+        static final int CONNECT_STATE_DISCONNECTED = 0;
+        static final int CONNECT_STATE_CONNECTING = 1;
         private static final int CONNECT_STATE_CONNECTED = 2;
-        private static final int CONNECT_STATE_SUSPENDED = 3;
+        static final int CONNECT_STATE_SUSPENDED = 3;
 
-        private final Context mContext;
-        private final ComponentName mServiceComponent;
-        private final ConnectionCallback mCallback;
-        private final Bundle mRootHints;
-        private final CallbackHandler mHandler = new CallbackHandler(this);
+        final Context mContext;
+        final ComponentName mServiceComponent;
+        final ConnectionCallback mCallback;
+        final Bundle mRootHints;
+        final CallbackHandler mHandler = new CallbackHandler(this);
         private final ArrayMap<String, Subscription> mSubscriptions = new ArrayMap<>();
 
-        private int mState = CONNECT_STATE_DISCONNECTED;
-        private MediaServiceConnection mServiceConnection;
-        private ServiceBinderWrapper mServiceBinderWrapper;
-        private Messenger mCallbacksMessenger;
+        int mState = CONNECT_STATE_DISCONNECTED;
+        MediaServiceConnection mServiceConnection;
+        ServiceBinderWrapper mServiceBinderWrapper;
+        Messenger mCallbacksMessenger;
         private String mRootId;
         private MediaSessionCompat.Token mMediaSessionToken;
         private Bundle mExtras;
@@ -880,7 +895,7 @@
          * for a clean shutdown, but everywhere else is a dirty shutdown and should
          * notify the app.
          */
-        private void forceCloseConnection() {
+        void forceCloseConnection() {
             if (mServiceConnection != null) {
                 mContext.unbindService(mServiceConnection);
             }
@@ -1164,7 +1179,6 @@
 
         /**
          * Log internal state.
-         * @hide
          */
         void dump() {
             Log.d(TAG, "MediaBrowserCompat...");
@@ -1183,6 +1197,9 @@
          * ServiceConnection to the other app.
          */
         private class MediaServiceConnection implements ServiceConnection {
+            MediaServiceConnection() {
+            }
+
             @Override
             public void onServiceConnected(final ComponentName name, final IBinder binder) {
                 postOrRun(new Runnable() {
@@ -1274,7 +1291,7 @@
             /**
              * Return true if this is the current ServiceConnection. Also logs if it's not.
              */
-            private boolean isCurrent(String funcName) {
+            boolean isCurrent(String funcName) {
                 if (mServiceConnection != this) {
                     if (mState != CONNECT_STATE_DISCONNECTED) {
                         // Check mState, because otherwise this log is noisy.
@@ -1300,9 +1317,9 @@
 
         public MediaBrowserImplApi21(Context context, ComponentName serviceComponent,
                 ConnectionCallback callback, Bundle rootHints) {
-            // Do not send the client version for API 24 and higher, since we don't need to use
+            // Do not send the client version for API 25 and higher, since we don't need to use
             // EXTRA_MESSENGER_BINDER for API 24 and higher.
-            if (Build.VERSION.SDK_INT < 24 && !BuildCompat.isAtLeastN()) {
+            if (Build.VERSION.SDK_INT < 25) {
                 if (rootHints == null) {
                     rootHints = new Bundle();
                 }
@@ -1466,7 +1483,7 @@
                     @Override
                     public void run() {
                         // Default framework implementation.
-                        cb.onItemLoaded(null);
+                        cb.onError(mediaId);
                     }
                 });
                 return;
@@ -1597,11 +1614,6 @@
                         callback.mSubscriptionCallbackObj);
             }
         }
-
-        @Override
-        public void getItem(@NonNull final String mediaId, @NonNull final ItemCallback cb) {
-            MediaBrowserCompatApi23.getItem(mBrowserObj, mediaId, cb.mItemCallbackObj);
-        }
     }
 
     private static class Subscription {
@@ -1779,7 +1791,7 @@
                 return;
             }
             Parcelable item = resultData.getParcelable(MediaBrowserServiceCompat.KEY_MEDIA_ITEM);
-            if (item instanceof MediaItem) {
+            if (item == null || item instanceof MediaItem) {
                 mCallback.onItemLoaded((MediaItem) item);
             } else {
                 mCallback.onError(mMediaId);
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserCompatUtils.java b/media-compat/java/android/support/v4/media/MediaBrowserCompatUtils.java
index 5db9eb4..1ffc9f5 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserCompatUtils.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserCompatUtils.java
@@ -17,10 +17,14 @@
 package android.support.v4.media;
 
 import android.os.Bundle;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class MediaBrowserCompatUtils {
     public static boolean areSameOptions(Bundle options1, Bundle options2) {
         if (options1 == options2) {
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java b/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
index 7ebfe9b..d2d12a7 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserProtocol.java
@@ -17,7 +17,6 @@
 
 /**
  * Defines the communication protocol for media browsers and media browser services.
- * @hide
  */
 class MediaBrowserProtocol {
 
diff --git a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
index 091cf35..23c0cb0 100644
--- a/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaBrowserServiceCompat.java
@@ -16,6 +16,7 @@
 
 package android.support.v4.media;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_ADD_SUBSCRIPTION;
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_CONNECT;
 import static android.support.v4.media.MediaBrowserProtocol.CLIENT_MSG_DISCONNECT;
@@ -55,6 +56,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.BundleCompat;
 import android.support.v4.media.session.MediaSessionCompat;
 import android.support.v4.os.BuildCompat;
@@ -96,8 +98,8 @@
  * </pre>
  */
 public abstract class MediaBrowserServiceCompat extends Service {
-    private static final String TAG = "MBServiceCompat";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final String TAG = "MBServiceCompat";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private MediaBrowserServiceImpl mImpl;
 
@@ -111,18 +113,22 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final String KEY_MEDIA_ITEM = "media_item";
 
-    private static final int RESULT_FLAG_OPTION_NOT_HANDLED = 0x00000001;
+    static final int RESULT_FLAG_OPTION_NOT_HANDLED = 0x00000001;
+    static final int RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED = 0x00000002;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag=true, value = { RESULT_FLAG_OPTION_NOT_HANDLED })
+    @IntDef(flag=true, value = { RESULT_FLAG_OPTION_NOT_HANDLED,
+            RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED })
     private @interface ResultFlags { }
 
-    private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap<>();
-    private ConnectionRecord mCurConnection;
-    private final ServiceHandler mHandler = new ServiceHandler();
+    final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap<>();
+    ConnectionRecord mCurConnection;
+    final ServiceHandler mHandler = new ServiceHandler();
     MediaSessionCompat.Token mSession;
 
     interface MediaBrowserServiceImpl {
@@ -331,9 +337,13 @@
                     = new Result<MediaBrowserCompat.MediaItem>(itemId) {
                 @Override
                 void onResultSent(MediaBrowserCompat.MediaItem item, @ResultFlags int flags) {
-                    Parcel parcelItem = Parcel.obtain();
-                    item.writeToParcel(parcelItem, 0);
-                    resultWrapper.sendResult(parcelItem);
+                    if (item == null) {
+                        resultWrapper.sendResult(null);
+                    } else {
+                        Parcel parcelItem = Parcel.obtain();
+                        item.writeToParcel(parcelItem, 0);
+                        resultWrapper.sendResult(parcelItem);
+                    }
                 }
 
                 @Override
@@ -400,6 +410,9 @@
     private final class ServiceHandler extends Handler {
         private final ServiceBinderImpl mServiceBinderImpl = new ServiceBinderImpl();
 
+        ServiceHandler() {
+        }
+
         @Override
         public void handleMessage(Message msg) {
             Bundle data = msg.getData();
@@ -470,6 +483,9 @@
         ServiceCallbacks callbacks;
         BrowserRoot root;
         HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap();
+
+        ConnectionRecord() {
+        }
     }
 
     /**
@@ -539,6 +555,9 @@
     }
 
     private class ServiceBinderImpl {
+        ServiceBinderImpl() {
+        }
+
         public void connect(final String pkg, final int uid, final Bundle rootHints,
                 final ServiceCallbacks callbacks) {
 
@@ -862,14 +881,18 @@
      * result.detach} may be called before returning from this function, and
      * then {@link Result#sendResult result.sendResult} called when the item has
      * been loaded.
-     * <p>
-     * The default implementation sends a null result.
+     * </p><p>
+     * When the given {@code itemId} is invalid, implementations must call
+     * {@link Result#sendResult result.sendResult} with {@code null}.
+     * </p><p>
+     * The default implementation will invoke {@link MediaBrowserCompat.ItemCallback#onError}.
      *
      * @param itemId The id for the specific {@link MediaBrowserCompat.MediaItem}.
      * @param result The Result to send the item to, or null if the id is
      *            invalid.
      */
     public void onLoadItem(String itemId, Result<MediaBrowserCompat.MediaItem> result) {
+        result.setFlags(RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED);
         result.sendResult(null);
     }
 
@@ -959,7 +982,7 @@
     /**
      * Return whether the given package is one of the ones that is owned by the uid.
      */
-    private boolean isValidPackage(String pkg, int uid) {
+    boolean isValidPackage(String pkg, int uid) {
         if (pkg == null) {
             return false;
         }
@@ -977,7 +1000,7 @@
     /**
      * Save the subscription and if it is a new subscription send the results.
      */
-    private void addSubscription(String id, ConnectionRecord connection, IBinder token,
+    void addSubscription(String id, ConnectionRecord connection, IBinder token,
             Bundle options) {
         // Save the subscription
         List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id);
@@ -999,7 +1022,7 @@
     /**
      * Remove the subscription.
      */
-    private boolean removeSubscription(String id, ConnectionRecord connection, IBinder token) {
+    boolean removeSubscription(String id, ConnectionRecord connection, IBinder token) {
         if (token == null) {
             return connection.subscriptions.remove(id) != null;
         }
@@ -1025,7 +1048,7 @@
      * <p>
      * Callers must make sure that this connection is still connected.
      */
-    private void performLoadChildren(final String parentId, final ConnectionRecord connection,
+    void performLoadChildren(final String parentId, final ConnectionRecord connection,
             final Bundle options) {
         final Result<List<MediaBrowserCompat.MediaItem>> result
                 = new Result<List<MediaBrowserCompat.MediaItem>>(parentId) {
@@ -1066,7 +1089,7 @@
         }
     }
 
-    private List<MediaBrowserCompat.MediaItem> applyOptions(List<MediaBrowserCompat.MediaItem> list,
+    List<MediaBrowserCompat.MediaItem> applyOptions(List<MediaBrowserCompat.MediaItem> list,
             final Bundle options) {
         if (list == null) {
             return null;
@@ -1087,12 +1110,16 @@
         return list.subList(fromIndex, toIndex);
     }
 
-    private void performLoadItem(String itemId, ConnectionRecord connection,
+    void performLoadItem(String itemId, ConnectionRecord connection,
             final ResultReceiver receiver) {
         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) {
+                            receiver.send(-1, null);
+                            return;
+                        }
                         Bundle bundle = new Bundle();
                         bundle.putParcelable(KEY_MEDIA_ITEM, item);
                         receiver.send(0, bundle);
diff --git a/media-compat/java/android/support/v4/media/MediaDescriptionCompat.java b/media-compat/java/android/support/v4/media/MediaDescriptionCompat.java
index a9c5819..1a597fc 100644
--- a/media-compat/java/android/support/v4/media/MediaDescriptionCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaDescriptionCompat.java
@@ -22,8 +22,11 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.text.TextUtils;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A simple set of metadata for a media item suitable for display. This can be
  * created using the Builder or retrieved from existing metadata using
@@ -98,6 +101,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final String DESCRIPTION_KEY_MEDIA_URI =
             "android.support.v4.media.description.MEDIA_URI";
     /**
@@ -105,6 +109,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final String DESCRIPTION_KEY_NULL_BUNDLE_FLAG =
             "android.support.v4.media.description.NULL_BUNDLE_FLAG";
     /**
@@ -145,7 +150,7 @@
      */
     private Object mDescriptionObj;
 
-    private MediaDescriptionCompat(String mediaId, CharSequence title, CharSequence subtitle,
+    MediaDescriptionCompat(String mediaId, CharSequence title, CharSequence subtitle,
             CharSequence description, Bitmap icon, Uri iconUri, Bundle extras, Uri mediaUri) {
         mMediaId = mediaId;
         mTitle = title;
@@ -157,7 +162,7 @@
         mMediaUri = mediaUri;
     }
 
-    private MediaDescriptionCompat(Parcel in) {
+    MediaDescriptionCompat(Parcel in) {
         mMediaId = in.readString();
         mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
         mSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
diff --git a/media-compat/java/android/support/v4/media/MediaMetadataCompat.java b/media-compat/java/android/support/v4/media/MediaMetadataCompat.java
index 1b98922..6116e6d 100644
--- a/media-compat/java/android/support/v4/media/MediaMetadataCompat.java
+++ b/media-compat/java/android/support/v4/media/MediaMetadataCompat.java
@@ -21,6 +21,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringDef;
 import android.support.v4.util.ArrayMap;
 import android.support.v4.media.MediaBrowserCompat;
@@ -32,6 +33,8 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.Set;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Contains metadata about an item, such as the title, artist, etc.
  */
@@ -238,6 +241,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @StringDef({METADATA_KEY_TITLE, METADATA_KEY_ARTIST, METADATA_KEY_ALBUM, METADATA_KEY_AUTHOR,
             METADATA_KEY_WRITER, METADATA_KEY_COMPOSER, METADATA_KEY_COMPILATION,
             METADATA_KEY_DATE, METADATA_KEY_GENRE, METADATA_KEY_ALBUM_ARTIST, METADATA_KEY_ART_URI,
@@ -250,6 +254,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @StringDef({METADATA_KEY_DURATION, METADATA_KEY_YEAR, METADATA_KEY_TRACK_NUMBER,
             METADATA_KEY_NUM_TRACKS, METADATA_KEY_DISC_NUMBER, METADATA_KEY_BT_FOLDER_TYPE})
     @Retention(RetentionPolicy.SOURCE)
@@ -258,6 +263,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @StringDef({METADATA_KEY_ART, METADATA_KEY_ALBUM_ART, METADATA_KEY_DISPLAY_ICON})
     @Retention(RetentionPolicy.SOURCE)
     public @interface BitmapKey {}
@@ -265,15 +271,16 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @StringDef({METADATA_KEY_USER_RATING, METADATA_KEY_RATING})
     @Retention(RetentionPolicy.SOURCE)
     public @interface RatingKey {}
 
-    private static final int METADATA_TYPE_LONG = 0;
-    private static final int METADATA_TYPE_TEXT = 1;
-    private static final int METADATA_TYPE_BITMAP = 2;
-    private static final int METADATA_TYPE_RATING = 3;
-    private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
+    static final int METADATA_TYPE_LONG = 0;
+    static final int METADATA_TYPE_TEXT = 1;
+    static final int METADATA_TYPE_BITMAP = 2;
+    static final int METADATA_TYPE_RATING = 3;
+    static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
 
     static {
         METADATA_KEYS_TYPE = new ArrayMap<String, Integer>();
@@ -330,15 +337,15 @@
             METADATA_KEY_ALBUM_ART_URI
     };
 
-    private final Bundle mBundle;
+    final Bundle mBundle;
     private Object mMetadataObj;
     private MediaDescriptionCompat mDescription;
 
-    private MediaMetadataCompat(Bundle bundle) {
+    MediaMetadataCompat(Bundle bundle) {
         mBundle = new Bundle(bundle);
     }
 
-    private MediaMetadataCompat(Parcel in) {
+    MediaMetadataCompat(Parcel in) {
         mBundle = in.readBundle();
     }
 
@@ -655,6 +662,7 @@
          *            in the metadata.
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public Builder(MediaMetadataCompat source, int maxBitmapSize) {
             this(source);
             for (String key : mBundle.keySet()) {
diff --git a/media-compat/java/android/support/v4/media/RatingCompat.java b/media-compat/java/android/support/v4/media/RatingCompat.java
index ee25ad4..af53bff 100644
--- a/media-compat/java/android/support/v4/media/RatingCompat.java
+++ b/media-compat/java/android/support/v4/media/RatingCompat.java
@@ -20,11 +20,14 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.support.annotation.IntDef;
+import android.support.annotation.RestrictTo;
 import android.util.Log;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A class to encapsulate rating information used as content metadata.
  * A rating is defined by its rating style (see {@link #RATING_HEART},
@@ -39,6 +42,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef({RATING_NONE, RATING_HEART, RATING_THUMB_UP_DOWN, RATING_3_STARS, RATING_4_STARS,
             RATING_5_STARS, RATING_PERCENTAGE})
     @Retention(RetentionPolicy.SOURCE)
@@ -47,6 +51,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef({RATING_3_STARS, RATING_4_STARS, RATING_5_STARS})
     @Retention(RetentionPolicy.SOURCE)
     public @interface StarStyle {}
@@ -96,7 +101,7 @@
 
     private Object mRatingObj; // framework Rating object
 
-    private RatingCompat(@Style int ratingStyle, float rating) {
+    RatingCompat(@Style int ratingStyle, float rating) {
         mRatingStyle = ratingStyle;
         mRatingValue = rating;
     }
diff --git a/media-compat/java/android/support/v4/media/VolumeProviderCompat.java b/media-compat/java/android/support/v4/media/VolumeProviderCompat.java
index cc82dbe..4213720 100644
--- a/media-compat/java/android/support/v4/media/VolumeProviderCompat.java
+++ b/media-compat/java/android/support/v4/media/VolumeProviderCompat.java
@@ -18,11 +18,14 @@
 
 import android.os.Build;
 import android.support.annotation.IntDef;
+import android.support.annotation.RestrictTo;
 import android.support.v4.media.session.MediaSessionCompat;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Handles requests to adjust or set the volume on a session. This is also used
  * to push volume updates back to the session after a request has been handled.
@@ -34,6 +37,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef({VOLUME_CONTROL_FIXED, VOLUME_CONTROL_RELATIVE, VOLUME_CONTROL_ABSOLUTE})
     @Retention(RetentionPolicy.SOURCE)
     public @interface ControlType {}
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 ff23aed..266a4d1 100644
--- a/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaControllerCompat.java
@@ -52,7 +52,7 @@
  * introduced after API level 4 in a backwards compatible fashion.
  */
 public final class MediaControllerCompat {
-    private static final String TAG = "MediaControllerCompat";
+    static final String TAG = "MediaControllerCompat";
 
     private final MediaControllerImpl mImpl;
     private final MediaSessionCompat.Token mToken;
@@ -343,9 +343,9 @@
      */
     public static abstract class Callback implements IBinder.DeathRecipient {
         private final Object mCallbackObj;
-        private MessageHandler mHandler;
+        MessageHandler mHandler;
 
-        private boolean mRegistered = false;
+        boolean mRegistered = false;
 
         public Callback() {
             if (android.os.Build.VERSION.SDK_INT >= 21) {
@@ -441,6 +441,9 @@
         }
 
         private class StubApi21 implements MediaControllerCompatApi21.Callback {
+            StubApi21() {
+            }
+
             @Override
             public void onSessionDestroyed() {
                 Callback.this.onSessionDestroyed();
@@ -487,6 +490,9 @@
 
         private class StubCompat extends IMediaControllerCallback.Stub {
 
+            StubCompat() {
+            }
+
             @Override
             public void onEvent(String event, Bundle extras) throws RemoteException {
                 mHandler.post(MessageHandler.MSG_EVENT, event, extras);
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 a383e2d..e73666c 100644
--- a/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
+++ b/media-compat/java/android/support/v4/media/session/MediaSessionCompat.java
@@ -39,6 +39,7 @@
 import android.os.ResultReceiver;
 import android.os.SystemClock;
 import android.support.annotation.IntDef;
+import android.support.annotation.RestrictTo;
 import android.support.v4.media.MediaDescriptionCompat;
 import android.support.v4.media.MediaMetadataCompat;
 import android.support.v4.media.RatingCompat;
@@ -53,6 +54,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Allows interaction with media controllers, volume keys, media buttons, and
  * transport controls.
@@ -80,7 +83,7 @@
  * backwards compatible fashion.
  */
 public class MediaSessionCompat {
-    private static final String TAG = "MediaSessionCompat";
+    static final String TAG = "MediaSessionCompat";
 
     private final MediaSessionImpl mImpl;
     private final MediaControllerCompat mController;
@@ -89,6 +92,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef(flag=true, value={FLAG_HANDLES_MEDIA_BUTTONS, FLAG_HANDLES_TRANSPORT_CONTROLS})
     @Retention(RetentionPolicy.SOURCE)
     public @interface SessionFlags {}
@@ -163,7 +167,7 @@
     private static final int MAX_BITMAP_SIZE_IN_DP = 320;
 
     // Maximum size of the bitmap in px. It shouldn't be changed.
-    private static int sMaxBitmapSize;
+    static int sMaxBitmapSize;
 
     /**
      * Creates a new session. You must call {@link #release()} when finished with the session.
@@ -522,6 +526,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public String getCallingPackage() {
         return mImpl.getCallingPackage();
     }
@@ -773,6 +778,9 @@
 
         private class StubApi21 implements MediaSessionCompatApi21.Callback {
 
+            StubApi21() {
+            }
+
             @Override
             public void onCommand(String command, Bundle extras, ResultReceiver cb) {
                 Callback.this.onCommand(command, extras, cb);
@@ -871,6 +879,9 @@
 
         private class StubApi23 extends StubApi21 implements MediaSessionCompatApi23.Callback {
 
+            StubApi23() {
+            }
+
             @Override
             public void onPlayFromUri(Uri uri, Bundle extras) {
                 Callback.this.onPlayFromUri(uri, extras);
@@ -879,6 +890,9 @@
 
         private class StubApi24 extends StubApi23 implements MediaSessionCompatApi24.Callback {
 
+            StubApi24() {
+            }
+
             @Override
             public void onPrepare() {
                 Callback.this.onPrepare();
@@ -1043,7 +1057,7 @@
             mItem = queueItem;
         }
 
-        private QueueItem(Parcel in) {
+        QueueItem(Parcel in) {
             mDescription = MediaDescriptionCompat.CREATOR.createFromParcel(in);
             mId = in.readLong();
         }
@@ -1252,34 +1266,34 @@
         private final Object mRccObj;
         private final MediaSessionStub mStub;
         private final Token mToken;
-        private final String mPackageName;
-        private final String mTag;
-        private final AudioManager mAudioManager;
+        final String mPackageName;
+        final String mTag;
+        final AudioManager mAudioManager;
 
-        private final Object mLock = new Object();
-        private final RemoteCallbackList<IMediaControllerCallback> mControllerCallbacks
+        final Object mLock = new Object();
+        final RemoteCallbackList<IMediaControllerCallback> mControllerCallbacks
                 = new RemoteCallbackList<>();
 
         private MessageHandler mHandler;
-        private boolean mDestroyed = false;
+        boolean mDestroyed = false;
         private boolean mIsActive = false;
         private boolean mIsRccRegistered = false;
         private boolean mIsMbrRegistered = false;
-        private volatile Callback mCallback;
+        volatile Callback mCallback;
 
-        private @SessionFlags int mFlags;
+        @SessionFlags int mFlags;
 
-        private MediaMetadataCompat mMetadata;
-        private PlaybackStateCompat mState;
-        private PendingIntent mSessionActivity;
-        private List<QueueItem> mQueue;
-        private CharSequence mQueueTitle;
-        private @RatingCompat.Style int mRatingType;
-        private Bundle mExtras;
+        MediaMetadataCompat mMetadata;
+        PlaybackStateCompat mState;
+        PendingIntent mSessionActivity;
+        List<QueueItem> mQueue;
+        CharSequence mQueueTitle;
+        @RatingCompat.Style int mRatingType;
+        Bundle mExtras;
 
-        private int mVolumeType;
-        private int mLocalStream;
-        private VolumeProviderCompat mVolumeProvider;
+        int mVolumeType;
+        int mLocalStream;
+        VolumeProviderCompat mVolumeProvider;
 
         private VolumeProviderCompat.Callback mVolumeCallback
                 = new VolumeProviderCompat.Callback() {
@@ -1381,15 +1395,15 @@
             }
         }
 
-        private void postToHandler(int what) {
+        void postToHandler(int what) {
             postToHandler(what, null);
         }
 
-        private void postToHandler(int what, Object obj) {
+        void postToHandler(int what, Object obj) {
             postToHandler(what, obj, null);
         }
 
-        private void postToHandler(int what, Object obj, Bundle extras) {
+        void postToHandler(int what, Object obj, Bundle extras) {
             synchronized (mLock) {
                 if (mHandler != null) {
                     mHandler.post(what, obj, extras);
@@ -1653,7 +1667,7 @@
             return registeredRcc;
         }
 
-        private void adjustVolume(int direction, int flags) {
+        void adjustVolume(int direction, int flags) {
             if (mVolumeType == MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
                 if (mVolumeProvider != null) {
                     mVolumeProvider.onAdjustVolume(direction);
@@ -1663,7 +1677,7 @@
             }
         }
 
-        private void setVolumeTo(int value, int flags) {
+        void setVolumeTo(int value, int flags) {
             if (mVolumeType == MediaControllerCompat.PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
                 if (mVolumeProvider != null) {
                     mVolumeProvider.onSetVolumeTo(value);
@@ -1673,7 +1687,7 @@
             }
         }
 
-        private PlaybackStateCompat getStateWithUpdatedPosition() {
+        PlaybackStateCompat getStateWithUpdatedPosition() {
             PlaybackStateCompat state;
             long duration = -1;
             synchronized (mLock) {
@@ -1710,7 +1724,7 @@
             return result == null ? state : result;
         }
 
-        private void sendVolumeInfoChanged(ParcelableVolumeInfo info) {
+        void sendVolumeInfoChanged(ParcelableVolumeInfo info) {
             int size = mControllerCallbacks.beginBroadcast();
             for (int i = size - 1; i >= 0; i--) {
                 IMediaControllerCallback cb = mControllerCallbacks.getBroadcastItem(i);
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 51f248b..f23d0fa 100644
--- a/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
+++ b/media-compat/java/android/support/v4/media/session/PlaybackStateCompat.java
@@ -23,6 +23,7 @@
 import android.os.SystemClock;
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.text.TextUtils;
 import android.view.KeyEvent;
 
@@ -31,6 +32,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Playback state for a {@link MediaSessionCompat}. This includes a state like
  * {@link PlaybackStateCompat#STATE_PLAYING}, the current playback position,
@@ -41,6 +44,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef(flag=true, value={ACTION_STOP, ACTION_PAUSE, ACTION_PLAY, ACTION_REWIND,
             ACTION_SKIP_TO_PREVIOUS, ACTION_SKIP_TO_NEXT, ACTION_FAST_FORWARD, ACTION_SET_RATING,
             ACTION_SEEK_TO, ACTION_PLAY_PAUSE, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH,
@@ -52,6 +56,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef({ACTION_STOP, ACTION_PAUSE, ACTION_PLAY, ACTION_REWIND, ACTION_SKIP_TO_PREVIOUS,
             ACTION_SKIP_TO_NEXT, ACTION_FAST_FORWARD, ACTION_PLAY_PAUSE})
     @Retention(RetentionPolicy.SOURCE)
@@ -186,6 +191,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @IntDef({STATE_NONE, STATE_STOPPED, STATE_PAUSED, STATE_PLAYING, STATE_FAST_FORWARDING,
             STATE_REWINDING, STATE_BUFFERING, STATE_ERROR, STATE_CONNECTING,
             STATE_SKIPPING_TO_PREVIOUS, STATE_SKIPPING_TO_NEXT, STATE_SKIPPING_TO_QUEUE_ITEM})
@@ -337,20 +343,20 @@
         return KeyEvent.KEYCODE_UNKNOWN;
     }
 
-    private final int mState;
-    private final long mPosition;
-    private final long mBufferedPosition;
-    private final float mSpeed;
-    private final long mActions;
-    private final CharSequence mErrorMessage;
-    private final long mUpdateTime;
-    private List<PlaybackStateCompat.CustomAction> mCustomActions;
-    private final long mActiveItemId;
-    private final Bundle mExtras;
+    final int mState;
+    final long mPosition;
+    final long mBufferedPosition;
+    final float mSpeed;
+    final long mActions;
+    final CharSequence mErrorMessage;
+    final long mUpdateTime;
+    List<PlaybackStateCompat.CustomAction> mCustomActions;
+    final long mActiveItemId;
+    final Bundle mExtras;
 
     private Object mStateObj;
 
-    private PlaybackStateCompat(int state, long position, long bufferedPosition,
+    PlaybackStateCompat(int state, long position, long bufferedPosition,
             float rate, long actions, CharSequence errorMessage, long updateTime,
             List<PlaybackStateCompat.CustomAction> customActions,
             long activeItemId, Bundle extras) {
@@ -366,7 +372,7 @@
         mExtras = extras;
     }
 
-    private PlaybackStateCompat(Parcel in) {
+    PlaybackStateCompat(Parcel in) {
         mState = in.readInt();
         mPosition = in.readLong();
         mSpeed = in.readFloat();
@@ -638,14 +644,14 @@
         /**
          * Use {@link PlaybackStateCompat.CustomAction.Builder#build()}.
          */
-        private CustomAction(String action, CharSequence name, int icon, Bundle extras) {
+        CustomAction(String action, CharSequence name, int icon, Bundle extras) {
             mAction = action;
             mName = name;
             mIcon = icon;
             mExtras = extras;
         }
 
-        private CustomAction(Parcel in) {
+        CustomAction(Parcel in) {
             mAction = in.readString();
             mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
             mIcon = in.readInt();
diff --git a/samples/Support13Demos/src/com/example/android/supportv13/app/ActionBarTabsPager.java b/samples/Support13Demos/src/com/example/android/supportv13/app/ActionBarTabsPager.java
index 301a2f8..1bf7691 100644
--- a/samples/Support13Demos/src/com/example/android/supportv13/app/ActionBarTabsPager.java
+++ b/samples/Support13Demos/src/com/example/android/supportv13/app/ActionBarTabsPager.java
@@ -103,7 +103,7 @@
             mActionBar = activity.getActionBar();
             mViewPager = pager;
             mViewPager.setAdapter(this);
-            mViewPager.setOnPageChangeListener(this);
+            mViewPager.addOnPageChangeListener(this);
         }
 
         public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
diff --git a/samples/Support13Demos/src/com/example/android/supportv13/app/FragmentNestingPagerSupport.java b/samples/Support13Demos/src/com/example/android/supportv13/app/FragmentNestingPagerSupport.java
index 0a88a05..3896d9a 100644
--- a/samples/Support13Demos/src/com/example/android/supportv13/app/FragmentNestingPagerSupport.java
+++ b/samples/Support13Demos/src/com/example/android/supportv13/app/FragmentNestingPagerSupport.java
@@ -101,7 +101,7 @@
             mActionBar = activity.getActionBar();
             mViewPager = pager;
             mViewPager.setAdapter(this);
-            mViewPager.setOnPageChangeListener(this);
+            mViewPager.addOnPageChangeListener(this);
         }
 
         public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) {
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/accessibility/AccessibilityManagerSupportActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/accessibility/AccessibilityManagerSupportActivity.java
index 4be078b..8c9d40c 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/accessibility/AccessibilityManagerSupportActivity.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/accessibility/AccessibilityManagerSupportActivity.java
@@ -23,7 +23,6 @@
 import android.os.Bundle;
 import android.support.v4.accessibilityservice.AccessibilityServiceInfoCompat;
 import android.support.v4.view.accessibility.AccessibilityManagerCompat;
-import android.support.v4.view.accessibility.AccessibilityManagerCompat.AccessibilityStateChangeListenerCompat;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -85,7 +84,7 @@
         // platform API version is lower and the called API is not available no listener
         // is added and you will not receive a call of onAccessibilityStateChanged.
         AccessibilityManagerCompat.addAccessibilityStateChangeListener(mAccessibilityManager,
-                new AccessibilityStateChangeListenerCompat() {
+                new AccessibilityManagerCompat.AccessibilityStateChangeListener() {
             @Override
             public void onAccessibilityStateChanged(boolean enabled) {
                 Toast.makeText(AccessibilityManagerSupportActivity.this,
@@ -119,7 +118,8 @@
                         R.string.accessibility_manager_enabled_service,
                         resolveInfo.loadLabel(getPackageManager()),
                         AccessibilityServiceInfoCompat.feedbackTypeToString(service.feedbackType),
-                        AccessibilityServiceInfoCompat.getDescription(service),
+                        AccessibilityServiceInfoCompat.loadDescription(
+                                service, getPackageManager()),
                         AccessibilityServiceInfoCompat.getSettingsActivityName(service));
                 builder.append(serviceDescription);
             }
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentArgumentsSupport.java b/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentArgumentsSupport.java
index 8def8af..a9f4439 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentArgumentsSupport.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentArgumentsSupport.java
@@ -16,21 +16,22 @@
 
 package com.example.android.supportv4.app;
 
-import com.example.android.supportv4.R;
-
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-
-import android.app.Activity;
+import android.content.Context;
 import android.content.res.TypedArray;
 import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+import android.support.v4.content.ContextCompat;
+import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
+import com.example.android.supportv4.R;
+
 /**
  * Demonstrates a fragment that can be configured through both Bundle arguments
  * and layout attributes.
@@ -71,11 +72,11 @@
          * Parse attributes during inflation from a view hierarchy into the
          * arguments we handle.
          */
-        @Override public void onInflate(Activity activity, AttributeSet attrs,
-                Bundle savedInstanceState) {
-            super.onInflate(activity, attrs, savedInstanceState);
+        @Override
+        public void onInflate(Context context, AttributeSet attrs, Bundle savedInstanceState) {
+            super.onInflate(context, attrs, savedInstanceState);
 
-            TypedArray a = activity.obtainStyledAttributes(attrs,
+            TypedArray a = context.obtainStyledAttributes(attrs,
                     R.styleable.FragmentArguments);
             mLabel = a.getText(R.styleable.FragmentArguments_android_label);
             a.recycle();
@@ -85,7 +86,8 @@
          * During creation, if arguments have been supplied to the fragment
          * then parse those out.
          */
-        @Override public void onCreate(Bundle savedInstanceState) {
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
 
             Bundle args = getArguments();
@@ -100,12 +102,14 @@
         /**
          * Create the view for this fragment, using the arguments given to it.
          */
-        @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                 Bundle savedInstanceState) {
             View v = inflater.inflate(R.layout.hello_world, container, false);
             View tv = v.findViewById(R.id.text);
             ((TextView)tv).setText(mLabel != null ? mLabel : "(no label)");
-            tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+            ViewCompat.setBackground(
+                    tv, ContextCompat.getDrawable(getContext(), android.R.drawable.gallery_thumb));
             return v;
         }
     }
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.java b/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.java
index cf734d7..66a1b2d 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.java
@@ -15,8 +15,6 @@
  */
 package com.example.android.supportv4.app;
 
-import com.example.android.supportv4.R;
-
 import android.content.Context;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
@@ -28,6 +26,8 @@
 import android.widget.TabHost;
 import android.widget.TabWidget;
 
+import com.example.android.supportv4.R;
+
 import java.util.ArrayList;
 
 /**
@@ -125,7 +125,7 @@
             mViewPager = pager;
             mTabHost.setOnTabChangedListener(this);
             mViewPager.setAdapter(this);
-            mViewPager.setOnPageChangeListener(this);
+            mViewPager.addOnPageChangeListener(this);
         }
 
         public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/app/LoaderCustomSupport.java b/samples/Support4Demos/src/com/example/android/supportv4/app/LoaderCustomSupport.java
index 312aba4..d858fae 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/app/LoaderCustomSupport.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/app/LoaderCustomSupport.java
@@ -37,8 +37,6 @@
 import android.support.v4.content.pm.ActivityInfoCompat;
 import android.support.v4.view.MenuItemCompat;
 import android.support.v4.widget.SearchViewCompat;
-import android.support.v4.widget.SearchViewCompat.OnCloseListenerCompat;
-import android.support.v4.widget.SearchViewCompat.OnQueryTextListenerCompat;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -411,8 +409,6 @@
         // If non-null, this is the current filter the user has provided.
         String mCurFilter;
 
-        OnQueryTextListenerCompat mOnQueryTextListenerCompat;
-
         @Override public void onActivityCreated(Bundle savedInstanceState) {
             super.onActivityCreated(savedInstanceState);
 
@@ -444,18 +440,23 @@
             final View searchView = SearchViewCompat.newSearchView(getActivity());
             if (searchView != null) {
                 SearchViewCompat.setOnQueryTextListener(searchView,
-                        new OnQueryTextListenerCompat() {
-                    @Override
-                    public boolean onQueryTextChange(String newText) {
-                        // Called when the action bar search text has changed.  Since this
-                        // is a simple array adapter, we can just have it do the filtering.
-                        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
-                        mAdapter.getFilter().filter(mCurFilter);
-                        return true;
-                    }
-                });
+                        new SearchViewCompat.OnQueryTextListener() {
+                            @Override
+                            public boolean onQueryTextChange(String newText) {
+                                // Called when the action bar search text has changed.  Since this
+                                // is a simple array adapter, we can just have it do the filtering.
+                                mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+                                mAdapter.getFilter().filter(mCurFilter);
+                                return true;
+                            }
+
+                            @Override
+                            public boolean onQueryTextSubmit(String query) {
+                                return false;
+                            }
+                        });
                 SearchViewCompat.setOnCloseListener(searchView,
-                        new OnCloseListenerCompat() {
+                        new SearchViewCompat.OnCloseListener() {
                             @Override
                             public boolean onClose() {
                                 if (!TextUtils.isEmpty(SearchViewCompat.getQuery(searchView))) {
@@ -463,8 +464,7 @@
                                 }
                                 return true;
                             }
-                    
-                });
+                        });
                 MenuItemCompat.setActionView(item, searchView);
             }
         }
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java b/samples/Support4Demos/src/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
index f26e038..b408349 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
+++ b/samples/Support4Demos/src/com/example/android/supportv4/widget/SlidingPaneLayoutActivity.java
@@ -29,8 +29,9 @@
 import android.widget.ArrayAdapter;
 import android.widget.ListView;
 import android.widget.TextView;
-import com.example.android.supportv4.Shakespeare;
+
 import com.example.android.supportv4.R;
+import com.example.android.supportv4.Shakespeare;
 
 /**
  * This example illustrates a common usage of SlidingPaneLayout in the Android support library.
@@ -98,7 +99,7 @@
          * as the left pane contains content one level up in the navigation hierarchy.
          */
         if (item.getItemId() == android.R.id.home && !mSlidingLayout.isOpen()) {
-            mSlidingLayout.smoothSlideOpen();
+            mSlidingLayout.openPane();
             return true;
         }
         return super.onOptionsItemSelected(item);
@@ -114,7 +115,7 @@
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
             mContent.setText(Shakespeare.DIALOGUE[position]);
             mActionBar.setTitle(Shakespeare.TITLES[position]);
-            mSlidingLayout.smoothSlideClosed();
+            mSlidingLayout.closePane();
         }
     }
 
@@ -206,7 +207,7 @@
 
         @Override
         public void onFirstLayout() {
-            if (mSlidingLayout.canSlide() && !mSlidingLayout.isOpen()) {
+            if (mSlidingLayout.isSlideable() && !mSlidingLayout.isOpen()) {
                 onPanelClosed();
             } else {
                 onPanelOpened();
diff --git a/samples/Support7Demos/AndroidManifest.xml b/samples/Support7Demos/AndroidManifest.xml
index 066afc3..a26d7fb 100644
--- a/samples/Support7Demos/AndroidManifest.xml
+++ b/samples/Support7Demos/AndroidManifest.xml
@@ -173,18 +173,9 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".app.ActionBarTabs"
-                android:label="@string/action_bar_tabs"
-                android:theme="@style/Theme.Custom">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
         <activity android:name=".app.ActionBarSettingsActionProviderActivity"
-                android:label="@string/action_bar_settings_action_provider"
-                android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
+                  android:label="@string/action_bar_settings_action_provider"
+                  android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
@@ -389,8 +380,17 @@
         </activity>
 
         <activity android:name=".widget.LinearLayoutManagerActivity"
-                  android:label="@string/linear_layout_manager"
-                  android:theme="@style/Theme.AppCompat">
+            android:label="@string/linear_layout_manager"
+            android:theme="@style/Theme.AppCompat">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".widget.LinearLayoutManagerJankActivity"
+            android:label="@string/linear_layout_manager"
+            android:theme="@style/Theme.AppCompat">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="com.example.android.supportv7.SAMPLE_CODE" />
diff --git a/samples/Support7Demos/res/layout/action_bar_display_options.xml b/samples/Support7Demos/res/layout/action_bar_display_options.xml
index 2efb7c2..e335e27 100644
--- a/samples/Support7Demos/res/layout/action_bar_display_options.xml
+++ b/samples/Support7Demos/res/layout/action_bar_display_options.xml
@@ -39,10 +39,6 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:text="@string/toggle_show_custom" />
-        <Button android:id="@+id/toggle_navigation"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/toggle_navigation" />
         <Button android:id="@+id/cycle_custom_gravity"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
diff --git a/samples/Support7Demos/res/values/strings.xml b/samples/Support7Demos/res/values/strings.xml
index 4bf046e..ad87a6a 100644
--- a/samples/Support7Demos/res/values/strings.xml
+++ b/samples/Support7Demos/res/values/strings.xml
@@ -144,6 +144,9 @@
     <string name="enableAnimations">Animate</string>
     <string name="enablePredictiveAnimations">Predictive</string>
     <string name="enableInPlaceChange">In Place Change</string>
+    <string name="enable_inflate_slowdown">Slow inflate</string>
+    <string name="enable_bind_slowdown">Slow bind</string>
+    <string name="enable_prefetch">Prefetch</string>
     <string name="add_item">Add</string>
     <string name="delete_item">Del</string>
     <string name="add_delete_item">A+D</string>
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarDisplayOptions.java b/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarDisplayOptions.java
index d4eef84..7c39a2b 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarDisplayOptions.java
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarDisplayOptions.java
@@ -15,8 +15,6 @@
  */
 package com.example.android.supportv7.app;
 
-import com.example.android.supportv7.R;
-
 import android.os.Bundle;
 import android.support.v4.app.FragmentTransaction;
 import android.support.v7.app.ActionBar;
@@ -27,9 +25,8 @@
 import android.view.View;
 import android.view.ViewGroup.LayoutParams;
 import android.widget.ArrayAdapter;
-import android.widget.Toast;
 
-;
+import com.example.android.supportv7.R;
 
 /**
  * This demo shows how various action bar display option flags can be combined and their effects.
@@ -49,7 +46,6 @@
         findViewById(R.id.toggle_use_logo).setOnClickListener(this);
         findViewById(R.id.toggle_show_title).setOnClickListener(this);
         findViewById(R.id.toggle_show_custom).setOnClickListener(this);
-        findViewById(R.id.toggle_navigation).setOnClickListener(this);
         findViewById(R.id.cycle_custom_gravity).setOnClickListener(this);
         findViewById(R.id.toggle_visibility).setOnClickListener(this);
 
@@ -60,22 +56,10 @@
 
         final ActionBar bar = getSupportActionBar();
         bar.setCustomView(mCustomView, mCustomViewLayoutParams);
-        bar.addTab(bar.newTab().setText("Tab 1").setTabListener(this));
-        bar.addTab(bar.newTab().setText("Tab 2").setTabListener(this));
-        bar.addTab(bar.newTab().setText("Tab 3").setTabListener(this));
 
         final ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(bar.getThemedContext(),
                 R.layout.support_simple_spinner_dropdown_item,
                 new String[] { "Item 1", "Item 2", "Item 3" });
-        bar.setListNavigationCallbacks(listAdapter, new ActionBar.OnNavigationListener() {
-            @Override
-            public boolean onNavigationItemSelected(int itemPosition, long itemId) {
-                Toast.makeText(ActionBarDisplayOptions.this,
-                        listAdapter.getItem(itemPosition),
-                        Toast.LENGTH_SHORT).show();
-                return true;
-            }
-        });
 
         bar.setLogo(R.drawable.ic_media_play);
     }
@@ -112,19 +96,6 @@
             case R.id.toggle_show_custom:
                 flags = ActionBar.DISPLAY_SHOW_CUSTOM;
                 break;
-            case R.id.toggle_navigation:
-                switch (bar.getNavigationMode()) {
-                    case ActionBar.NAVIGATION_MODE_STANDARD:
-                        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-                        break;
-                    case ActionBar.NAVIGATION_MODE_TABS:
-                        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
-                        break;
-                    case ActionBar.NAVIGATION_MODE_LIST:
-                        bar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-                        break;
-                }
-                return;
             case R.id.cycle_custom_gravity: {
                 ActionBar.LayoutParams lp = mCustomViewLayoutParams;
                 int newGravity = 0;
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarTabs.java b/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarTabs.java
deleted file mode 100644
index a8c87f4..0000000
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/ActionBarTabs.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.example.android.supportv7.app;
-
-import com.example.android.supportv7.R;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentTransaction;
-import android.support.v7.app.ActionBar;
-import android.support.v7.app.ActionBar.Tab;
-import android.support.v7.app.AppCompatActivity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-import android.widget.Toast;
-
-/**
- * This demonstrates the use of action bar tabs and how they interact
- * with other action bar features.
- */
-public class ActionBarTabs extends AppCompatActivity {
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.action_bar_tabs);
-    }
-
-    public void onAddTab(View v) {
-        final ActionBar bar = getSupportActionBar();
-        final int tabCount = bar.getTabCount();
-        final String text = "Tab " + tabCount;
-        bar.addTab(bar.newTab()
-                .setText(text)
-                .setTabListener(new TabListener(new TabContentFragment(text))));
-    }
-
-    public void onRemoveTab(View v) {
-        final ActionBar bar = getSupportActionBar();
-        if (bar.getTabCount() > 0) {
-            bar.removeTabAt(bar.getTabCount() - 1);
-        }
-    }
-
-    public void onToggleTabs(View v) {
-        final ActionBar bar = getSupportActionBar();
-
-        if (bar.getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) {
-            bar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-        } else {
-            bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-        }
-    }
-
-    public void onRemoveAllTabs(View v) {
-        getSupportActionBar().removeAllTabs();
-    }
-
-    /**
-     * A TabListener receives event callbacks from the action bar as tabs
-     * are deselected, selected, and reselected. A FragmentTransaction
-     * is provided to each of these callbacks; if any operations are added
-     * to it, it will be committed at the end of the full tab switch operation.
-     * This lets tab switches be atomic without the app needing to track
-     * the interactions between different tabs.
-     *
-     * NOTE: This is a very simple implementation that does not retain
-     * fragment state of the non-visible tabs across activity instances.
-     * Look at the FragmentTabs example for how to do a more complete
-     * implementation.
-     */
-    private class TabListener implements ActionBar.TabListener {
-        private TabContentFragment mFragment;
-
-        public TabListener(TabContentFragment fragment) {
-            mFragment = fragment;
-        }
-
-        @Override
-        public void onTabSelected(Tab tab, FragmentTransaction ft) {
-            ft.add(R.id.fragment_content, mFragment, mFragment.getText());
-        }
-
-        @Override
-        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
-            ft.remove(mFragment);
-        }
-
-        @Override
-        public void onTabReselected(Tab tab, FragmentTransaction ft) {
-            Toast.makeText(ActionBarTabs.this, "Reselected!", Toast.LENGTH_SHORT).show();
-        }
-
-    }
-
-    private class TabContentFragment extends Fragment {
-        private String mText;
-
-        public TabContentFragment(String text) {
-            mText = text;
-        }
-
-        public String getText() {
-            return mText;
-        }
-
-        @Override
-        public View onCreateView(LayoutInflater inflater, ViewGroup container,
-                Bundle savedInstanceState) {
-            View fragView = inflater.inflate(R.layout.action_bar_tab_content, container, false);
-
-            TextView text = (TextView) fragView.findViewById(R.id.text);
-            text.setText(mText);
-
-            return fragView;
-        }
-    }
-}
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/app/_index.html b/samples/Support7Demos/src/com/example/android/supportv7/app/_index.html
index c316d1b..dc190ef 100644
--- a/samples/Support7Demos/src/com/example/android/supportv7/app/_index.html
+++ b/samples/Support7Demos/src/com/example/android/supportv7/app/_index.html
@@ -13,11 +13,6 @@
 menu. This demo is for informative purposes only; see Usage for an example of using the
 Action Bar in a more idiomatic manner.</dd>
 
-  <dt><a href="ActionBarTabs.html">Action Bar Tabs</a></dt>
-  <dd>Demonstrates the use of Action Bar tabs and how they interact with other action bar
-features.  Also see the <a href="FragmentTabs.html">Fragment Tabs</a> for a more
-complete example of how to switch between fragments.</dd>
-
   <dt><a href="ActionBarUsage.html">Action Bar Usage</a></dt>
   <dd>Demonstrates simple usage of the Action Bar, including a SearchView as an action item. The
 default Honeycomb theme includes the Action Bar by default and a menu resource is used to populate
diff --git a/samples/Support7Demos/src/com/example/android/supportv7/widget/LinearLayoutManagerJankActivity.java b/samples/Support7Demos/src/com/example/android/supportv7/widget/LinearLayoutManagerJankActivity.java
new file mode 100644
index 0000000..1709d3e
--- /dev/null
+++ b/samples/Support7Demos/src/com/example/android/supportv7/widget/LinearLayoutManagerJankActivity.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.supportv7.widget;
+
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.ViewGroup;
+
+import com.example.android.supportv7.Cheeses;
+import com.example.android.supportv7.R;
+import com.example.android.supportv7.widget.adapter.SimpleStringAdapter;
+import com.example.android.supportv7.widget.util.ConfigToggle;
+
+/**
+ * A configurably janky activity that uses {@link LinearLayoutManager}.
+ */
+public class LinearLayoutManagerJankActivity extends LinearLayoutManagerActivity {
+
+    private boolean mBindSlowdownEnabled = true;
+    private boolean mInflateSlowdownEnabled = true;
+
+    /**
+     * Spin wait. Used instead of sleeping so a core is used up for the duration, and so
+     * traces/sampled profiling show the sections as expensive, and not just a scheduling mistake.
+     */
+    private static void spinWaitMs(long ms) {
+        long start = System.nanoTime();
+        while (System.nanoTime() - start < ms * 1000L * 1000L);
+    }
+
+    @Override
+    protected RecyclerView.Adapter createAdapter() {
+        return new SimpleStringAdapter(this, Cheeses.sCheeseStrings) {
+            @Override
+            public void onBindViewHolder(ViewHolder holder, int position) {
+                super.onBindViewHolder(holder, position);
+                if (mBindSlowdownEnabled) spinWaitMs(8);
+            }
+
+            @Override
+            public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+                if (mInflateSlowdownEnabled) spinWaitMs(4);
+                return super.onCreateViewHolder(parent, viewType);
+            }
+        };
+    }
+
+    @Override
+    ConfigToggle[] createConfigToggles() {
+        return new ConfigToggle[]{
+                new ConfigToggle(this, R.string.enable_bind_slowdown) {
+                    @Override
+                    public boolean isChecked() { return mBindSlowdownEnabled; }
+
+                    @Override
+                    public void onChange(boolean newValue) { mBindSlowdownEnabled = newValue; }
+                },
+                new ConfigToggle(this, R.string.enable_inflate_slowdown) {
+                    @Override
+                    public boolean isChecked() { return mInflateSlowdownEnabled; }
+
+                    @Override
+                    public void onChange(boolean newValue) { mInflateSlowdownEnabled = newValue; }
+                },
+                new ConfigToggle(this, R.string.enable_prefetch) {
+                    @Override
+                    public boolean isChecked() { return mLayoutManager.isItemPrefetchEnabled(); }
+
+                    @Override
+                    public void onChange(boolean newValue) {
+                        mLayoutManager.setItemPrefetchEnabled(newValue);
+                    }
+                },
+        };
+    }
+}
diff --git a/samples/SupportDesignDemos/Android.mk b/samples/SupportDesignDemos/Android.mk
index de9e302..8ae120e 100644
--- a/samples/SupportDesignDemos/Android.mk
+++ b/samples/SupportDesignDemos/Android.mk
@@ -28,16 +28,19 @@
         android-support-v4 \
         android-support-v7-appcompat \
         android-support-v7-recyclerview \
+        android-support-transition \
         android-support-design
 LOCAL_RESOURCE_DIR = \
         $(LOCAL_PATH)/res \
         frameworks/support/v7/appcompat/res \
         frameworks/support/v7/recyclerview/res \
+        frameworks/support/transition/res \
         frameworks/support/design/res
 LOCAL_AAPT_FLAGS := \
         --auto-add-overlay \
         --extra-packages android.support.v7.appcompat \
         --extra-packages android.support.v7.recyclerview \
+        --extra-packages android.support.transition \
         --extra-packages android.support.design \
         --no-version-vectors
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
diff --git a/samples/SupportDesignDemos/res/layout/design_bottom_navigation_view.xml b/samples/SupportDesignDemos/res/layout/design_bottom_navigation_view.xml
index b21ba3b..83e7314 100644
--- a/samples/SupportDesignDemos/res/layout/design_bottom_navigation_view.xml
+++ b/samples/SupportDesignDemos/res/layout/design_bottom_navigation_view.xml
@@ -14,7 +14,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout
+<RelativeLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         android:layout_width="match_parent"
@@ -30,15 +30,22 @@
         android:id="@+id/button_add"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginTop="50dp"
-        android:text="@string/bottomnavigation_add"/>
+        android:text="@string/bottomnavigation_add"
+        android:layout_below="@+id/button_disable"/>
+
+    <Button
+        android:id="@+id/button_remove"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/bottomnavigation_remove"
+        android:layout_below="@+id/button_add"/>
 
     <Button
         android:id="@+id/button_tint"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_marginTop="100dp"
-        android:text="@string/bottomnavigation_tint"/>
+        android:text="@string/bottomnavigation_tint"
+        android:layout_below="@+id/button_remove"/>
 
     <android.support.design.widget.BottomNavigationView
             android:id="@+id/bottom_navigation"
@@ -46,6 +53,7 @@
             android:layout_height="56dp"
             android:layout_gravity="bottom"
             android:background="#eee"
+            android:layout_alignParentBottom="true"
             app:menu="@menu/sample_bottom_menu"/>
 
-</FrameLayout>
+</RelativeLayout>
diff --git a/samples/SupportDesignDemos/res/values/strings.xml b/samples/SupportDesignDemos/res/values/strings.xml
index a6a1bc9..95900ca 100644
--- a/samples/SupportDesignDemos/res/values/strings.xml
+++ b/samples/SupportDesignDemos/res/values/strings.xml
@@ -124,6 +124,7 @@
     <string name="design_bottom_navigation_view">Bottom navigation view</string>
 
     <string name="bottomnavigation_disable">Disable item</string>
-    <string name="bottomnavigation_add">Add item</string>
+    <string name="bottomnavigation_add">Add an item</string>
+    <string name="bottomnavigation_remove">Remove an item</string>
     <string name="bottomnavigation_tint">Toggle tint</string>
 </resources>
diff --git a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomNavigationViewUsage.java b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomNavigationViewUsage.java
index fce3c3b..72b50db 100644
--- a/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomNavigationViewUsage.java
+++ b/samples/SupportDesignDemos/src/com/example/android/support/design/widget/BottomNavigationViewUsage.java
@@ -50,8 +50,17 @@
         buttonAdd.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View view) {
-                MenuItem item = bottom.getMenu().add("Bananas");
-                item.setIcon(android.R.drawable.ic_lock_power_off);
+                if (bottom.getMenu().size() < 5) {
+                    MenuItem item = bottom.getMenu().add("Bananas");
+                    item.setIcon(android.R.drawable.ic_lock_power_off);
+                }
+            }
+        });
+        Button buttonRemove = (Button) findViewById(R.id.button_remove);
+        buttonRemove.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                bottom.getMenu().removeItem(0);
             }
         });
         Button buttonTint = (Button) findViewById(R.id.button_tint);
diff --git a/transition/ics/android/support/transition/TransitionIcs.java b/transition/ics/android/support/transition/TransitionIcs.java
index 6a78a18..8cd5fae 100644
--- a/transition/ics/android/support/transition/TransitionIcs.java
+++ b/transition/ics/android/support/transition/TransitionIcs.java
@@ -234,6 +234,9 @@
 
         private final ArrayList<TransitionInterfaceListener> mListeners = new ArrayList<>();
 
+        CompatListener() {
+        }
+
         public void addListener(TransitionInterfaceListener listener) {
             mListeners.add(listener);
         }
diff --git a/transition/ics/android/support/transition/TransitionManagerPort.java b/transition/ics/android/support/transition/TransitionManagerPort.java
index d6ca154..47eaff0 100644
--- a/transition/ics/android/support/transition/TransitionManagerPort.java
+++ b/transition/ics/android/support/transition/TransitionManagerPort.java
@@ -16,6 +16,7 @@
 
 package android.support.transition;
 
+import android.support.annotation.RestrictTo;
 import android.support.v4.util.ArrayMap;
 import android.support.v4.view.ViewCompat;
 import android.util.Log;
@@ -26,6 +27,8 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 class TransitionManagerPort {
     // TODO: how to handle enter/exit?
 
@@ -38,7 +41,7 @@
     private static ThreadLocal<WeakReference<ArrayMap<ViewGroup, ArrayList<TransitionPort>>>>
             sRunningTransitions = new ThreadLocal<>();
 
-    private static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<>();
+    static ArrayList<ViewGroup> sPendingTransitions = new ArrayList<>();
 
     ArrayMap<ScenePort, TransitionPort> mSceneTransitions = new ArrayMap<>();
 
@@ -57,6 +60,7 @@
      * @hide pending later changes
      * @see #setDefaultTransition(TransitionPort)
      */
+    @RestrictTo(GROUP_ID)
     public static TransitionPort getDefaultTransition() {
         return sDefaultTransition;
     }
@@ -69,6 +73,7 @@
      * @param transition The default transition to be used for scene changes.
      * @hide pending later changes
      */
+    @RestrictTo(GROUP_ID)
     public void setDefaultTransition(TransitionPort transition) {
         sDefaultTransition = transition;
     }
@@ -105,7 +110,7 @@
         sceneChangeRunTransition(sceneRoot, transitionClone);
     }
 
-    private static ArrayMap<ViewGroup, ArrayList<TransitionPort>> getRunningTransitions() {
+    static ArrayMap<ViewGroup, ArrayList<TransitionPort>> getRunningTransitions() {
         WeakReference<ArrayMap<ViewGroup, ArrayList<TransitionPort>>> runningTransitions =
                 sRunningTransitions.get();
         if (runningTransitions == null || runningTransitions.get() == null) {
diff --git a/transition/ics/android/support/transition/TransitionPort.java b/transition/ics/android/support/transition/TransitionPort.java
index f6c3346..516f93b 100644
--- a/transition/ics/android/support/transition/TransitionPort.java
+++ b/transition/ics/android/support/transition/TransitionPort.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.TimeInterpolator;
+import android.support.annotation.RestrictTo;
 import android.support.v4.util.ArrayMap;
 import android.support.v4.util.LongSparseArray;
 import android.util.Log;
@@ -30,6 +31,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 abstract class TransitionPort implements Cloneable {
 
     static final boolean DBG = false;
@@ -99,7 +102,7 @@
 
     // Track all animators in use in case the transition gets canceled and needs to
     // cancel running animators
-    private ArrayList<Animator> mCurrentAnimators = new ArrayList<>();
+    ArrayList<Animator> mCurrentAnimators = new ArrayList<>();
 
     // Whether this transition has ended. Used to avoid pause/resume on transitions
     // that have completed
@@ -171,6 +174,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
             TransitionValuesMaps endValues) {
         if (DBG) {
@@ -406,6 +410,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void runAnimators() {
         if (DBG) {
             Log.d(LOG_TAG, "runAnimators() on " + this);
@@ -789,6 +794,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void pause(View sceneRoot) {
         if (!mEnded) {
             ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
@@ -820,6 +826,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void resume(View sceneRoot) {
         if (mPaused) {
             if (!mEnded) {
@@ -918,6 +925,7 @@
      * @param animator The Animator to be run during this transition.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void animate(Animator animator) {
         // TODO: maybe pass auto-end as a boolean parameter?
         if (animator == null) {
@@ -950,6 +958,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void start() {
         if (mNumInstances == 0) {
             if (mListeners != null && mListeners.size() > 0) {
@@ -976,6 +985,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void end() {
         --mNumInstances;
         if (mNumInstances == 0) {
@@ -1010,6 +1020,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void cancel() {
         int numAnimators = mCurrentAnimators.size();
         for (int i = numAnimators - 1; i >= 0; i--) {
@@ -1182,6 +1193,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class TransitionListenerAdapter implements TransitionListener {
 
         @Override
diff --git a/transition/ics/android/support/transition/TransitionSetPort.java b/transition/ics/android/support/transition/TransitionSetPort.java
index 97985a5..a834bca 100644
--- a/transition/ics/android/support/transition/TransitionSetPort.java
+++ b/transition/ics/android/support/transition/TransitionSetPort.java
@@ -17,12 +17,15 @@
 package android.support.transition;
 
 import android.animation.TimeInterpolator;
+import android.support.annotation.RestrictTo;
 import android.util.AndroidRuntimeException;
 import android.view.View;
 import android.view.ViewGroup;
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 class TransitionSetPort extends TransitionPort {
 
     /**
@@ -162,6 +165,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     protected void createAnimators(ViewGroup sceneRoot, TransitionValuesMaps startValues,
             TransitionValuesMaps endValues) {
@@ -173,6 +177,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     protected void runAnimators() {
         if (mTransitions.isEmpty()) {
@@ -231,6 +236,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public void pause(View sceneRoot) {
         super.pause(sceneRoot);
@@ -241,6 +247,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public void resume(View sceneRoot) {
         super.resume(sceneRoot);
@@ -251,6 +258,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     protected void cancel() {
         super.cancel();
diff --git a/transition/ics/android/support/transition/ViewOverlay.java b/transition/ics/android/support/transition/ViewOverlay.java
index 9cea400..ef6793c 100644
--- a/transition/ics/android/support/transition/ViewOverlay.java
+++ b/transition/ics/android/support/transition/ViewOverlay.java
@@ -21,6 +21,7 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.view.MotionEvent;
 import android.view.View;
@@ -31,6 +32,8 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 class ViewOverlay {
 
     /**
@@ -323,6 +326,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         protected ViewParent invalidateChildInParentFast(int left, int top, Rect dirty) {
             if (mHostView instanceof ViewGroup && sInvalidateChildInParentFastMethod != null) {
                 try {
diff --git a/transition/ics/android/support/transition/VisibilityPort.java b/transition/ics/android/support/transition/VisibilityPort.java
index afbf6fe..ebe5cb8 100644
--- a/transition/ics/android/support/transition/VisibilityPort.java
+++ b/transition/ics/android/support/transition/VisibilityPort.java
@@ -226,5 +226,8 @@
         ViewGroup startParent;
 
         ViewGroup endParent;
+
+        VisibilityInfo() {
+        }
     }
 }
diff --git a/transition/kitkat/android/support/transition/TransitionKitKat.java b/transition/kitkat/android/support/transition/TransitionKitKat.java
index 78e4b76..e9e60e5 100644
--- a/transition/kitkat/android/support/transition/TransitionKitKat.java
+++ b/transition/kitkat/android/support/transition/TransitionKitKat.java
@@ -325,15 +325,18 @@
 
         private final ArrayList<TransitionInterfaceListener> mListeners = new ArrayList<>();
 
-        private void addListener(TransitionInterfaceListener listener) {
+        CompatListener() {
+        }
+
+        void addListener(TransitionInterfaceListener listener) {
             mListeners.add(listener);
         }
 
-        private void removeListener(TransitionInterfaceListener listener) {
+        void removeListener(TransitionInterfaceListener listener) {
             mListeners.remove(listener);
         }
 
-        private boolean isEmpty() {
+        boolean isEmpty() {
             return mListeners.isEmpty();
         }
 
diff --git a/v13/java/android/support/v13/app/FragmentTabHost.java b/v13/java/android/support/v13/app/FragmentTabHost.java
index c010b4f..6cfd0ad 100644
--- a/v13/java/android/support/v13/app/FragmentTabHost.java
+++ b/v13/java/android/support/v13/app/FragmentTabHost.java
@@ -51,10 +51,10 @@
     private boolean mAttached;
 
     static final class TabInfo {
-        private final String tag;
-        private final Class<?> clss;
-        private final Bundle args;
-        private Fragment fragment;
+        final String tag;
+        final Class<?> clss;
+        final Bundle args;
+        Fragment fragment;
 
         TabInfo(String _tag, Class<?> _class, Bundle _args) {
             tag = _tag;
@@ -86,7 +86,7 @@
             super(superState);
         }
 
-        private SavedState(Parcel in) {
+        SavedState(Parcel in) {
             super(in);
             curTab = in.readString();
         }
diff --git a/v13/java/android/support/v13/view/DragAndDropPermissionsCompat.java b/v13/java/android/support/v13/view/DragAndDropPermissionsCompat.java
index 4ade66f..4f5d9d8 100644
--- a/v13/java/android/support/v13/view/DragAndDropPermissionsCompat.java
+++ b/v13/java/android/support/v13/view/DragAndDropPermissionsCompat.java
@@ -17,9 +17,12 @@
 package android.support.v13.view;
 
 import android.app.Activity;
+import android.support.annotation.RestrictTo;
 import android.support.v4.os.BuildCompat;
 import android.view.DragEvent;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for accessing features in {@link android.view.DragAndDropPermissions}
  * introduced after API level 13 in a backwards compatible fashion.
@@ -72,6 +75,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public static DragAndDropPermissionsCompat request(Activity activity, DragEvent dragEvent) {
         Object dragAndDropPermissions = IMPL.request(activity, dragEvent);
         if (dragAndDropPermissions != null) {
diff --git a/v13/java/android/support/v13/view/ViewCompat.java b/v13/java/android/support/v13/view/ViewCompat.java
index 38db5fa..971d70d 100644
--- a/v13/java/android/support/v13/view/ViewCompat.java
+++ b/v13/java/android/support/v13/view/ViewCompat.java
@@ -33,6 +33,9 @@
     }
 
     private static class BaseViewCompatImpl implements ViewCompatImpl {
+        BaseViewCompatImpl() {
+        }
+
         @Override
         public boolean startDragAndDrop(View v, ClipData data, View.DragShadowBuilder shadowBuilder,
                 Object localState, int flags) {
@@ -51,6 +54,9 @@
     }
 
     private static class Api24ViewCompatImpl implements ViewCompatImpl {
+        Api24ViewCompatImpl() {
+        }
+
         @Override
         public boolean startDragAndDrop(View v, ClipData data, View.DragShadowBuilder shadowBuilder,
                 Object localState, int flags) {
diff --git a/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java
index 4f64876..829f29b 100644
--- a/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java
+++ b/v14/preference/src/android/support/v14/preference/EditTextPreferenceDialogFragment.java
@@ -18,10 +18,13 @@
 
 import android.os.Bundle;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v7.preference.EditTextPreference;
 import android.view.View;
 import android.widget.EditText;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 public class EditTextPreferenceDialogFragment extends PreferenceDialogFragment {
 
     private static final String SAVE_STATE_TEXT = "EditTextPreferenceDialogFragment.text";
@@ -74,6 +77,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     protected boolean needInputMethod() {
         // We want the input method to show, if possible, when dialog is displayed
diff --git a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
index cb3ebc3..284b9aa 100644
--- a/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
+++ b/v14/preference/src/android/support/v14/preference/MultiSelectListPreference.java
@@ -23,6 +23,7 @@
 import android.os.Parcelable;
 import android.support.annotation.ArrayRes;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.SharedPreferencesCompat;
 import android.support.v4.content.res.TypedArrayUtils;
 import android.support.v7.preference.internal.AbstractMultiSelectListPreference;
@@ -32,6 +33,8 @@
 import java.util.HashSet;
 import java.util.Set;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link android.support.v7.preference.Preference} that displays a list of entries as
  * a dialog.
@@ -96,6 +99,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected boolean persistStringSet(Set<String> values) {
         if (shouldPersist()) {
             // Shouldn't store null
@@ -128,6 +132,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected Set<String> getPersistedStringSet(Set<String> defaultReturnValue) {
         if (!shouldPersist()) {
             return defaultReturnValue;
diff --git a/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java b/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java
index 48b404e..c05f427 100644
--- a/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java
+++ b/v14/preference/src/android/support/v14/preference/PreferenceDialogFragment.java
@@ -29,6 +29,7 @@
 import android.os.Bundle;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v7.preference.DialogPreference;
 import android.text.TextUtils;
 import android.view.LayoutInflater;
@@ -37,6 +38,8 @@
 import android.view.WindowManager;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Abstract base class which presents a dialog associated with a
  * {@link android.support.v7.preference.DialogPreference}. Since the preference object may
@@ -192,6 +195,7 @@
      * the soft input method brought up automatically.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected boolean needInputMethod() {
         return false;
     }
diff --git a/v14/preference/src/android/support/v14/preference/PreferenceFragment.java b/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
index 2d090b2..2904cae 100644
--- a/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
+++ b/v14/preference/src/android/support/v14/preference/PreferenceFragment.java
@@ -27,6 +27,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.XmlRes;
 import android.support.v4.content.res.TypedArrayUtils;
 import android.support.v4.view.ViewCompat;
@@ -49,6 +50,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Shows a hierarchy of {@link Preference} objects as
  * lists. These preferences will
@@ -552,10 +555,12 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     protected void onBindPreferences() {
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     protected void onUnbindPreferences() {
     }
 
@@ -658,6 +663,7 @@
      * @return Fragment to possibly use as a callback
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public Fragment getCallbackFragment() {
         return null;
     }
diff --git a/v14/preference/src/android/support/v14/preference/SwitchPreference.java b/v14/preference/src/android/support/v14/preference/SwitchPreference.java
index 6e4b0d7..1d6bbaf 100644
--- a/v14/preference/src/android/support/v14/preference/SwitchPreference.java
+++ b/v14/preference/src/android/support/v14/preference/SwitchPreference.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.TypedArrayUtils;
 import android.support.v7.preference.AndroidResources;
 import android.support.v7.preference.PreferenceViewHolder;
@@ -29,6 +30,8 @@
 import android.widget.CompoundButton;
 import android.widget.Switch;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link android.support.v7.preference.Preference} that provides a two-state toggleable option.
  * <p>
@@ -203,6 +206,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     protected void performClick(View view) {
         super.performClick(view);
diff --git a/v17/leanback/Android.mk b/v17/leanback/Android.mk
index 9d5d940..14b02ab 100644
--- a/v17/leanback/Android.mk
+++ b/v17/leanback/Android.mk
@@ -37,6 +37,8 @@
 LOCAL_SDK_VERSION := 17
 LOCAL_SRC_FILES := $(call all-java-files-under, common)
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+LOCAL_SHARED_ANDROID_LIBRARIES := \
+    android-support-annotations
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # -----------------------------------------------------------------------
@@ -48,6 +50,8 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, api23)
 LOCAL_JAVA_LIBRARIES := android-support-v17-leanback-res android-support-v17-leanback-common
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+LOCAL_SHARED_ANDROID_LIBRARIES := \
+    android-support-annotations
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # -----------------------------------------------------------------------
@@ -59,6 +63,8 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, api21)
 LOCAL_JAVA_LIBRARIES := android-support-v17-leanback-res android-support-v17-leanback-common
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+LOCAL_SHARED_ANDROID_LIBRARIES := \
+    android-support-annotations
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # -----------------------------------------------------------------------
@@ -70,6 +76,8 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, kitkat)
 LOCAL_JAVA_LIBRARIES := android-support-v17-leanback-res android-support-v17-leanback-common
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+LOCAL_SHARED_ANDROID_LIBRARIES := \
+    android-support-annotations
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # -----------------------------------------------------------------------
@@ -81,6 +89,8 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, jbmr2)
 LOCAL_JAVA_LIBRARIES := android-support-v17-leanback-res android-support-v17-leanback-common
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
+LOCAL_SHARED_ANDROID_LIBRARIES := \
+    android-support-annotations
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 # -----------------------------------------------------------------------
@@ -91,7 +101,8 @@
 #   LOCAL_STATIC_ANDROID_LIBRARIES := \
 #       android-support-v17-leanback \
 #       android-support-v7-recyclerview \
-#       android-support-v4
+#       android-support-v4 \
+#       android-support-annotations
 #
 # in their makefiles to include the resources and their dependencies in their package.
 include $(CLEAR_VARS)
@@ -110,7 +121,8 @@
     android-support-v17-leanback-res
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-v7-recyclerview \
-    android-support-v4
+    android-support-v4 \
+    android-support-annotations
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
@@ -122,6 +134,7 @@
     $(call all-java-files-under, src) \
     $(call all-html-files-under, src)
 leanback.docs.java_libraries := \
+    android-support-annotations \
     android-support-v4 \
     android-support-v7-recyclerview \
     android-support-v17-leanback-res \
diff --git a/v17/leanback/api21/android/support/v17/leanback/transition/FadeAndShortSlide.java b/v17/leanback/api21/android/support/v17/leanback/transition/FadeAndShortSlide.java
index 224d062..3cfc94f 100644
--- a/v17/leanback/api21/android/support/v17/leanback/transition/FadeAndShortSlide.java
+++ b/v17/leanback/api21/android/support/v17/leanback/transition/FadeAndShortSlide.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.transition.Fade;
 import android.transition.Transition;
@@ -32,10 +33,13 @@
 import android.view.ViewGroup;
 import android.view.animation.DecelerateInterpolator;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Execute horizontal slide of 1/4 width and fade (to workaround bug 23718734)
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class FadeAndShortSlide extends Visibility {
 
     private static final TimeInterpolator sDecelerate = new DecelerateInterpolator();
@@ -49,6 +53,9 @@
 
     private static abstract class CalculateSlide {
 
+        CalculateSlide() {
+        }
+
         /** Returns the translation X value for view when it goes out of the scene */
         float getGoneX(FadeAndShortSlide t, ViewGroup sceneRoot, View view, int[] position) {
             return view.getTranslationX();
diff --git a/v17/leanback/api21/android/support/v17/leanback/transition/SlideNoPropagation.java b/v17/leanback/api21/android/support/v17/leanback/transition/SlideNoPropagation.java
index ddff13c..866b904 100644
--- a/v17/leanback/api21/android/support/v17/leanback/transition/SlideNoPropagation.java
+++ b/v17/leanback/api21/android/support/v17/leanback/transition/SlideNoPropagation.java
@@ -14,12 +14,16 @@
 package android.support.v17.leanback.transition;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.transition.Slide;
 import android.util.AttributeSet;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class SlideNoPropagation extends Slide {
 
     public SlideNoPropagation() {
diff --git a/v17/leanback/api21/android/support/v17/leanback/transition/TranslationAnimationCreator.java b/v17/leanback/api21/android/support/v17/leanback/transition/TranslationAnimationCreator.java
index 46068da..a423995 100644
--- a/v17/leanback/api21/android/support/v17/leanback/transition/TranslationAnimationCreator.java
+++ b/v17/leanback/api21/android/support/v17/leanback/transition/TranslationAnimationCreator.java
@@ -1,5 +1,6 @@
 package android.support.v17.leanback.transition;
 
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 
 import android.animation.Animator;
@@ -12,12 +13,15 @@
 import android.transition.Transition.TransitionListener;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This class is used by Slide and Explode to create an animator that goes from the start
  * position to the end position. It takes into account the canceled position so that it
  * will not blink out or shift suddenly when the transition is interrupted.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 class TranslationAnimationCreator {
 
     /**
@@ -83,7 +87,7 @@
         private final float mTerminalX;
         private final float mTerminalY;
 
-        private TransitionPositionListener(View movingView, View viewInHierarchy,
+        TransitionPositionListener(View movingView, View viewInHierarchy,
                 int startX, int startY, float terminalX, float terminalY) {
             mMovingView = movingView;
             mViewInHierarchy = viewInHierarchy;
diff --git a/v17/leanback/common/android/support/v17/leanback/transition/TransitionListener.java b/v17/leanback/common/android/support/v17/leanback/transition/TransitionListener.java
index 6a4056e..b1a4a08 100644
--- a/v17/leanback/common/android/support/v17/leanback/transition/TransitionListener.java
+++ b/v17/leanback/common/android/support/v17/leanback/transition/TransitionListener.java
@@ -13,10 +13,15 @@
  */
 package android.support.v17.leanback.transition;
 
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Listeners for transition start and stop.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class TransitionListener {
 
     protected Object mImpl;
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/transition/Scale.java b/v17/leanback/kitkat/android/support/v17/leanback/transition/Scale.java
index 28acbbd..2bdc3aa 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/transition/Scale.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/transition/Scale.java
@@ -22,9 +22,6 @@
 import android.transition.Transition;
 import android.transition.TransitionValues;
 
-/**
- * @hide
- */
 class Scale extends Transition {
     private static final String PROPNAME_SCALE = "android:leanback:scale";
 
diff --git a/v17/leanback/kitkat/android/support/v17/leanback/transition/SlideKitkat.java b/v17/leanback/kitkat/android/support/v17/leanback/transition/SlideKitkat.java
index a1f2d63..686c4fa 100644
--- a/v17/leanback/kitkat/android/support/v17/leanback/transition/SlideKitkat.java
+++ b/v17/leanback/kitkat/android/support/v17/leanback/transition/SlideKitkat.java
@@ -41,7 +41,6 @@
 /**
  * Slide distance toward/from a edge.
  * This is a limited Slide implementation for KitKat without propagation support.
- * @hide
  */
 class SlideKitkat extends Visibility {
     private static final String TAG = "SlideKitkat";
@@ -64,6 +63,9 @@
     }
 
     private static abstract class CalculateSlideHorizontal implements CalculateSlide {
+        CalculateSlideHorizontal() {
+        }
+
         @Override
         public float getHere(View view) {
             return view.getTranslationX();
@@ -76,6 +78,9 @@
     }
 
     private static abstract class CalculateSlideVertical implements CalculateSlide {
+        CalculateSlideVertical() {
+        }
+
         @Override
         public float getHere(View view) {
             return view.getTranslationY();
diff --git a/v17/leanback/res/values-bs-rBA/strings.xml b/v17/leanback/res/values-bs-rBA/strings.xml
index 63a76e2..cdfe434 100644
--- a/v17/leanback/res/values-bs-rBA/strings.xml
+++ b/v17/leanback/res/values-bs-rBA/strings.xml
@@ -53,5 +53,5 @@
     <string name="lb_date_separator" msgid="2440386660906697298">"/"</string>
     <string name="lb_time_separator" msgid="2763247350845477227">":"</string>
     <string name="lb_onboarding_get_started" msgid="6961440391306351139">"ZAPOÄŒNITE"</string>
-    <string name="lb_onboarding_accessibility_next" msgid="2918313444257732434">"Naprijed"</string>
+    <string name="lb_onboarding_accessibility_next" msgid="2918313444257732434">"Sljedeća"</string>
 </resources>
diff --git a/v17/leanback/src/android/support/v17/leanback/animation/LogAccelerateInterpolator.java b/v17/leanback/src/android/support/v17/leanback/animation/LogAccelerateInterpolator.java
index 5ebfe57..4b98f44 100644
--- a/v17/leanback/src/android/support/v17/leanback/animation/LogAccelerateInterpolator.java
+++ b/v17/leanback/src/android/support/v17/leanback/animation/LogAccelerateInterpolator.java
@@ -14,10 +14,14 @@
 package android.support.v17.leanback.animation;
 
 import android.animation.TimeInterpolator;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class LogAccelerateInterpolator implements TimeInterpolator {
 
     int mBase;
diff --git a/v17/leanback/src/android/support/v17/leanback/animation/LogDecelerateInterpolator.java b/v17/leanback/src/android/support/v17/leanback/animation/LogDecelerateInterpolator.java
index 9c9b552..d9a4282 100644
--- a/v17/leanback/src/android/support/v17/leanback/animation/LogDecelerateInterpolator.java
+++ b/v17/leanback/src/android/support/v17/leanback/animation/LogDecelerateInterpolator.java
@@ -14,10 +14,14 @@
 package android.support.v17.leanback.animation;
 
 import android.animation.TimeInterpolator;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class LogDecelerateInterpolator implements TimeInterpolator {
 
     int mBase;
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BackgroundFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BackgroundFragment.java
index a58235b..d3547f3 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BackgroundFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BackgroundFragment.java
@@ -14,11 +14,15 @@
 package android.support.v17.leanback.app;
 
 import android.app.Fragment;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * Fragment used by the background manager.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class BackgroundFragment extends Fragment implements
         BackgroundManager.FragmentStateQueriable {
     private BackgroundManager mBackgroundManager;
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BackgroundManager.java b/v17/leanback/src/android/support/v17/leanback/app/BackgroundManager.java
index 1b10741..0c490ea 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BackgroundManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BackgroundManager.java
@@ -88,10 +88,10 @@
         public boolean isResumed();
     }
 
-    private static final String TAG = "BackgroundManager";
-    private static final boolean DEBUG = false;
+    static final String TAG = "BackgroundManager";
+    static final boolean DEBUG = false;
 
-    private static final int FULL_ALPHA = 255;
+    static final int FULL_ALPHA = 255;
     private static final int DIM_ALPHA_ON_SOLID = (int) (0.8f * FULL_ALPHA);
     private static final int CHANGE_BG_DELAY_MS = 500;
     private static final int FADE_DURATION = 500;
@@ -106,8 +106,8 @@
     private static final String WINDOW_NAME = "BackgroundManager";
     private static final String FRAGMENT_TAG = BackgroundManager.class.getCanonicalName();
 
-    private Context mContext;
-    private Handler mHandler;
+    Context mContext;
+    Handler mHandler;
     private Window mWindow;
     private WindowManager mWindowManager;
     private View mBgView;
@@ -117,7 +117,7 @@
 
     private int mHeightPx;
     private int mWidthPx;
-    private Drawable mBackgroundDrawable;
+    Drawable mBackgroundDrawable;
     private int mBackgroundColor;
     private boolean mAttached;
     private long mLastSetTime;
@@ -205,7 +205,7 @@
         }
     }
 
-    private static class DrawableWrapper {
+    static class DrawableWrapper {
         private int mAlpha = FULL_ALPHA;
         private Drawable mDrawable;
         private ColorFilter mColorFilter;
@@ -439,9 +439,9 @@
         return result;
     }
 
-    private TranslucentLayerDrawable mLayerDrawable;
+    TranslucentLayerDrawable mLayerDrawable;
     private Drawable mDimDrawable;
-    private ChangeBackgroundRunnable mChangeRunnable;
+    ChangeBackgroundRunnable mChangeRunnable;
     private boolean mChangeRunnablePending;
 
     private final Animator.AnimatorListener mAnimationListener = new Animator.AnimatorListener() {
@@ -690,17 +690,17 @@
         mFragmentState = fragment;
     }
 
-    private DrawableWrapper getImageInWrapper() {
+    DrawableWrapper getImageInWrapper() {
         return mLayerDrawable == null ? null :
                 mLayerDrawable.findWrapperById(R.id.background_imagein);
     }
 
-    private DrawableWrapper getImageOutWrapper() {
+    DrawableWrapper getImageOutWrapper() {
         return mLayerDrawable == null ? null :
                 mLayerDrawable.findWrapperById(R.id.background_imageout);
     }
 
-    private DrawableWrapper getDimWrapper() {
+    DrawableWrapper getDimWrapper() {
         return mLayerDrawable == null ? null :
                 mLayerDrawable.findWrapperById(R.id.background_dim);
     }
@@ -835,7 +835,6 @@
     /**
      * Release references to Drawables and put the BackgroundManager into the
      * detached state. Called when the associated Activity is destroyed.
-     * @hide
      */
     void detach() {
         if (DEBUG) Log.v(TAG, "detach " + this);
@@ -880,11 +879,11 @@
         releaseBackgroundBitmap();
     }
 
-    private void releaseBackgroundBitmap() {
+    void releaseBackgroundBitmap() {
         mBackgroundDrawable = null;
     }
 
-    private void setBackgroundDrawable(Drawable drawable) {
+    void setBackgroundDrawable(Drawable drawable) {
         mBackgroundDrawable = drawable;
         mService.setDrawable(mBackgroundDrawable);
     }
@@ -911,7 +910,7 @@
         return ContextCompat.getDrawable(mContext, R.color.lb_background_protection);
     }
 
-    private void postChangeRunnable() {
+    void postChangeRunnable() {
         if (mChangeRunnable == null || !mChangeRunnablePending) {
             return;
         }
@@ -1076,7 +1075,7 @@
         setDrawableInternal(bitmapDrawable);
     }
 
-    private void applyBackgroundChanges() {
+    void applyBackgroundChanges() {
         if (!mAttached) {
             return;
         }
@@ -1129,7 +1128,7 @@
         return mBackgroundDrawable;
     }
 
-    private boolean sameDrawable(Drawable first, Drawable second) {
+    boolean sameDrawable(Drawable first, Drawable second) {
         if (first == null || second == null) {
             return false;
         }
@@ -1148,7 +1147,7 @@
      * Task which changes the background.
      */
     class ChangeBackgroundRunnable implements Runnable {
-        private Drawable mDrawable;
+        Drawable mDrawable;
 
         ChangeBackgroundRunnable(Drawable drawable) {
             mDrawable = drawable;
@@ -1188,7 +1187,7 @@
         }
     }
 
-    private static Drawable createEmptyDrawable(Context context) {
+    static Drawable createEmptyDrawable(Context context) {
         Bitmap bitmap = null;
         return new BitmapDrawable(context.getResources(), bitmap);
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BackgroundSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BackgroundSupportFragment.java
index c430a34..72cb5a1 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BackgroundSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BackgroundSupportFragment.java
@@ -15,12 +15,16 @@
  */
 package android.support.v17.leanback.app;
 
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.Fragment;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Fragment used by the background manager.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class BackgroundSupportFragment extends Fragment implements
         BackgroundManager.FragmentStateQueriable {
     private BackgroundManager mBackgroundManager;
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 d298e20..0f6aae3 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseFragment.java
@@ -81,8 +81,8 @@
 
     final StateMachine mEnterTransitionStates;
 
-    private Object mEntranceTransition;
-    private final ProgressBarManager mProgressBarManager = new ProgressBarManager();
+    Object mEntranceTransition;
+    final ProgressBarManager mProgressBarManager = new ProgressBarManager();
 
     BaseFragment() {
         mEnterTransitionStates = new StateMachine();
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseRowFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseRowFragment.java
index 2ddea53..c9489d1 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseRowFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseRowFragment.java
@@ -33,10 +33,10 @@
 abstract class BaseRowFragment extends Fragment {
     private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition";
     private ObjectAdapter mAdapter;
-    private VerticalGridView mVerticalGridView;
+    VerticalGridView mVerticalGridView;
     private PresenterSelector mPresenterSelector;
-    private ItemBridgeAdapter mBridgeAdapter;
-    private int mSelectedPosition = -1;
+    ItemBridgeAdapter mBridgeAdapter;
+    int mSelectedPosition = -1;
     private boolean mPendingTransitionPrepare;
     private LateSelectionObserver mLateSelectionObserver = new LateSelectionObserver();
 
@@ -90,6 +90,9 @@
     private class LateSelectionObserver extends RecyclerView.AdapterDataObserver {
         boolean mIsLateSelection = false;
 
+        LateSelectionObserver() {
+        }
+
         @Override
         public void onChanged() {
             performLateSelection();
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BaseRowSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BaseRowSupportFragment.java
index 847eb57..6fc741d 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseRowSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseRowSupportFragment.java
@@ -35,10 +35,10 @@
 abstract class BaseRowSupportFragment extends Fragment {
     private static final String CURRENT_SELECTED_POSITION = "currentSelectedPosition";
     private ObjectAdapter mAdapter;
-    private VerticalGridView mVerticalGridView;
+    VerticalGridView mVerticalGridView;
     private PresenterSelector mPresenterSelector;
-    private ItemBridgeAdapter mBridgeAdapter;
-    private int mSelectedPosition = -1;
+    ItemBridgeAdapter mBridgeAdapter;
+    int mSelectedPosition = -1;
     private boolean mPendingTransitionPrepare;
     private LateSelectionObserver mLateSelectionObserver = new LateSelectionObserver();
 
@@ -92,6 +92,9 @@
     private class LateSelectionObserver extends RecyclerView.AdapterDataObserver {
         boolean mIsLateSelection = false;
 
+        LateSelectionObserver() {
+        }
+
         @Override
         public void onChanged() {
             performLateSelection();
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 5322195..8a818e0 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BaseSupportFragment.java
@@ -83,8 +83,8 @@
 
     final StateMachine mEnterTransitionStates;
 
-    private Object mEntranceTransition;
-    private final ProgressBarManager mProgressBarManager = new ProgressBarManager();
+    Object mEntranceTransition;
+    final ProgressBarManager mProgressBarManager = new ProgressBarManager();
 
     BaseSupportFragment() {
         mEnterTransitionStates = new StateMachine();
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 fa3aae3..0f7cfa0 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
@@ -253,6 +253,9 @@
         boolean mShowTitleView = true;
         boolean mDataReady = false;
 
+        FragmentHostImpl() {
+        }
+
         @Override
         public void notifyViewCreated(MainFragmentAdapter fragmentAdapter) {
             performPendingStates();
@@ -320,7 +323,7 @@
     public static class MainFragmentAdapter<T extends Fragment> {
         private boolean mScalingEnabled;
         private final T mFragment;
-        private FragmentHostImpl mFragmentHost;
+        FragmentHostImpl mFragmentHost;
 
         public MainFragmentAdapter(T fragment) {
             this.mFragment = fragment;
@@ -592,11 +595,11 @@
         }
     }
 
-    private static final String TAG = "BrowseFragment";
+    static final String TAG = "BrowseFragment";
 
     private static final String LB_HEADERS_BACKSTACK = "lbHeadersBackStack_";
 
-    private static boolean DEBUG = false;
+    static boolean DEBUG = false;
 
     /** The headers fragment is enabled and shown by default. */
     public static final int HEADERS_ENABLED = 1;
@@ -609,9 +612,9 @@
 
     private MainFragmentAdapterRegistry mMainFragmentAdapterRegistry
             = new MainFragmentAdapterRegistry();
-    private MainFragmentAdapter mMainFragmentAdapter;
-    private Fragment mMainFragment;
-    private HeadersFragment mHeadersFragment;
+    MainFragmentAdapter mMainFragmentAdapter;
+    Fragment mMainFragment;
+    HeadersFragment mHeadersFragment;
     private MainFragmentRowsAdapter mMainFragmentRowsAdapter;
 
     private ObjectAdapter mAdapter;
@@ -622,31 +625,31 @@
     private int mBrandColor = Color.TRANSPARENT;
     private boolean mBrandColorSet;
 
-    private BrowseFrameLayout mBrowseFrame;
+    BrowseFrameLayout mBrowseFrame;
     private ScaleFrameLayout mScaleFrameLayout;
-    private boolean mHeadersBackStackEnabled = true;
-    private String mWithHeadersBackStackName;
-    private boolean mShowingHeaders = true;
-    private boolean mCanShowHeaders = true;
+    boolean mHeadersBackStackEnabled = true;
+    String mWithHeadersBackStackName;
+    boolean mShowingHeaders = true;
+    boolean mCanShowHeaders = true;
     private int mContainerListMarginStart;
     private int mContainerListAlignTop;
     private boolean mMainFragmentScaleEnabled = true;
-    private OnItemViewSelectedListener mExternalOnItemViewSelectedListener;
+    OnItemViewSelectedListener mExternalOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
     private int mSelectedPosition = -1;
     private float mScaleFactor;
-    private boolean mIsPageRow;
+    boolean mIsPageRow;
 
     private PresenterSelector mHeaderPresenterSelector;
     private final SetSelectionRunnable mSetSelectionRunnable = new SetSelectionRunnable();
 
     // transition related:
-    private Object mSceneWithHeaders;
-    private Object mSceneWithoutHeaders;
+    Object mSceneWithHeaders;
+    Object mSceneWithoutHeaders;
     private Object mSceneAfterEntranceTransition;
-    private Object mHeadersTransition;
-    private BackStackListener mBackStackChangedListener;
-    private BrowseTransitionListener mBrowseTransitionListener;
+    Object mHeadersTransition;
+    BackStackListener mBackStackChangedListener;
+    BrowseTransitionListener mBrowseTransitionListener;
 
     private static final String ARG_TITLE = BrowseFragment.class.getCanonicalName() + ".title";
     private static final String ARG_HEADERS_STATE =
@@ -892,7 +895,7 @@
         mMainFragmentScaleEnabled = enable;
     }
 
-    private void startHeadersTransitionInternal(final boolean withHeaders) {
+    void startHeadersTransitionInternal(final boolean withHeaders) {
         if (getFragmentManager().isDestroyed()) {
             return;
         }
@@ -980,7 +983,7 @@
         }
     };
 
-    private final boolean isHeadersDataReady() {
+    final boolean isHeadersDataReady() {
         return mAdapter != null && mAdapter.size() != 0;
     }
 
@@ -1207,7 +1210,7 @@
                 && (!mIsPageRow || mMainFragmentAdapter.mFragmentHost.mDataReady);
     }
 
-    private void createHeadersTransition() {
+    void createHeadersTransition() {
         mHeadersTransition = TransitionHelper.loadTransition(getActivity(),
                 mShowingHeaders ?
                 R.transition.lb_browse_headers_in : R.transition.lb_browse_headers_out);
@@ -1332,7 +1335,7 @@
         containerList.setLayoutParams(lp);
     }
 
-    private void showHeaders(boolean show) {
+    void showHeaders(boolean show) {
         if (DEBUG) Log.v(TAG, "showHeaders " + show);
         mHeadersFragment.setHeadersEnabled(show);
         setHeadersOnScreen(show);
@@ -1395,14 +1398,14 @@
         }
     };
 
-    private void onRowSelected(int position) {
+    void onRowSelected(int position) {
         if (position != mSelectedPosition) {
             mSetSelectionRunnable.post(
                     position, SetSelectionRunnable.TYPE_INTERNAL_SYNC, true);
         }
     }
 
-    private void setSelection(int position, boolean smooth) {
+    void setSelection(int position, boolean smooth) {
         if (position == NO_POSITION) {
             return;
         }
@@ -1701,6 +1704,8 @@
         void execute() {
             mView.getViewTreeObserver().addOnPreDrawListener(this);
             mainFragmentAdapter.setExpand(false);
+            // always trigger onPreDraw even adapter setExpand() does nothing.
+            mView.invalidate();
             mState = STATE_INIT;
         }
 
@@ -1712,6 +1717,8 @@
             }
             if (mState == STATE_INIT) {
                 mainFragmentAdapter.setExpand(true);
+                // always trigger onPreDraw even adapter setExpand() does nothing.
+                mView.invalidate();
                 mState = STATE_FIRST_DRAW;
             } else if (mState == STATE_FIRST_DRAW) {
                 mCallback.run();
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 53d53a3..c88438e 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseSupportFragment.java
@@ -255,6 +255,9 @@
         boolean mShowTitleView = true;
         boolean mDataReady = false;
 
+        FragmentHostImpl() {
+        }
+
         @Override
         public void notifyViewCreated(MainFragmentAdapter fragmentAdapter) {
             performPendingStates();
@@ -322,7 +325,7 @@
     public static class MainFragmentAdapter<T extends Fragment> {
         private boolean mScalingEnabled;
         private final T mFragment;
-        private FragmentHostImpl mFragmentHost;
+        FragmentHostImpl mFragmentHost;
 
         public MainFragmentAdapter(T fragment) {
             this.mFragment = fragment;
@@ -594,11 +597,11 @@
         }
     }
 
-    private static final String TAG = "BrowseSupportFragment";
+    static final String TAG = "BrowseSupportFragment";
 
     private static final String LB_HEADERS_BACKSTACK = "lbHeadersBackStack_";
 
-    private static boolean DEBUG = false;
+    static boolean DEBUG = false;
 
     /** The headers fragment is enabled and shown by default. */
     public static final int HEADERS_ENABLED = 1;
@@ -611,9 +614,9 @@
 
     private MainFragmentAdapterRegistry mMainFragmentAdapterRegistry
             = new MainFragmentAdapterRegistry();
-    private MainFragmentAdapter mMainFragmentAdapter;
-    private Fragment mMainFragment;
-    private HeadersSupportFragment mHeadersSupportFragment;
+    MainFragmentAdapter mMainFragmentAdapter;
+    Fragment mMainFragment;
+    HeadersSupportFragment mHeadersSupportFragment;
     private MainFragmentRowsAdapter mMainFragmentRowsAdapter;
 
     private ObjectAdapter mAdapter;
@@ -624,31 +627,31 @@
     private int mBrandColor = Color.TRANSPARENT;
     private boolean mBrandColorSet;
 
-    private BrowseFrameLayout mBrowseFrame;
+    BrowseFrameLayout mBrowseFrame;
     private ScaleFrameLayout mScaleFrameLayout;
-    private boolean mHeadersBackStackEnabled = true;
-    private String mWithHeadersBackStackName;
-    private boolean mShowingHeaders = true;
-    private boolean mCanShowHeaders = true;
+    boolean mHeadersBackStackEnabled = true;
+    String mWithHeadersBackStackName;
+    boolean mShowingHeaders = true;
+    boolean mCanShowHeaders = true;
     private int mContainerListMarginStart;
     private int mContainerListAlignTop;
     private boolean mMainFragmentScaleEnabled = true;
-    private OnItemViewSelectedListener mExternalOnItemViewSelectedListener;
+    OnItemViewSelectedListener mExternalOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
     private int mSelectedPosition = -1;
     private float mScaleFactor;
-    private boolean mIsPageRow;
+    boolean mIsPageRow;
 
     private PresenterSelector mHeaderPresenterSelector;
     private final SetSelectionRunnable mSetSelectionRunnable = new SetSelectionRunnable();
 
     // transition related:
-    private Object mSceneWithHeaders;
-    private Object mSceneWithoutHeaders;
+    Object mSceneWithHeaders;
+    Object mSceneWithoutHeaders;
     private Object mSceneAfterEntranceTransition;
-    private Object mHeadersTransition;
-    private BackStackListener mBackStackChangedListener;
-    private BrowseTransitionListener mBrowseTransitionListener;
+    Object mHeadersTransition;
+    BackStackListener mBackStackChangedListener;
+    BrowseTransitionListener mBrowseTransitionListener;
 
     private static final String ARG_TITLE = BrowseSupportFragment.class.getCanonicalName() + ".title";
     private static final String ARG_HEADERS_STATE =
@@ -894,7 +897,7 @@
         mMainFragmentScaleEnabled = enable;
     }
 
-    private void startHeadersTransitionInternal(final boolean withHeaders) {
+    void startHeadersTransitionInternal(final boolean withHeaders) {
         if (getFragmentManager().isDestroyed()) {
             return;
         }
@@ -982,7 +985,7 @@
         }
     };
 
-    private final boolean isHeadersDataReady() {
+    final boolean isHeadersDataReady() {
         return mAdapter != null && mAdapter.size() != 0;
     }
 
@@ -1209,7 +1212,7 @@
                 && (!mIsPageRow || mMainFragmentAdapter.mFragmentHost.mDataReady);
     }
 
-    private void createHeadersTransition() {
+    void createHeadersTransition() {
         mHeadersTransition = TransitionHelper.loadTransition(getActivity(),
                 mShowingHeaders ?
                 R.transition.lb_browse_headers_in : R.transition.lb_browse_headers_out);
@@ -1334,7 +1337,7 @@
         containerList.setLayoutParams(lp);
     }
 
-    private void showHeaders(boolean show) {
+    void showHeaders(boolean show) {
         if (DEBUG) Log.v(TAG, "showHeaders " + show);
         mHeadersSupportFragment.setHeadersEnabled(show);
         setHeadersOnScreen(show);
@@ -1397,14 +1400,14 @@
         }
     };
 
-    private void onRowSelected(int position) {
+    void onRowSelected(int position) {
         if (position != mSelectedPosition) {
             mSetSelectionRunnable.post(
                     position, SetSelectionRunnable.TYPE_INTERNAL_SYNC, true);
         }
     }
 
-    private void setSelection(int position, boolean smooth) {
+    void setSelection(int position, boolean smooth) {
         if (position == NO_POSITION) {
             return;
         }
@@ -1703,6 +1706,8 @@
         void execute() {
             mView.getViewTreeObserver().addOnPreDrawListener(this);
             mainFragmentAdapter.setExpand(false);
+            // always trigger onPreDraw even adapter setExpand() does nothing.
+            mView.invalidate();
             mState = STATE_INIT;
         }
 
@@ -1714,6 +1719,8 @@
             }
             if (mState == STATE_INIT) {
                 mainFragmentAdapter.setExpand(true);
+                // always trigger onPreDraw even adapter setExpand() does nothing.
+                mView.invalidate();
                 mState = STATE_FIRST_DRAW;
             } else if (mState == STATE_FIRST_DRAW) {
                 mCallback.run();
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 1875683..ee733a6 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsFragment.java
@@ -69,13 +69,16 @@
  * </p>
  */
 public class DetailsFragment extends BaseFragment {
-    private static final String TAG = "DetailsFragment";
-    private static boolean DEBUG = false;
+    static final String TAG = "DetailsFragment";
+    static boolean DEBUG = false;
 
     private class SetSelectionRunnable implements Runnable {
         int mPosition;
         boolean mSmooth = true;
 
+        SetSelectionRunnable() {
+        }
+
         @Override
         public void run() {
             if (mRowsFragment == null) {
@@ -85,11 +88,11 @@
         }
     }
 
-    private RowsFragment mRowsFragment;
+    RowsFragment mRowsFragment;
 
     private ObjectAdapter mAdapter;
     private int mContainerListAlignTop;
-    private BaseOnItemViewSelectedListener mExternalOnItemViewSelectedListener;
+    BaseOnItemViewSelectedListener mExternalOnItemViewSelectedListener;
     private BaseOnItemViewClickedListener mOnItemViewClickedListener;
 
     private Object mSceneAfterEntranceTransition;
@@ -228,7 +231,7 @@
      * that setup should only change the Presenter behavior that is meaningful in DetailsFragment.  For
      * example how a row is aligned in details Fragment.   The default implementation invokes
      * {@link #setupDetailsOverviewRowPresenter(FullWidthDetailsOverviewRowPresenter)}
-     * 
+     *
      */
     protected void setupPresenter(Presenter rowPresenter) {
         if (rowPresenter instanceof FullWidthDetailsOverviewRowPresenter) {
@@ -310,7 +313,7 @@
         }
     }
 
-    private void onRowSelected(int selectedPosition, int selectedSubPosition) {
+    void onRowSelected(int selectedPosition, int selectedSubPosition) {
         ObjectAdapter adapter = getAdapter();
         if (adapter == null || adapter.size() == 0 ||
                 (selectedPosition == 0 && selectedSubPosition == 0)) {
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 8f69db2..af23da9 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/DetailsSupportFragment.java
@@ -71,13 +71,16 @@
  * </p>
  */
 public class DetailsSupportFragment extends BaseSupportFragment {
-    private static final String TAG = "DetailsSupportFragment";
-    private static boolean DEBUG = false;
+    static final String TAG = "DetailsSupportFragment";
+    static boolean DEBUG = false;
 
     private class SetSelectionRunnable implements Runnable {
         int mPosition;
         boolean mSmooth = true;
 
+        SetSelectionRunnable() {
+        }
+
         @Override
         public void run() {
             if (mRowsSupportFragment == null) {
@@ -87,11 +90,11 @@
         }
     }
 
-    private RowsSupportFragment mRowsSupportFragment;
+    RowsSupportFragment mRowsSupportFragment;
 
     private ObjectAdapter mAdapter;
     private int mContainerListAlignTop;
-    private BaseOnItemViewSelectedListener mExternalOnItemViewSelectedListener;
+    BaseOnItemViewSelectedListener mExternalOnItemViewSelectedListener;
     private BaseOnItemViewClickedListener mOnItemViewClickedListener;
 
     private Object mSceneAfterEntranceTransition;
@@ -230,7 +233,7 @@
      * that setup should only change the Presenter behavior that is meaningful in DetailsSupportFragment.  For
      * example how a row is aligned in details Fragment.   The default implementation invokes
      * {@link #setupDetailsOverviewRowPresenter(FullWidthDetailsOverviewRowPresenter)}
-     * 
+     *
      */
     protected void setupPresenter(Presenter rowPresenter) {
         if (rowPresenter instanceof FullWidthDetailsOverviewRowPresenter) {
@@ -312,7 +315,7 @@
         }
     }
 
-    private void onRowSelected(int selectedPosition, int selectedSubPosition) {
+    void onRowSelected(int selectedPosition, int selectedSubPosition) {
         ObjectAdapter adapter = getAdapter();
         if (adapter == null || adapter.size() == 0 ||
                 (selectedPosition == 0 && selectedSubPosition == 0)) {
diff --git a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepFragment.java b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepFragment.java
index 732e39d..73c9700 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepFragment.java
@@ -24,6 +24,7 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.widget.GuidanceStylist;
@@ -48,6 +49,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A GuidedStepFragment is used to guide the user through a decision or series of decisions.
  * It is composed of a guidance view on the left and a view on the right containing a list of
@@ -222,12 +225,14 @@
      * Animation to slide the contents from the side (left/right).
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final int SLIDE_FROM_SIDE = 0;
 
     /**
      * Animation to slide the contents from the bottom.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final int SLIDE_FROM_BOTTOM = 1;
 
     private static final String TAG = "GuidedStepFragment";
@@ -236,6 +241,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class DummyFragment extends Fragment {
         @Override
         public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -248,7 +254,7 @@
 
     private ContextThemeWrapper mThemeWrapper;
     private GuidanceStylist mGuidanceStylist;
-    private GuidedActionsStylist mActionsStylist;
+    GuidedActionsStylist mActionsStylist;
     private GuidedActionsStylist mButtonActionsStylist;
     private GuidedActionAdapter mAdapter;
     private GuidedActionAdapter mSubAdapter;
@@ -1309,6 +1315,7 @@
      * For now clients(subclasses) can call this method inside the constructor.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setEntranceTransitionType(int transitionType) {
       this.entranceTransitionType = transitionType;
     }
@@ -1360,7 +1367,7 @@
         return 0;
     }
 
-    private void runImeAnimations(boolean entering) {
+    void runImeAnimations(boolean entering) {
         ArrayList<Animator> animators = new ArrayList<Animator>();
         if (entering) {
             mGuidanceStylist.onImeAppearing(animators);
diff --git a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepRootLayout.java b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepRootLayout.java
index deb8160..6d05fd1 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepRootLayout.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepRootLayout.java
@@ -18,12 +18,10 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.widget.LinearLayout;
 
 /**
  * Utility class used by GuidedStepFragment to disable focus out left/right.
- * @hide
  */
 class GuidedStepRootLayout extends LinearLayout {
 
diff --git a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepSupportFragment.java
index 30ada02..f5b27df 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/GuidedStepSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/GuidedStepSupportFragment.java
@@ -17,6 +17,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
@@ -50,6 +51,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A GuidedStepSupportFragment is used to guide the user through a decision or series of decisions.
  * It is composed of a guidance view on the left and a view on the right containing a list of
@@ -224,12 +227,14 @@
      * Animation to slide the contents from the side (left/right).
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final int SLIDE_FROM_SIDE = 0;
 
     /**
      * Animation to slide the contents from the bottom.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static final int SLIDE_FROM_BOTTOM = 1;
 
     private static final String TAG = "GuidedStepSupportFragment";
@@ -238,6 +243,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class DummyFragment extends Fragment {
         @Override
         public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -250,7 +256,7 @@
 
     private ContextThemeWrapper mThemeWrapper;
     private GuidanceStylist mGuidanceStylist;
-    private GuidedActionsStylist mActionsStylist;
+    GuidedActionsStylist mActionsStylist;
     private GuidedActionsStylist mButtonActionsStylist;
     private GuidedActionAdapter mAdapter;
     private GuidedActionAdapter mSubAdapter;
@@ -1362,7 +1368,7 @@
         return 0;
     }
 
-    private void runImeAnimations(boolean entering) {
+    void runImeAnimations(boolean entering) {
         ArrayList<Animator> animators = new ArrayList<Animator>();
         if (entering) {
             mGuidanceStylist.onImeAppearing(animators);
diff --git a/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java b/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
index d3e76a5..18f96fe 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/HeadersFragment.java
@@ -70,7 +70,7 @@
     }
 
     private OnHeaderViewSelectedListener mOnHeaderViewSelectedListener;
-    private OnHeaderClickedListener mOnHeaderClickedListener;
+    OnHeaderClickedListener mOnHeaderClickedListener;
     private boolean mHeadersEnabled = true;
     private boolean mHeadersGone = false;
     private int mBackgroundColor;
@@ -137,7 +137,7 @@
 
     };
 
-    private static OnLayoutChangeListener sLayoutChangeListener = new OnLayoutChangeListener() {
+    static OnLayoutChangeListener sLayoutChangeListener = new OnLayoutChangeListener() {
         @Override
         public void onLayoutChange(View v, int left, int top, int right, int bottom,
             int oldLeft, int oldTop, int oldRight, int oldBottom) {
@@ -214,7 +214,7 @@
 
     // Wrapper needed because of conflict between RecyclerView's use of alpha
     // for ADD animations, and RowHeaderPresenter's use of alpha for selected level.
-    private final ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() {
+    final ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() {
         @Override
         public void wrap(View wrapper, View wrapped) {
             ((FrameLayout) wrapper).addView(wrapped);
diff --git a/v17/leanback/src/android/support/v17/leanback/app/HeadersSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/HeadersSupportFragment.java
index 9e01e70..8937e08 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/HeadersSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/HeadersSupportFragment.java
@@ -72,7 +72,7 @@
     }
 
     private OnHeaderViewSelectedListener mOnHeaderViewSelectedListener;
-    private OnHeaderClickedListener mOnHeaderClickedListener;
+    OnHeaderClickedListener mOnHeaderClickedListener;
     private boolean mHeadersEnabled = true;
     private boolean mHeadersGone = false;
     private int mBackgroundColor;
@@ -139,7 +139,7 @@
 
     };
 
-    private static OnLayoutChangeListener sLayoutChangeListener = new OnLayoutChangeListener() {
+    static OnLayoutChangeListener sLayoutChangeListener = new OnLayoutChangeListener() {
         @Override
         public void onLayoutChange(View v, int left, int top, int right, int bottom,
             int oldLeft, int oldTop, int oldRight, int oldBottom) {
@@ -216,7 +216,7 @@
 
     // Wrapper needed because of conflict between RecyclerView's use of alpha
     // for ADD animations, and RowHeaderPresenter's use of alpha for selected level.
-    private final ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() {
+    final ItemBridgeAdapter.Wrapper mWrapper = new ItemBridgeAdapter.Wrapper() {
         @Override
         public void wrap(View wrapper, View wrapped) {
             ((FrameLayout) wrapper).addView(wrapped);
diff --git a/v17/leanback/src/android/support/v17/leanback/app/ListRowDataAdapter.java b/v17/leanback/src/android/support/v17/leanback/app/ListRowDataAdapter.java
index e107460..59a9b1b 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/ListRowDataAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/ListRowDataAdapter.java
@@ -24,7 +24,7 @@
     public static final int ON_CHANGED = 16;
 
     private final ObjectAdapter mAdapter;
-    private int mLastVisibleRowIndex;
+    int mLastVisibleRowIndex;
 
     public ListRowDataAdapter(ObjectAdapter adapter) {
         super(adapter.getPresenterSelector());
@@ -43,7 +43,7 @@
         }
     }
 
-    private void initialize() {
+    void initialize() {
         int i = mAdapter.size() - 1;
         while (i >= 0) {
             Row item = (Row) mAdapter.get(i);
@@ -65,7 +65,7 @@
         return mAdapter.get(index);
     }
 
-    private void doNotify(int eventType, int positionStart, int itemCount) {
+    void doNotify(int eventType, int positionStart, int itemCount) {
         switch (eventType) {
             case ON_ITEM_RANGE_CHANGED:
                 notifyItemRangeChanged(positionStart, itemCount);
@@ -85,6 +85,9 @@
 
     private class SimpleDataObserver extends DataObserver {
 
+        SimpleDataObserver() {
+        }
+
         @Override
         public void onItemRangeChanged(int positionStart, int itemCount) {
             if (positionStart <= mLastVisibleRowIndex) {
@@ -148,6 +151,9 @@
      */
     private class QueueBasedDataObserver extends DataObserver {
 
+        QueueBasedDataObserver() {
+        }
+
         @Override
         public void onChanged() {
             initialize();
diff --git a/v17/leanback/src/android/support/v17/leanback/app/MediaControllerGlue.java b/v17/leanback/src/android/support/v17/leanback/app/MediaControllerGlue.java
index 2f04229..27ccd06 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/MediaControllerGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/MediaControllerGlue.java
@@ -16,10 +16,10 @@
  * {@link android.support.v4.media.session.MediaControllerCompat}.
  */
 public abstract class MediaControllerGlue extends PlaybackControlGlue {
-    private static final String TAG = "MediaControllerGlue";
-    private static final boolean DEBUG = false;
+    static final String TAG = "MediaControllerGlue";
+    static final boolean DEBUG = false;
 
-    private MediaControllerCompat mMediaController;
+    MediaControllerCompat mMediaController;
 
     private final MediaControllerCompat.Callback mCallback = new MediaControllerCompat.Callback() {
         @Override
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 bfd0f14..16d3ed1 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingFragment.java
@@ -168,19 +168,19 @@
 
     private ContextThemeWrapper mThemeWrapper;
 
-    private PagingIndicator mPageIndicator;
-    private View mStartButton;
+    PagingIndicator mPageIndicator;
+    View mStartButton;
     private ImageView mLogoView;
-    private TextView mTitleView;
-    private TextView mDescriptionView;
+    TextView mTitleView;
+    TextView mDescriptionView;
 
-    private boolean mIsLtr;
+    boolean mIsLtr;
 
     // No need to save/restore the logo resource ID, because the logo animation will not appear when
     // the fragment is restored.
     private int mLogoResourceId;
-    private boolean mEnterTransitionFinished;
-    private int mCurrentPageIndex;
+    boolean mEnterTransitionFinished;
+    int mCurrentPageIndex;
 
     private AnimatorSet mAnimator;
 
@@ -235,13 +235,13 @@
         }
     };
 
-    private void moveToPreviousPage() {
+    void moveToPreviousPage() {
         if (mCurrentPageIndex > 0) {
             --mCurrentPageIndex;
             onPageChangedInternal(mCurrentPageIndex + 1);
         }
     }
-    private void moveToNextPage() {
+    void moveToNextPage() {
         if (mCurrentPageIndex < getPageCount() - 1) {
             ++mCurrentPageIndex;
             onPageChangedInternal(mCurrentPageIndex - 1);
@@ -365,7 +365,7 @@
         return null;
     }
 
-    private boolean startLogoAnimation() {
+    boolean startLogoAnimation() {
         Animator animator = null;
         if (mLogoResourceId != 0) {
             mLogoView.setVisibility(View.VISIBLE);
@@ -449,7 +449,7 @@
         mDescriptionView.setText(getPageDescription(mCurrentPageIndex));
     }
 
-    private void startEnterAnimation() {
+    void startEnterAnimation() {
         mEnterTransitionFinished = true;
         initializeViews(getView());
         List<Animator> animators = new ArrayList<>();
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 d873f61..076b61e 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/OnboardingSupportFragment.java
@@ -170,19 +170,19 @@
 
     private ContextThemeWrapper mThemeWrapper;
 
-    private PagingIndicator mPageIndicator;
-    private View mStartButton;
+    PagingIndicator mPageIndicator;
+    View mStartButton;
     private ImageView mLogoView;
-    private TextView mTitleView;
-    private TextView mDescriptionView;
+    TextView mTitleView;
+    TextView mDescriptionView;
 
-    private boolean mIsLtr;
+    boolean mIsLtr;
 
     // No need to save/restore the logo resource ID, because the logo animation will not appear when
     // the fragment is restored.
     private int mLogoResourceId;
-    private boolean mEnterTransitionFinished;
-    private int mCurrentPageIndex;
+    boolean mEnterTransitionFinished;
+    int mCurrentPageIndex;
 
     private AnimatorSet mAnimator;
 
@@ -237,13 +237,13 @@
         }
     };
 
-    private void moveToPreviousPage() {
+    void moveToPreviousPage() {
         if (mCurrentPageIndex > 0) {
             --mCurrentPageIndex;
             onPageChangedInternal(mCurrentPageIndex + 1);
         }
     }
-    private void moveToNextPage() {
+    void moveToNextPage() {
         if (mCurrentPageIndex < getPageCount() - 1) {
             ++mCurrentPageIndex;
             onPageChangedInternal(mCurrentPageIndex - 1);
@@ -367,7 +367,7 @@
         return null;
     }
 
-    private boolean startLogoAnimation() {
+    boolean startLogoAnimation() {
         Animator animator = null;
         if (mLogoResourceId != 0) {
             mLogoView.setVisibility(View.VISIBLE);
@@ -451,7 +451,7 @@
         mDescriptionView.setText(getPageDescription(mCurrentPageIndex));
     }
 
-    private void startEnterAnimation() {
+    void startEnterAnimation() {
         mEnterTransitionFinished = true;
         initializeViews(getView());
         List<Animator> animators = new ArrayList<>();
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PermissionHelper.java b/v17/leanback/src/android/support/v17/leanback/app/PermissionHelper.java
index ee9f866..e6edadb 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PermissionHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PermissionHelper.java
@@ -14,10 +14,14 @@
 package android.support.v17.leanback.app;
 
 import android.os.Build;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class PermissionHelper {
 
     public static void requestPermissions(android.app.Fragment fragment, String[] permissions,
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java
index 2a2df3c..004f6f0 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlGlue.java
@@ -155,10 +155,10 @@
      */
     public static final int PLAYBACK_SPEED_FAST_L4 = 14;
 
-    private static final String TAG = "PlaybackControlGlue";
-    private static final boolean DEBUG = false;
+    static final String TAG = "PlaybackControlGlue";
+    static final boolean DEBUG = false;
 
-    private static final int MSG_UPDATE_PLAYBACK_STATE = 100;
+    static final int MSG_UPDATE_PLAYBACK_STATE = 100;
     private static final int UPDATE_PLAYBACK_STATE_DELAY_MS = 2000;
     private static final int NUMBER_OF_SEEK_SPEEDS = PLAYBACK_SPEED_FAST_L4 -
             PLAYBACK_SPEED_FAST_L0 + 1;
@@ -174,7 +174,7 @@
     private PlaybackControlsRow.SkipPreviousAction mSkipPreviousAction;
     private PlaybackControlsRow.FastForwardAction mFastForwardAction;
     private PlaybackControlsRow.RewindAction mRewindAction;
-    private OnItemViewClickedListener mExternalOnItemViewClickedListener;
+    OnItemViewClickedListener mExternalOnItemViewClickedListener;
     private int mPlaybackSpeed = PLAYBACK_SPEED_NORMAL;
     private boolean mFadeWhenPlaying = true;
 
@@ -483,7 +483,7 @@
     /**
      * Called when the given action is invoked, either by click or keyevent.
      */
-    private boolean dispatchAction(Action action, KeyEvent keyEvent) {
+    boolean dispatchAction(Action action, KeyEvent keyEvent) {
         boolean handled = false;
         if (action == mPlayPauseAction) {
             boolean canPlay = keyEvent == null ||
@@ -589,7 +589,7 @@
         onRowChanged(mControlsRow);
     }
 
-    private void updatePlaybackState() {
+    void updatePlaybackState() {
         if (hasValidMedia()) {
             mPlaybackSpeed = getCurrentSpeedId();
             updatePlaybackState(mPlaybackSpeed);
diff --git a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java b/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java
index 9adbbb9..1e1eab5 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackControlSupportGlue.java
@@ -157,10 +157,10 @@
      */
     public static final int PLAYBACK_SPEED_FAST_L4 = 14;
 
-    private static final String TAG = "PlaybackControlSupportGlue";
-    private static final boolean DEBUG = false;
+    static final String TAG = "PlaybackControlSupportGlue";
+    static final boolean DEBUG = false;
 
-    private static final int MSG_UPDATE_PLAYBACK_STATE = 100;
+    static final int MSG_UPDATE_PLAYBACK_STATE = 100;
     private static final int UPDATE_PLAYBACK_STATE_DELAY_MS = 2000;
     private static final int NUMBER_OF_SEEK_SPEEDS = PLAYBACK_SPEED_FAST_L4 -
             PLAYBACK_SPEED_FAST_L0 + 1;
@@ -176,7 +176,7 @@
     private PlaybackControlsRow.SkipPreviousAction mSkipPreviousAction;
     private PlaybackControlsRow.FastForwardAction mFastForwardAction;
     private PlaybackControlsRow.RewindAction mRewindAction;
-    private OnItemViewClickedListener mExternalOnItemViewClickedListener;
+    OnItemViewClickedListener mExternalOnItemViewClickedListener;
     private int mPlaybackSpeed = PLAYBACK_SPEED_NORMAL;
     private boolean mFadeWhenPlaying = true;
 
@@ -485,7 +485,7 @@
     /**
      * Called when the given action is invoked, either by click or keyevent.
      */
-    private boolean dispatchAction(Action action, KeyEvent keyEvent) {
+    boolean dispatchAction(Action action, KeyEvent keyEvent) {
         boolean handled = false;
         if (action == mPlayPauseAction) {
             boolean canPlay = keyEvent == null ||
@@ -591,7 +591,7 @@
         onRowChanged(mControlsRow);
     }
 
-    private void updatePlaybackState() {
+    void updatePlaybackState() {
         if (hasValidMedia()) {
             mPlaybackSpeed = getCurrentSpeedId();
             updatePlaybackState(mPlaybackSpeed);
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 eaabd72..59e22d7 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlayFragment.java
@@ -102,16 +102,16 @@
         public boolean handleInputEvent(InputEvent event);
     }
 
-    private static final String TAG = "PlaybackOverlayFragment";
-    private static final boolean DEBUG = false;
+    static final String TAG = "PlaybackOverlayFragment";
+    static final boolean DEBUG = false;
     private static final int ANIMATION_MULTIPLIER = 1;
 
-    private static int START_FADE_OUT = 1;
+    static int START_FADE_OUT = 1;
 
     // Fading status
-    private static final int IDLE = 0;
+    static final int IDLE = 0;
     private static final int IN = 1;
-    private static final int OUT = 2;
+    static final int OUT = 2;
 
     private int mPaddingTop;
     private int mPaddingBottom;
@@ -121,18 +121,18 @@
     private int mBgLightColor;
     private int mShowTimeMs;
     private int mMajorFadeTranslateY, mMinorFadeTranslateY;
-    private int mAnimationTranslateY;
-    private OnFadeCompleteListener mFadeCompleteListener;
+    int mAnimationTranslateY;
+    OnFadeCompleteListener mFadeCompleteListener;
     private InputEventHandler mInputEventHandler;
-    private boolean mFadingEnabled = true;
-    private int mFadingStatus = IDLE;
-    private int mBgAlpha;
+    boolean mFadingEnabled = true;
+    int mFadingStatus = IDLE;
+    int mBgAlpha;
     private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
     private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
     private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
     private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
     private boolean mTranslateAnimationEnabled;
-    private boolean mResetControlsToPrimaryActionsPending;
+    boolean mResetControlsToPrimaryActionsPending;
     private RecyclerView.ItemAnimator mItemAnimator;
 
     private final Animator.AnimatorListener mFadeListener =
@@ -195,20 +195,20 @@
         }
     };
 
-    private void setBgAlpha(int alpha) {
+    void setBgAlpha(int alpha) {
         mBgAlpha = alpha;
         if (mRootView != null) {
             mRootView.getBackground().setAlpha(alpha);
         }
     }
 
-    private void enableVerticalGridAnimations(boolean enable) {
+    void enableVerticalGridAnimations(boolean enable) {
         if (getVerticalGridView() != null) {
             getVerticalGridView().setAnimateChildLayout(enable);
         }
     }
 
-    private void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
+    void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
         if (vh == null && getVerticalGridView() != null) {
             vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
         }
@@ -310,7 +310,7 @@
         return mFadingStatus == IDLE && mBgAlpha == 0;
     }
 
-    private boolean onInterceptInputEvent(InputEvent event) {
+    boolean onInterceptInputEvent(InputEvent event) {
         final boolean controlsHidden = areControlsHidden();
         if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event);
         boolean consumeEvent = false;
@@ -367,7 +367,7 @@
         getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
     }
 
-    private void startFadeTimer() {
+    void startFadeTimer() {
         if (mHandler != null) {
             mHandler.removeMessages(START_FADE_OUT);
             mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs);
@@ -400,7 +400,7 @@
     private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
     private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
 
-    private View getControlRowView() {
+    View getControlRowView() {
         if (getVerticalGridView() == null) {
             return null;
         }
@@ -522,7 +522,7 @@
         mDescriptionFadeOutAnimator.addUpdateListener(listener);
     }
 
-    private void fade(boolean fadeIn) {
+    void fade(boolean fadeIn) {
         if (DEBUG) Log.v(TAG, "fade " + fadeIn);
         if (getView() == null) {
             return;
@@ -679,7 +679,7 @@
         }
     }
 
-    private void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
+    void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
         // Add extra space between rows 0 and 1
         if (vh == null && getVerticalGridView() != null) {
             vh = (ItemBridgeAdapter.ViewHolder)
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 d35614c..eb2a8c3 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/PlaybackOverlaySupportFragment.java
@@ -104,16 +104,16 @@
         public boolean handleInputEvent(InputEvent event);
     }
 
-    private static final String TAG = "PlaybackOverlaySupportFragment";
-    private static final boolean DEBUG = false;
+    static final String TAG = "PlaybackOverlaySupportFragment";
+    static final boolean DEBUG = false;
     private static final int ANIMATION_MULTIPLIER = 1;
 
-    private static int START_FADE_OUT = 1;
+    static int START_FADE_OUT = 1;
 
     // Fading status
-    private static final int IDLE = 0;
+    static final int IDLE = 0;
     private static final int IN = 1;
-    private static final int OUT = 2;
+    static final int OUT = 2;
 
     private int mPaddingTop;
     private int mPaddingBottom;
@@ -123,18 +123,18 @@
     private int mBgLightColor;
     private int mShowTimeMs;
     private int mMajorFadeTranslateY, mMinorFadeTranslateY;
-    private int mAnimationTranslateY;
-    private OnFadeCompleteListener mFadeCompleteListener;
+    int mAnimationTranslateY;
+    OnFadeCompleteListener mFadeCompleteListener;
     private InputEventHandler mInputEventHandler;
-    private boolean mFadingEnabled = true;
-    private int mFadingStatus = IDLE;
-    private int mBgAlpha;
+    boolean mFadingEnabled = true;
+    int mFadingStatus = IDLE;
+    int mBgAlpha;
     private ValueAnimator mBgFadeInAnimator, mBgFadeOutAnimator;
     private ValueAnimator mControlRowFadeInAnimator, mControlRowFadeOutAnimator;
     private ValueAnimator mDescriptionFadeInAnimator, mDescriptionFadeOutAnimator;
     private ValueAnimator mOtherRowFadeInAnimator, mOtherRowFadeOutAnimator;
     private boolean mTranslateAnimationEnabled;
-    private boolean mResetControlsToPrimaryActionsPending;
+    boolean mResetControlsToPrimaryActionsPending;
     private RecyclerView.ItemAnimator mItemAnimator;
 
     private final Animator.AnimatorListener mFadeListener =
@@ -197,20 +197,20 @@
         }
     };
 
-    private void setBgAlpha(int alpha) {
+    void setBgAlpha(int alpha) {
         mBgAlpha = alpha;
         if (mRootView != null) {
             mRootView.getBackground().setAlpha(alpha);
         }
     }
 
-    private void enableVerticalGridAnimations(boolean enable) {
+    void enableVerticalGridAnimations(boolean enable) {
         if (getVerticalGridView() != null) {
             getVerticalGridView().setAnimateChildLayout(enable);
         }
     }
 
-    private void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
+    void resetControlsToPrimaryActions(ItemBridgeAdapter.ViewHolder vh) {
         if (vh == null && getVerticalGridView() != null) {
             vh = (ItemBridgeAdapter.ViewHolder) getVerticalGridView().findViewHolderForPosition(0);
         }
@@ -312,7 +312,7 @@
         return mFadingStatus == IDLE && mBgAlpha == 0;
     }
 
-    private boolean onInterceptInputEvent(InputEvent event) {
+    boolean onInterceptInputEvent(InputEvent event) {
         final boolean controlsHidden = areControlsHidden();
         if (DEBUG) Log.v(TAG, "onInterceptInputEvent hidden " + controlsHidden + " " + event);
         boolean consumeEvent = false;
@@ -369,7 +369,7 @@
         getVerticalGridView().setOnKeyInterceptListener(mOnKeyInterceptListener);
     }
 
-    private void startFadeTimer() {
+    void startFadeTimer() {
         if (mHandler != null) {
             mHandler.removeMessages(START_FADE_OUT);
             mHandler.sendEmptyMessageDelayed(START_FADE_OUT, mShowTimeMs);
@@ -402,7 +402,7 @@
     private TimeInterpolator mLogDecelerateInterpolator = new LogDecelerateInterpolator(100,0);
     private TimeInterpolator mLogAccelerateInterpolator = new LogAccelerateInterpolator(100,0);
 
-    private View getControlRowView() {
+    View getControlRowView() {
         if (getVerticalGridView() == null) {
             return null;
         }
@@ -524,7 +524,7 @@
         mDescriptionFadeOutAnimator.addUpdateListener(listener);
     }
 
-    private void fade(boolean fadeIn) {
+    void fade(boolean fadeIn) {
         if (DEBUG) Log.v(TAG, "fade " + fadeIn);
         if (getView() == null) {
             return;
@@ -681,7 +681,7 @@
         }
     }
 
-    private void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
+    void updateControlsBottomSpace(ItemBridgeAdapter.ViewHolder vh) {
         // Add extra space between rows 0 and 1
         if (vh == null && getVerticalGridView() != null) {
             vh = (ItemBridgeAdapter.ViewHolder)
diff --git a/v17/leanback/src/android/support/v17/leanback/app/ProgressBarManager.java b/v17/leanback/src/android/support/v17/leanback/app/ProgressBarManager.java
index e05ca0c..c9a2b87 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/ProgressBarManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/ProgressBarManager.java
@@ -18,12 +18,12 @@
     private static final long DEFAULT_PROGRESS_BAR_DELAY = 1000;
 
     private long mInitialDelay = DEFAULT_PROGRESS_BAR_DELAY;
-    private ViewGroup rootView;
-    private View mProgressBarView;
+    ViewGroup rootView;
+    View mProgressBarView;
     private Handler mHandler = new Handler();
-    private boolean mEnableProgressBar = true;
-    private boolean mUserProvidedProgressBar;
-    private boolean mIsShowing;
+    boolean mEnableProgressBar = true;
+    boolean mUserProvidedProgressBar;
+    boolean mIsShowing;
 
     private Runnable runnable = new Runnable() {
         @Override
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 6a667d6..7b93115 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/RowsFragment.java
@@ -131,18 +131,18 @@
 
     }
 
-    private static final String TAG = "RowsFragment";
-    private static final boolean DEBUG = false;
+    static final String TAG = "RowsFragment";
+    static final boolean DEBUG = false;
 
-    private ItemBridgeAdapter.ViewHolder mSelectedViewHolder;
+    ItemBridgeAdapter.ViewHolder mSelectedViewHolder;
     private int mSubPosition;
-    private boolean mExpand = true;
-    private boolean mViewsCreated;
+    boolean mExpand = true;
+    boolean mViewsCreated;
     private int mAlignedTop;
-    private boolean mAfterEntranceTransition = true;
+    boolean mAfterEntranceTransition = true;
 
-    private BaseOnItemViewSelectedListener mOnItemViewSelectedListener;
-    private BaseOnItemViewClickedListener mOnItemViewClickedListener;
+    BaseOnItemViewSelectedListener mOnItemViewSelectedListener;
+    BaseOnItemViewClickedListener mOnItemViewClickedListener;
 
     // Select animation and interpolator are not intended to be
     // exposed at this moment. They might be synced with vertical scroll
@@ -153,7 +153,7 @@
     private RecyclerView.RecycledViewPool mRecycledViewPool;
     private ArrayList<Presenter> mPresenterMapper;
 
-    private ItemBridgeAdapter.AdapterListener mExternalAdapterListener;
+    ItemBridgeAdapter.AdapterListener mExternalAdapterListener;
 
     @Override
     protected VerticalGridView findGridViewFromRoot(View view) {
@@ -311,11 +311,11 @@
         mExternalAdapterListener = listener;
     }
 
-    private static void setRowViewExpanded(ItemBridgeAdapter.ViewHolder vh, boolean expanded) {
+    static void setRowViewExpanded(ItemBridgeAdapter.ViewHolder vh, boolean expanded) {
         ((RowPresenter) vh.getPresenter()).setRowViewExpanded(vh.getViewHolder(), expanded);
     }
 
-    private static void setRowViewSelected(ItemBridgeAdapter.ViewHolder vh, boolean selected,
+    static void setRowViewSelected(ItemBridgeAdapter.ViewHolder vh, boolean selected,
             boolean immediate) {
         RowViewHolderExtra extra = (RowViewHolderExtra) vh.getExtraObject();
         extra.animateSelect(selected, immediate);
@@ -396,7 +396,7 @@
         }
     };
 
-    private void setupSharedViewPool(ItemBridgeAdapter.ViewHolder bridgeVh) {
+    void setupSharedViewPool(ItemBridgeAdapter.ViewHolder bridgeVh) {
         RowPresenter rowPresenter = (RowPresenter) bridgeVh.getPresenter();
         RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(bridgeVh.getViewHolder());
 
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 ed79a36..4086658 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/RowsSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/RowsSupportFragment.java
@@ -133,18 +133,18 @@
 
     }
 
-    private static final String TAG = "RowsSupportFragment";
-    private static final boolean DEBUG = false;
+    static final String TAG = "RowsSupportFragment";
+    static final boolean DEBUG = false;
 
-    private ItemBridgeAdapter.ViewHolder mSelectedViewHolder;
+    ItemBridgeAdapter.ViewHolder mSelectedViewHolder;
     private int mSubPosition;
-    private boolean mExpand = true;
-    private boolean mViewsCreated;
+    boolean mExpand = true;
+    boolean mViewsCreated;
     private int mAlignedTop;
-    private boolean mAfterEntranceTransition = true;
+    boolean mAfterEntranceTransition = true;
 
-    private BaseOnItemViewSelectedListener mOnItemViewSelectedListener;
-    private BaseOnItemViewClickedListener mOnItemViewClickedListener;
+    BaseOnItemViewSelectedListener mOnItemViewSelectedListener;
+    BaseOnItemViewClickedListener mOnItemViewClickedListener;
 
     // Select animation and interpolator are not intended to be
     // exposed at this moment. They might be synced with vertical scroll
@@ -155,7 +155,7 @@
     private RecyclerView.RecycledViewPool mRecycledViewPool;
     private ArrayList<Presenter> mPresenterMapper;
 
-    private ItemBridgeAdapter.AdapterListener mExternalAdapterListener;
+    ItemBridgeAdapter.AdapterListener mExternalAdapterListener;
 
     @Override
     protected VerticalGridView findGridViewFromRoot(View view) {
@@ -313,11 +313,11 @@
         mExternalAdapterListener = listener;
     }
 
-    private static void setRowViewExpanded(ItemBridgeAdapter.ViewHolder vh, boolean expanded) {
+    static void setRowViewExpanded(ItemBridgeAdapter.ViewHolder vh, boolean expanded) {
         ((RowPresenter) vh.getPresenter()).setRowViewExpanded(vh.getViewHolder(), expanded);
     }
 
-    private static void setRowViewSelected(ItemBridgeAdapter.ViewHolder vh, boolean selected,
+    static void setRowViewSelected(ItemBridgeAdapter.ViewHolder vh, boolean selected,
             boolean immediate) {
         RowViewHolderExtra extra = (RowViewHolderExtra) vh.getExtraObject();
         extra.animateSelect(selected, immediate);
@@ -398,7 +398,7 @@
         }
     };
 
-    private void setupSharedViewPool(ItemBridgeAdapter.ViewHolder bridgeVh) {
+    void setupSharedViewPool(ItemBridgeAdapter.ViewHolder bridgeVh) {
         RowPresenter rowPresenter = (RowPresenter) bridgeVh.getPresenter();
         RowPresenter.ViewHolder rowVh = rowPresenter.getRowViewHolder(bridgeVh.getViewHolder());
 
diff --git a/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java b/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
index 01ba0bf..70393c4 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
@@ -65,20 +65,20 @@
  * </p>
  */
 public class SearchFragment extends Fragment {
-    private static final String TAG = SearchFragment.class.getSimpleName();
-    private static final boolean DEBUG = false;
+    static final String TAG = SearchFragment.class.getSimpleName();
+    static final boolean DEBUG = false;
 
     private static final String EXTRA_LEANBACK_BADGE_PRESENT = "LEANBACK_BADGE_PRESENT";
     private static final String ARG_PREFIX = SearchFragment.class.getCanonicalName();
     private static final String ARG_QUERY =  ARG_PREFIX + ".query";
     private static final String ARG_TITLE = ARG_PREFIX  + ".title";
 
-    private static final long SPEECH_RECOGNITION_DELAY_MS = 300;
+    static final long SPEECH_RECOGNITION_DELAY_MS = 300;
 
-    private static final int RESULTS_CHANGED = 0x1;
-    private static final int QUERY_COMPLETE = 0x2;
+    static final int RESULTS_CHANGED = 0x1;
+    static final int QUERY_COMPLETE = 0x2;
 
-    private static final int AUDIO_PERMISSION_REQUEST_CODE = 0;
+    static final int AUDIO_PERMISSION_REQUEST_CODE = 0;
 
     /**
      * Search API to be provided by the application.
@@ -119,7 +119,7 @@
         public boolean onQueryTextSubmit(String query);
     }
 
-    private final DataObserver mAdapterObserver = new DataObserver() {
+    final DataObserver mAdapterObserver = new DataObserver() {
         @Override
         public void onChanged() {
             // onChanged() may be called multiple times e.g. the provider add
@@ -129,9 +129,9 @@
         }
     };
 
-    private final Handler mHandler = new Handler();
+    final Handler mHandler = new Handler();
 
-    private final Runnable mResultsChangedCallback = new Runnable() {
+    final Runnable mResultsChangedCallback = new Runnable() {
         @Override
         public void run() {
             if (DEBUG) Log.v(TAG, "results changed, new size " + mResultAdapter.size());
@@ -194,7 +194,7 @@
         }
     };
 
-    private final Runnable mStartRecognitionRunnable = new Runnable() {
+    final Runnable mStartRecognitionRunnable = new Runnable() {
         @Override
         public void run() {
             mAutoStartRecognition = false;
@@ -202,14 +202,14 @@
         }
     };
 
-    private RowsFragment mRowsFragment;
-    private SearchBar mSearchBar;
-    private SearchResultProvider mProvider;
-    private String mPendingQuery = null;
+    RowsFragment mRowsFragment;
+    SearchBar mSearchBar;
+    SearchResultProvider mProvider;
+    String mPendingQuery = null;
 
-    private OnItemViewSelectedListener mOnItemViewSelectedListener;
+    OnItemViewSelectedListener mOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
-    private ObjectAdapter mResultAdapter;
+    ObjectAdapter mResultAdapter;
     private SpeechRecognitionCallback mSpeechRecognitionCallback;
 
     private String mTitle;
@@ -218,8 +218,8 @@
 
     private SpeechRecognizer mSpeechRecognizer;
 
-    private int mStatus;
-    private boolean mAutoStartRecognition = true;
+    int mStatus;
+    boolean mAutoStartRecognition = true;
 
     private boolean mIsPaused;
     private boolean mPendingStartRecognitionWhenPaused;
@@ -613,33 +613,33 @@
         return recognizerIntent;
     }
 
-    private void retrieveResults(String searchQuery) {
+    void retrieveResults(String searchQuery) {
         if (DEBUG) Log.v(TAG, "retrieveResults " + searchQuery);
         if (mProvider.onQueryTextChange(searchQuery)) {
             mStatus &= ~QUERY_COMPLETE;
         }
     }
 
-    private void submitQuery(String query) {
+    void submitQuery(String query) {
         queryComplete();
         if (null != mProvider) {
             mProvider.onQueryTextSubmit(query);
         }
     }
 
-    private void queryComplete() {
+    void queryComplete() {
         if (DEBUG) Log.v(TAG, "queryComplete");
         mStatus |= QUERY_COMPLETE;
         focusOnResults();
     }
 
-    private void updateSearchBarVisibility() {
+    void updateSearchBarVisibility() {
         int position = mRowsFragment != null ? mRowsFragment.getSelectedPosition() : -1;
         mSearchBar.setVisibility(position <=0 || mResultAdapter == null
                 || mResultAdapter.size() == 0 ? View.VISIBLE : View.GONE);
     }
 
-    private void updateSearchBarNextFocusId() {
+    void updateSearchBarNextFocusId() {
         if (mSearchBar == null || mResultAdapter == null) {
             return;
         }
@@ -649,7 +649,7 @@
         mSearchBar.setNextFocusDownId(viewId);
     }
 
-    private void updateFocus() {
+    void updateFocus() {
         if (mResultAdapter != null && mResultAdapter.size() > 0 &&
                 mRowsFragment != null && mRowsFragment.getAdapter() == mResultAdapter) {
             focusOnResults();
@@ -674,14 +674,14 @@
         mHandler.post(mSetSearchResultProvider);
     }
 
-    private void releaseAdapter() {
+    void releaseAdapter() {
         if (mResultAdapter != null) {
             mResultAdapter.unregisterObserver(mAdapterObserver);
             mResultAdapter = null;
         }
     }
 
-    private void executePendingQuery() {
+    void executePendingQuery() {
         if (null != mPendingQuery && null != mResultAdapter) {
             String query = mPendingQuery;
             mPendingQuery = null;
diff --git a/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
index 27c4099..7b9582c 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/SearchSupportFragment.java
@@ -67,20 +67,20 @@
  * </p>
  */
 public class SearchSupportFragment extends Fragment {
-    private static final String TAG = SearchSupportFragment.class.getSimpleName();
-    private static final boolean DEBUG = false;
+    static final String TAG = SearchSupportFragment.class.getSimpleName();
+    static final boolean DEBUG = false;
 
     private static final String EXTRA_LEANBACK_BADGE_PRESENT = "LEANBACK_BADGE_PRESENT";
     private static final String ARG_PREFIX = SearchSupportFragment.class.getCanonicalName();
     private static final String ARG_QUERY =  ARG_PREFIX + ".query";
     private static final String ARG_TITLE = ARG_PREFIX  + ".title";
 
-    private static final long SPEECH_RECOGNITION_DELAY_MS = 300;
+    static final long SPEECH_RECOGNITION_DELAY_MS = 300;
 
-    private static final int RESULTS_CHANGED = 0x1;
-    private static final int QUERY_COMPLETE = 0x2;
+    static final int RESULTS_CHANGED = 0x1;
+    static final int QUERY_COMPLETE = 0x2;
 
-    private static final int AUDIO_PERMISSION_REQUEST_CODE = 0;
+    static final int AUDIO_PERMISSION_REQUEST_CODE = 0;
 
     /**
      * Search API to be provided by the application.
@@ -121,7 +121,7 @@
         public boolean onQueryTextSubmit(String query);
     }
 
-    private final DataObserver mAdapterObserver = new DataObserver() {
+    final DataObserver mAdapterObserver = new DataObserver() {
         @Override
         public void onChanged() {
             // onChanged() may be called multiple times e.g. the provider add
@@ -131,9 +131,9 @@
         }
     };
 
-    private final Handler mHandler = new Handler();
+    final Handler mHandler = new Handler();
 
-    private final Runnable mResultsChangedCallback = new Runnable() {
+    final Runnable mResultsChangedCallback = new Runnable() {
         @Override
         public void run() {
             if (DEBUG) Log.v(TAG, "results changed, new size " + mResultAdapter.size());
@@ -196,7 +196,7 @@
         }
     };
 
-    private final Runnable mStartRecognitionRunnable = new Runnable() {
+    final Runnable mStartRecognitionRunnable = new Runnable() {
         @Override
         public void run() {
             mAutoStartRecognition = false;
@@ -204,14 +204,14 @@
         }
     };
 
-    private RowsSupportFragment mRowsSupportFragment;
-    private SearchBar mSearchBar;
-    private SearchResultProvider mProvider;
-    private String mPendingQuery = null;
+    RowsSupportFragment mRowsSupportFragment;
+    SearchBar mSearchBar;
+    SearchResultProvider mProvider;
+    String mPendingQuery = null;
 
-    private OnItemViewSelectedListener mOnItemViewSelectedListener;
+    OnItemViewSelectedListener mOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
-    private ObjectAdapter mResultAdapter;
+    ObjectAdapter mResultAdapter;
     private SpeechRecognitionCallback mSpeechRecognitionCallback;
 
     private String mTitle;
@@ -220,8 +220,8 @@
 
     private SpeechRecognizer mSpeechRecognizer;
 
-    private int mStatus;
-    private boolean mAutoStartRecognition = true;
+    int mStatus;
+    boolean mAutoStartRecognition = true;
 
     private boolean mIsPaused;
     private boolean mPendingStartRecognitionWhenPaused;
@@ -615,33 +615,33 @@
         return recognizerIntent;
     }
 
-    private void retrieveResults(String searchQuery) {
+    void retrieveResults(String searchQuery) {
         if (DEBUG) Log.v(TAG, "retrieveResults " + searchQuery);
         if (mProvider.onQueryTextChange(searchQuery)) {
             mStatus &= ~QUERY_COMPLETE;
         }
     }
 
-    private void submitQuery(String query) {
+    void submitQuery(String query) {
         queryComplete();
         if (null != mProvider) {
             mProvider.onQueryTextSubmit(query);
         }
     }
 
-    private void queryComplete() {
+    void queryComplete() {
         if (DEBUG) Log.v(TAG, "queryComplete");
         mStatus |= QUERY_COMPLETE;
         focusOnResults();
     }
 
-    private void updateSearchBarVisibility() {
+    void updateSearchBarVisibility() {
         int position = mRowsSupportFragment != null ? mRowsSupportFragment.getSelectedPosition() : -1;
         mSearchBar.setVisibility(position <=0 || mResultAdapter == null
                 || mResultAdapter.size() == 0 ? View.VISIBLE : View.GONE);
     }
 
-    private void updateSearchBarNextFocusId() {
+    void updateSearchBarNextFocusId() {
         if (mSearchBar == null || mResultAdapter == null) {
             return;
         }
@@ -651,7 +651,7 @@
         mSearchBar.setNextFocusDownId(viewId);
     }
 
-    private void updateFocus() {
+    void updateFocus() {
         if (mResultAdapter != null && mResultAdapter.size() > 0 &&
                 mRowsSupportFragment != null && mRowsSupportFragment.getAdapter() == mResultAdapter) {
             focusOnResults();
@@ -676,14 +676,14 @@
         mHandler.post(mSetSearchResultProvider);
     }
 
-    private void releaseAdapter() {
+    void releaseAdapter() {
         if (mResultAdapter != null) {
             mResultAdapter.unregisterObserver(mAdapterObserver);
             mResultAdapter = null;
         }
     }
 
-    private void executePendingQuery() {
+    void executePendingQuery() {
         if (null != mPendingQuery && null != mResultAdapter) {
             String query = mPendingQuery;
             mPendingQuery = null;
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 c02fd69..b8f3df2 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
@@ -37,13 +37,13 @@
  * an {@link ObjectAdapter}.
  */
 public class VerticalGridFragment extends BaseFragment {
-    private static final String TAG = "VerticalGridFragment";
-    private static boolean DEBUG = false;
+    static final String TAG = "VerticalGridFragment";
+    static boolean DEBUG = false;
 
     private ObjectAdapter mAdapter;
     private VerticalGridPresenter mGridPresenter;
-    private VerticalGridPresenter.ViewHolder mGridViewHolder;
-    private OnItemViewSelectedListener mOnItemViewSelectedListener;
+    VerticalGridPresenter.ViewHolder mGridViewHolder;
+    OnItemViewSelectedListener mOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
     private Object mSceneAfterEntranceTransition;
     private int mSelectedPosition = -1;
@@ -116,14 +116,14 @@
         mOnItemViewSelectedListener = listener;
     }
 
-    private void gridOnItemSelected(int position) {
+    void gridOnItemSelected(int position) {
         if (position != mSelectedPosition) {
             mSelectedPosition = position;
             showOrHideTitle();
         }
     }
 
-    private void showOrHideTitle() {
+    void showOrHideTitle() {
         if (mGridViewHolder.getGridView().findViewHolderForAdapterPosition(mSelectedPosition)
                 == null) {
             return;
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 3bf5e12..309de0c 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
@@ -39,13 +39,13 @@
  * an {@link ObjectAdapter}.
  */
 public class VerticalGridSupportFragment extends BaseSupportFragment {
-    private static final String TAG = "VerticalGridSupportFragment";
-    private static boolean DEBUG = false;
+    static final String TAG = "VerticalGridSupportFragment";
+    static boolean DEBUG = false;
 
     private ObjectAdapter mAdapter;
     private VerticalGridPresenter mGridPresenter;
-    private VerticalGridPresenter.ViewHolder mGridViewHolder;
-    private OnItemViewSelectedListener mOnItemViewSelectedListener;
+    VerticalGridPresenter.ViewHolder mGridViewHolder;
+    OnItemViewSelectedListener mOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
     private Object mSceneAfterEntranceTransition;
     private int mSelectedPosition = -1;
@@ -118,14 +118,14 @@
         mOnItemViewSelectedListener = listener;
     }
 
-    private void gridOnItemSelected(int position) {
+    void gridOnItemSelected(int position) {
         if (position != mSelectedPosition) {
             mSelectedPosition = position;
             showOrHideTitle();
         }
     }
 
-    private void showOrHideTitle() {
+    void showOrHideTitle() {
         if (mGridViewHolder.getGridView().findViewHolderForAdapterPosition(mSelectedPosition)
                 == null) {
             return;
diff --git a/v17/leanback/src/android/support/v17/leanback/os/TraceHelper.java b/v17/leanback/src/android/support/v17/leanback/os/TraceHelper.java
index 09a082d..4f1cd33 100644
--- a/v17/leanback/src/android/support/v17/leanback/os/TraceHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/os/TraceHelper.java
@@ -16,23 +16,30 @@
 package android.support.v17.leanback.os;
 
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.os.TraceHelperJbmr2;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 
 /**
  * Helper for systrace events.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class TraceHelper {
 
     final static TraceHelperVersionImpl sImpl;
 
-    static interface TraceHelperVersionImpl {
-        public void beginSection(String section);
-        public void endSection();
+    interface TraceHelperVersionImpl {
+        void beginSection(String section);
+        void endSection();
     }
 
     private static final class TraceHelperStubImpl implements TraceHelperVersionImpl {
+        TraceHelperStubImpl() {
+        }
+
         @Override
         public void beginSection(String section) {
         }
@@ -43,6 +50,9 @@
     }
 
     private static final class TraceHelperJbmr2Impl implements TraceHelperVersionImpl {
+        TraceHelperJbmr2Impl() {
+        }
+
         @Override
         public void beginSection(String section) {
             TraceHelperJbmr2.beginSection(section);
diff --git a/v17/leanback/src/android/support/v17/leanback/system/Settings.java b/v17/leanback/src/android/support/v17/leanback/system/Settings.java
index 73fbdce..ec0316c 100644
--- a/v17/leanback/src/android/support/v17/leanback/system/Settings.java
+++ b/v17/leanback/src/android/support/v17/leanback/system/Settings.java
@@ -22,9 +22,12 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.widget.ShadowOverlayContainer;
 import android.util.Log;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Provides various preferences affecting Leanback runtime behavior.
  * <p>Note this class is not thread safe and its methods should only
@@ -66,6 +69,7 @@
      * Returns true if static shadows are recommended.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public boolean preferStaticShadows() {
         return mPreferStaticShadows;
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/transition/LeanbackTransitionHelper.java b/v17/leanback/src/android/support/v17/leanback/transition/LeanbackTransitionHelper.java
index 47495cb..d4eecdb 100644
--- a/v17/leanback/src/android/support/v17/leanback/transition/LeanbackTransitionHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/transition/LeanbackTransitionHelper.java
@@ -16,23 +16,25 @@
 import android.animation.AnimatorInflater;
 import android.content.Context;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.view.Gravity;
 import android.view.View;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper class to load Leanback specific transition.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class LeanbackTransitionHelper {
 
-    static interface LeanbackTransitionHelperVersion {
-
-        public Object loadTitleInTransition(Context context);
-
-        public Object loadTitleOutTransition(Context context);
+    interface LeanbackTransitionHelperVersion {
+        Object loadTitleInTransition(Context context);
+        Object loadTitleOutTransition(Context context);
     }
 
     /*
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 7437227..5b72643 100644
--- a/v17/leanback/src/android/support/v17/leanback/transition/TransitionHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/transition/TransitionHelper.java
@@ -15,6 +15,7 @@
 
 import android.content.Context;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
@@ -22,10 +23,13 @@
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Helper for view transitions.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class TransitionHelper {
 
     public static final int FADE_IN = 0x1;
@@ -162,6 +166,9 @@
 
         private static class TransitionStub {
             ArrayList<TransitionListener> mTransitionListeners;
+
+            TransitionStub() {
+            }
         }
 
         @Override
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 4155af6..18b2133 100644
--- a/v17/leanback/src/android/support/v17/leanback/util/StateMachine.java
+++ b/v17/leanback/src/android/support/v17/leanback/util/StateMachine.java
@@ -13,11 +13,15 @@
  */
 package android.support.v17.leanback.util;
 
+import android.support.annotation.RestrictTo;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * 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:
@@ -27,6 +31,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class StateMachine {
 
     /**
@@ -46,7 +51,7 @@
     public static class State {
 
         private int mStatus;
-        private ArrayList<State> mPriorStates;
+        ArrayList<State> mPriorStates;
 
         /**
          * Run State, Subclass may override.
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/AbstractDetailsDescriptionPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/AbstractDetailsDescriptionPresenter.java
index 88469bb..f603536 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/AbstractDetailsDescriptionPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/AbstractDetailsDescriptionPresenter.java
@@ -37,20 +37,20 @@
      * The ViewHolder for the {@link AbstractDetailsDescriptionPresenter}.
      */
     public static class ViewHolder extends Presenter.ViewHolder {
-        private final TextView mTitle;
-        private final TextView mSubtitle;
-        private final TextView mBody;
-        private final int mTitleMargin;
-        private final int mUnderTitleBaselineMargin;
-        private final int mUnderSubtitleBaselineMargin;
-        private final int mTitleLineSpacing;
-        private final int mBodyLineSpacing;
-        private final int mBodyMaxLines;
-        private final int mBodyMinLines;
-        private final FontMetricsInt mTitleFontMetricsInt;
-        private final FontMetricsInt mSubtitleFontMetricsInt;
-        private final FontMetricsInt mBodyFontMetricsInt;
-        private final int mTitleMaxLines;
+        final TextView mTitle;
+        final TextView mSubtitle;
+        final TextView mBody;
+        final int mTitleMargin;
+        final int mUnderTitleBaselineMargin;
+        final int mUnderSubtitleBaselineMargin;
+        final int mTitleLineSpacing;
+        final int mBodyLineSpacing;
+        final int mBodyMaxLines;
+        final int mBodyMinLines;
+        final FontMetricsInt mTitleFontMetricsInt;
+        final FontMetricsInt mSubtitleFontMetricsInt;
+        final FontMetricsInt mBodyFontMetricsInt;
+        final int mTitleMaxLines;
         private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
 
         public ViewHolder(final View view) {
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 25fddb6..87652dc 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaItemPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/AbstractMediaItemPresenter.java
@@ -153,22 +153,22 @@
      */
     public static class ViewHolder extends RowPresenter.ViewHolder {
 
-        private final View mMediaRowView;
-        private final View mSelectorView;
+        final View mMediaRowView;
+        final View mSelectorView;
         private final View mMediaItemDetailsView;
-        private final ViewFlipper mMediaItemNumberViewFlipper;
-        private final TextView mMediaItemNumberView;
-        private final View mMediaItemPausedView;
+        final ViewFlipper mMediaItemNumberViewFlipper;
+        final TextView mMediaItemNumberView;
+        final View mMediaItemPausedView;
 
-        private final View mMediaItemPlayingView;
+        final View mMediaItemPlayingView;
         private final TextView mMediaItemNameView;
         private final TextView mMediaItemDurationView;
         private final View mMediaItemRowSeparator;
         private final ViewGroup mMediaItemActionsContainer;
         private final List<Presenter.ViewHolder> mActionViewHolders;
-        private MultiActionsProvider.MultiAction[] mMediaItemRowActions;
+        MultiActionsProvider.MultiAction[] mMediaItemRowActions;
         AbstractMediaItemPresenter mRowPresenter;
-        private ValueAnimator mFocusViewAnimator;
+        ValueAnimator mFocusViewAnimator;
 
         public ViewHolder(View view) {
             super(view);
@@ -582,7 +582,7 @@
      * @param isDetails Whether the changed-focused view is for a media item details (true) or
      *                  an action (false).
      */
-    private static ValueAnimator updateSelector(final View selectorView,
+    static ValueAnimator updateSelector(final View selectorView,
             View focusChangedView, ValueAnimator layoutAnimator, boolean isDetails) {
         int animationDuration = focusChangedView.getContext().getResources()
                 .getInteger(android.R.integer.config_shortAnimTime);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/BackgroundHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/BackgroundHelper.java
index 2df10a8..e9e1581 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/BackgroundHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/BackgroundHelper.java
@@ -17,23 +17,30 @@
 
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.widget.BackgroundHelperKitkat;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 
 /**
  * Helper for view backgrounds.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class BackgroundHelper {
 
     final static BackgroundHelperVersionImpl sImpl;
 
-    static interface BackgroundHelperVersionImpl {
-        public void setBackgroundPreservingAlpha(View view, Drawable drawable);
+    interface BackgroundHelperVersionImpl {
+        void setBackgroundPreservingAlpha(View view, Drawable drawable);
     }
 
     private static final class BackgroundHelperStubImpl implements BackgroundHelperVersionImpl {
+        BackgroundHelperStubImpl() {
+        }
+
         @Override
         public void setBackgroundPreservingAlpha(View view, Drawable drawable) {
             // Cannot query drawable alpha
@@ -42,6 +49,9 @@
     }
 
     private static final class BackgroundHelperKitkatImpl implements BackgroundHelperVersionImpl {
+        BackgroundHelperKitkatImpl() {
+        }
+
         @Override
         public void setBackgroundPreservingAlpha(View view, Drawable drawable) {
             BackgroundHelperKitkat.setBackgroundPreservingAlpha(view, drawable);
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 40127dc..20308c5 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/BaseCardView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/BaseCardView.java
@@ -115,8 +115,8 @@
     private int mExtraVisibility;
 
     private ArrayList<View> mMainViewList;
-    private ArrayList<View> mInfoViewList;
-    private ArrayList<View> mExtraViewList;
+    ArrayList<View> mInfoViewList;
+    ArrayList<View> mExtraViewList;
 
     private int mMeasuredWidth;
     private int mMeasuredHeight;
@@ -125,9 +125,9 @@
     private final int mActivatedAnimDuration;
     private final int mSelectedAnimDuration;
 
-    private float mInfoOffset;
-    private float mInfoVisFraction;
-    private float mInfoAlpha = 1.0f;
+    float mInfoOffset;
+    float mInfoVisFraction;
+    float mInfoAlpha = 1.0f;
     private Animation mAnim;
 
     private final static int[] LB_PRESSED_STATE_SET = new int[]{
@@ -649,7 +649,7 @@
     // This animation changes the Y offset of the info and extra views,
     // so that they animate UP to make the extra info area visible when a
     // card is selected.
-    private void animateInfoOffset(boolean shown) {
+    void animateInfoOffset(boolean shown) {
         cancelAnimations();
 
         int extraHeight = 0;
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 013060f..82f5cfb 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/BaseGridView.java
@@ -16,6 +16,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.support.v7.widget.RecyclerView;
 import android.util.AttributeSet;
@@ -25,12 +26,15 @@
 import android.view.View;
 import android.support.v7.widget.SimpleItemAnimator;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * An abstract base class for vertically and horizontally scrolling lists. The items come
  * from the {@link RecyclerView.Adapter} associated with this view.
  * Do not directly use this class, use {@link VerticalGridView} and {@link HorizontalGridView}.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 abstract class BaseGridView extends RecyclerView {
 
     /**
@@ -187,7 +191,7 @@
     private OnTouchInterceptListener mOnTouchInterceptListener;
     private OnMotionInterceptListener mOnMotionInterceptListener;
     private OnKeyInterceptListener mOnKeyInterceptListener;
-    private RecyclerView.RecyclerListener mChainedRecyclerListener;
+    RecyclerView.RecyclerListener mChainedRecyclerListener;
     private OnUnhandledKeyListener mOnUnhandledKeyListener;
 
     public BaseGridView(Context context, AttributeSet attrs, int defStyle) {
@@ -328,7 +332,7 @@
      * Returns the offset percent for window alignment in addition to
      * {@link #getWindowAlignmentOffset()}.
      *
-     * @return Percentage to offset. E.g., 40 means 40% of the width from the 
+     * @return Percentage to offset. E.g., 40 means 40% of the width from the
      *         low edge, or {@link #WINDOW_ALIGN_OFFSET_PERCENT_DISABLED} if
      *         disabled. Default value is 50.
      */
@@ -932,6 +936,7 @@
      *                          Must be bigger or equals to 0.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setExtraLayoutSpace(int extraLayoutSpace) {
         mLayoutManager.setExtraLayoutSpace(extraLayoutSpace);
     }
@@ -941,6 +946,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public int getExtraLayoutSpace() {
         return mLayoutManager.getExtraLayoutSpace();
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/BrowseRowsFrameLayout.java b/v17/leanback/src/android/support/v17/leanback/widget/BrowseRowsFrameLayout.java
index 6b663ce..ec42537 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/BrowseRowsFrameLayout.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/BrowseRowsFrameLayout.java
@@ -14,16 +14,20 @@
 package android.support.v17.leanback.widget;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Customized FrameLayout excludes margin of child from calculating the child size.
  * So we can change left margin of rows while keep the width of rows unchanged without
  * using hardcoded DIPS.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class BrowseRowsFrameLayout extends FrameLayout {
 
     public BrowseRowsFrameLayout(Context context) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ControlBarPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/ControlBarPresenter.java
index e3f9ab8..f79f02f 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ControlBarPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ControlBarPresenter.java
@@ -30,7 +30,7 @@
  */
 class ControlBarPresenter extends Presenter {
 
-    private static final int MAX_CONTROLS = 7;
+    static final int MAX_CONTROLS = 7;
 
     /**
      * The data type expected by this presenter.
@@ -181,8 +181,8 @@
         }
     }
 
-    private OnControlClickedListener mOnControlClickedListener;
-    private OnControlSelectedListener mOnControlSelectedListener;
+    OnControlClickedListener mOnControlClickedListener;
+    OnControlSelectedListener mOnControlSelectedListener;
     private int mLayoutResourceId;
     private static int sChildMarginDefault;
     private static int sControlIconWidth;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.java
index 34c2004..88d7195 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewRowPresenter.java
@@ -65,8 +65,8 @@
 @Deprecated
 public class DetailsOverviewRowPresenter extends RowPresenter {
 
-    private static final String TAG = "DetailsOverviewRowPresenter";
-    private static final boolean DEBUG = false;
+    static final String TAG = "DetailsOverviewRowPresenter";
+    static final boolean DEBUG = false;
 
     private static final int MORE_ACTIONS_FADE_MS = 100;
     private static final long DEFAULT_TIMEOUT = 5000;
@@ -227,7 +227,7 @@
             return (view.getRight() - view.getLeft()) / 2;
         }
 
-        private void checkFirstAndLastPosition(boolean fromScroll) {
+        void checkFirstAndLastPosition(boolean fromScroll) {
             RecyclerView.ViewHolder viewHolder;
 
             viewHolder = mActionsRow.findViewHolderForPosition(mNumItems - 1);
@@ -289,8 +289,8 @@
         }
     }
 
-    private final Presenter mDetailsPresenter;
-    private OnActionClickedListener mActionClickedListener;
+    final Presenter mDetailsPresenter;
+    OnActionClickedListener mActionClickedListener;
 
     private int mBackgroundColor = Color.TRANSPARENT;
     private boolean mBackgroundColorSet;
@@ -460,7 +460,7 @@
         return (height > 0 ? height : 0);
     }
 
-    private void bindImageDrawable(ViewHolder vh) {
+    void bindImageDrawable(ViewHolder vh) {
         DetailsOverviewRow row = (DetailsOverviewRow) vh.getRow();
 
         ViewGroup.MarginLayoutParams layoutParams =
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 cac7d9e..937d328 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewSharedElementHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DetailsOverviewSharedElementHelper.java
@@ -36,15 +36,15 @@
 
 final class DetailsOverviewSharedElementHelper extends SharedElementCallback {
 
-    private static final String TAG = "DetailsOverviewSharedElementHelper";
-    private static final boolean DEBUG = false;
+    static final String TAG = "DetailsOverviewSharedElementHelper";
+    static final boolean DEBUG = false;
 
-    private ViewHolder mViewHolder;
-    private Activity mActivityToRunTransition;
-    private boolean mStartedPostpone;
-    private String mSharedElementName;
-    private int mRightPanelWidth;
-    private int mRightPanelHeight;
+    ViewHolder mViewHolder;
+    Activity mActivityToRunTransition;
+    boolean mStartedPostpone;
+    String mSharedElementName;
+    int mRightPanelWidth;
+    int mRightPanelHeight;
 
     private ScaleType mSavedScaleType;
     private Matrix mSavedMatrix;
@@ -255,7 +255,7 @@
         });
     }
 
-    private void startPostponedEnterTransition() {
+    void startPostponedEnterTransition() {
         if (!mStartedPostpone) {
             if (DEBUG) {
                 Log.d(TAG, "startPostponedEnterTransition " + mActivityToRunTransition);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/DividerPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/DividerPresenter.java
index 9ddd64c..44a2578 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/DividerPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/DividerPresenter.java
@@ -14,12 +14,15 @@
 package android.support.v17.leanback.widget;
 
 import android.graphics.Paint;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * DividerPresenter provides a default presentation for {@link DividerRow} in HeadersFragment.
  */
@@ -34,6 +37,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public DividerPresenter(int layoutResourceId) {
         mLayoutResourceId = layoutResourceId;
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHandler.java b/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHandler.java
index 6864527..9e11a4c 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHandler.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHandler.java
@@ -13,8 +13,11 @@
  */
 package android.support.v17.leanback.widget;
 
+import android.support.annotation.RestrictTo;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Interface for highlighting the item that has focus.
  */
@@ -26,6 +29,7 @@
      * @param view The view whose focus is changing.
      * @param hasFocus True if focus is gained; false otherwise.
      */
+    @RestrictTo(GROUP_ID)
     void onItemFocused(View view, boolean hasFocus);
 
     /**
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 87bbbd4..0990327 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/FocusHighlightHelper.java
@@ -35,7 +35,7 @@
         return zoomIndex == ZOOM_FACTOR_NONE || getResId(zoomIndex) > 0;
     }
 
-    private static int getResId(int zoomIndex) {
+    static int getResId(int zoomIndex) {
         switch (zoomIndex) {
             case ZOOM_FACTOR_SMALL:
                 return R.fraction.lb_focus_zoom_factor_small;
@@ -209,7 +209,7 @@
         private static boolean sInitialized;
         private static float sSelectScale;
         private static int sDuration;
-        private BaseGridView mGridView;
+        BaseGridView mGridView;
 
         HeaderItemFocusHighlight(BaseGridView gridView) {
             mGridView = gridView;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ForegroundHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/ForegroundHelper.java
index c9bed58..252a317 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ForegroundHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ForegroundHelper.java
@@ -24,6 +24,9 @@
      * Implementation used on api 23 (and above).
      */
     private static final class ForegroundHelperApi23Impl implements ForegroundHelperVersionImpl {
+        ForegroundHelperApi23Impl() {
+        }
+
         @Override
         public void setForeground(View view, Drawable drawable) {
             ForegroundHelperApi23.setForeground(view, drawable);
@@ -39,6 +42,9 @@
      * Stub implementation
      */
     private static final class ForegroundHelperStubImpl implements ForegroundHelperVersionImpl {
+        ForegroundHelperStubImpl() {
+        }
+
         @Override
         public void setForeground(View view, Drawable drawable) {
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewRowPresenter.java
index 7c9d5db..4b02418 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewRowPresenter.java
@@ -71,11 +71,11 @@
  */
 public class FullWidthDetailsOverviewRowPresenter extends RowPresenter {
 
-    private static final String TAG = "FullWidthDetailsOverviewRowPresenter";
-    private static final boolean DEBUG = false;
+    static final String TAG = "FullWidthDetailsOverviewRowPresenter";
+    static final boolean DEBUG = false;
 
     private static Rect sTmpRect = new Rect();
-    private static final Handler sHandler = new Handler();
+    static final Handler sHandler = new Handler();
 
     /**
      * This is the default state corresponding to layout file.  The view takes full width
@@ -290,7 +290,7 @@
             return (view.getRight() - view.getLeft()) / 2;
         }
 
-        private void checkFirstAndLastPosition(boolean fromScroll) {
+        void checkFirstAndLastPosition(boolean fromScroll) {
             RecyclerView.ViewHolder viewHolder;
 
             viewHolder = mActionsRow.findViewHolderForPosition(mNumItems - 1);
@@ -383,9 +383,9 @@
 
     protected int mInitialState = STATE_HALF;
 
-    private final Presenter mDetailsPresenter;
-    private final DetailsOverviewLogoPresenter mDetailsOverviewLogoPresenter;
-    private OnActionClickedListener mActionClickedListener;
+    final Presenter mDetailsPresenter;
+    final DetailsOverviewLogoPresenter mDetailsOverviewLogoPresenter;
+    OnActionClickedListener mActionClickedListener;
 
     private int mBackgroundColor = Color.TRANSPARENT;
     private int mActionsBackgroundColor = Color.TRANSPARENT;
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 a9fe9ec..9fd8815 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewSharedElementHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/FullWidthDetailsOverviewSharedElementHelper.java
@@ -46,15 +46,15 @@
 public class FullWidthDetailsOverviewSharedElementHelper extends
         FullWidthDetailsOverviewRowPresenter.Listener {
 
-    private static final String TAG = "FullWidthDetailsOverviewSharedElementHelper";
-    private static final boolean DEBUG = false;
+    static final String TAG = "FullWidthDetailsOverviewSharedElementHelper";
+    static final boolean DEBUG = false;
 
     private static final long DEFAULT_TIMEOUT = 5000;
 
-    private ViewHolder mViewHolder;
-    private Activity mActivityToRunTransition;
+    ViewHolder mViewHolder;
+    Activity mActivityToRunTransition;
     private boolean mStartedPostpone;
-    private String mSharedElementName;
+    String mSharedElementName;
     private boolean mAutoStartSharedElementTransition = true;
 
     public void setSharedElementEnterTransition(Activity activity, String sharedElementName) {
@@ -174,7 +174,7 @@
         });
     }
 
-    private void startPostponedEnterTransitionInternal() {
+    void startPostponedEnterTransitionInternal() {
         if (!mStartedPostpone && mViewHolder != null) {
             if (DEBUG) {
                 Log.d(TAG, "startPostponedEnterTransition " + 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 1c6c4b0..0a21ddd 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GridLayoutManager.java
@@ -58,10 +58,10 @@
     final static class LayoutParams extends RecyclerView.LayoutParams {
 
         // For placement
-        private int mLeftInset;
-        private int mTopInset;
-        private int mRightInset;
-        private int mBottomInset;
+        int mLeftInset;
+        int mTopInset;
+        int mRightInset;
+        int mBottomInset;
 
         // For alignment
         private int mAlignX;
@@ -366,20 +366,20 @@
     };
 
     private static final String TAG = "GridLayoutManager";
-    private static final boolean DEBUG = false;
-    private static final boolean TRACE = false;
+    static final boolean DEBUG = false;
+    static final boolean TRACE = false;
 
     // maximum pending movement in one direction.
-    private final static int MAX_PENDING_MOVES = 10;
+    final static int MAX_PENDING_MOVES = 10;
     // minimal milliseconds to scroll window size in major direction,  we put a cap to prevent the
     // effect smooth scrolling too over to bind an item view then drag the item view back.
-    private final static int MIN_MS_SMOOTH_SCROLL_MAIN_SCREEN = 30;
+    final static int MIN_MS_SMOOTH_SCROLL_MAIN_SCREEN = 30;
 
-    private String getTag() {
+    String getTag() {
         return TAG + ":" + mBaseGridView.getId();
     }
 
-    private final BaseGridView mBaseGridView;
+    final BaseGridView mBaseGridView;
 
     /**
      * Note on conventions in the presence of RTL layout directions:
@@ -408,47 +408,47 @@
     /**
      * The orientation of a "row".
      */
-    private int mOrientation = HORIZONTAL;
+    int mOrientation = HORIZONTAL;
     private OrientationHelper mOrientationHelper = OrientationHelper.createHorizontalHelper(this);
 
-    private RecyclerView.State mState;
-    private RecyclerView.Recycler mRecycler;
+    RecyclerView.State mState;
+    RecyclerView.Recycler mRecycler;
 
     private static final Rect sTempRect = new Rect();
 
-    private boolean mInLayout;
+    boolean mInLayout;
     private boolean mInScroll;
-    private boolean mInFastRelayout;
+    boolean mInFastRelayout;
     /**
      * During full layout pass, when GridView had focus: onLayoutChildren will
      * skip non-focusable child and adjust mFocusPosition.
      */
-    private boolean mInLayoutSearchFocus;
-    private boolean mInSelection = false;
+    boolean mInLayoutSearchFocus;
+    boolean mInSelection = false;
 
     private OnChildSelectedListener mChildSelectedListener = null;
 
     private ArrayList<OnChildViewHolderSelectedListener> mChildViewHolderSelectedListeners = null;
 
-    private OnChildLaidOutListener mChildLaidOutListener = null;
+    OnChildLaidOutListener mChildLaidOutListener = null;
 
     /**
      * The focused position, it's not the currently visually aligned position
      * but it is the final position that we intend to focus on. If there are
      * multiple setSelection() called, mFocusPosition saves last value.
      */
-    private int mFocusPosition = NO_POSITION;
+    int mFocusPosition = NO_POSITION;
 
     /**
      * A view can have multiple alignment position,  this is the index of which
      * alignment is used,  by default is 0.
      */
-    private int mSubFocusPosition = 0;
+    int mSubFocusPosition = 0;
 
     /**
      * LinearSmoothScroller that consume pending DPAD movements.
      */
-    private PendingMoveSmoothScroller mPendingMoveSmoothScroller;
+    PendingMoveSmoothScroller mPendingMoveSmoothScroller;
 
     /**
      * The offset to be applied to mFocusPosition, due to adapter change, on the next
@@ -477,13 +477,13 @@
     /**
      * override child visibility
      */
-    private int mChildVisibility = -1;
+    int mChildVisibility = -1;
 
     /**
      * The scroll offsets of the viewport relative to the entire view.
      */
     private int mScrollOffsetPrimary;
-    private int mScrollOffsetSecondary;
+    int mScrollOffsetSecondary;
 
     /**
      * User-specified row height/column width.  Can be WRAP_CONTENT.
@@ -536,7 +536,7 @@
     /**
      * The number of rows in the grid.
      */
-    private int mNumRows;
+    int mNumRows;
     /**
      * Number of rows requested, can be 0 to be determined by parent size and
      * rowHeight.
@@ -555,7 +555,7 @@
     /**
      * Defines how item view is aligned in the window.
      */
-    private final WindowAlignment mWindowAlignment = new WindowAlignment();
+    final WindowAlignment mWindowAlignment = new WindowAlignment();
 
     /**
      * Defines how item view is aligned.
@@ -612,12 +612,12 @@
     /**
      * Temporary variable: an int array of length=2.
      */
-    private static int[] sTwoInts = new int[2];
+    static int[] sTwoInts = new int[2];
 
     /**
      * Set to true for RTL layout in horizontal orientation
      */
-    private boolean mReverseFlowPrimary = false;
+    boolean mReverseFlowPrimary = false;
 
     /**
      * Set to true for RTL layout in vertical orientation
@@ -858,7 +858,7 @@
         return params.getViewPosition();
     }
 
-    private int getSubPositionByView(View view, View childView) {
+    int getSubPositionByView(View view, View childView) {
         if (view == null || childView == null) {
             return 0;
         }
@@ -887,7 +887,7 @@
         return getPositionByView(getChildAt(index));
     }
 
-    private void dispatchChildSelected() {
+    void dispatchChildSelected() {
         if (mChildSelectedListener == null && !hasOnChildViewHolderSelectedListener()) {
             return;
         }
@@ -1019,15 +1019,15 @@
         outBounds.bottom -= params.mBottomInset;
     }
 
-    private int getViewMin(View v) {
+    int getViewMin(View v) {
         return mOrientationHelper.getDecoratedStart(v);
     }
 
-    private int getViewMax(View v) {
+    int getViewMax(View v) {
         return mOrientationHelper.getDecoratedEnd(v);
     }
 
-    private int getViewPrimarySize(View view) {
+    int getViewPrimarySize(View view) {
         getDecoratedBoundsWithMargins(view, sTempRect);
         return mOrientation == HORIZONTAL ? sTempRect.width() : sTempRect.height();
     }
@@ -1142,7 +1142,7 @@
         return mRowSizeSecondary[rowIndex];
     }
 
-    private int getRowStartSecondary(int rowIndex) {
+    int getRowStartSecondary(int rowIndex) {
         int start = 0;
         // Iterate from left to right, which is a different index traversal
         // in RTL flow
@@ -1402,7 +1402,7 @@
         leaveContext();
     }
 
-    private void measureChild(View child) {
+    void measureChild(View child) {
         if (TRACE) TraceHelper.beginSection("measureChild");
         final LayoutParams lp = (LayoutParams) child.getLayoutParams();
         calculateItemDecorationsForChild(child, sTempRect);
@@ -1434,9 +1434,9 @@
     }
 
     /**
-     * Get facet from the ViewHolder or the viewType. 
+     * Get facet from the ViewHolder or the viewType.
      */
-    private <E> E getFacet(RecyclerView.ViewHolder vh, Class<? extends E> facetClass) {
+    <E> E getFacet(RecyclerView.ViewHolder vh, Class<? extends E> facetClass) {
         E facet = null;
         if (vh instanceof FacetProvider) {
             facet = (E) ((FacetProvider) vh).getFacet(facetClass);
@@ -1594,7 +1594,7 @@
         }
     };
 
-    private void layoutChild(int rowIndex, View v, int start, int end, int startSecondary) {
+    void layoutChild(int rowIndex, View v, int start, int end, int startSecondary) {
         if (TRACE) TraceHelper.beginSection("layoutChild");
         int sizeSecondary = mOrientation == HORIZONTAL ? getDecoratedMeasuredHeightWithMargin(v)
                 : getDecoratedMeasuredWidthWithMargin(v);
@@ -1711,7 +1711,7 @@
     /**
      * Fast layout when there is no structure change, adapter change, etc.
      * It will layout all views was layout requested or updated, until hit a view
-     * with different size,  then it break and detachAndScrap all views after that. 
+     * with different size,  then it break and detachAndScrap all views after that.
      */
     private void fastRelayout() {
         boolean invalidateAfter = false;
@@ -2088,7 +2088,7 @@
         return dy;
     }
 
-    private void updateScrollMax() {
+    void updateScrollMax() {
         int highVisiblePos = (!mReverseFlowPrimary) ? mGrid.getLastVisibleIndex()
                 : mGrid.getFirstVisibleIndex();
         int highMaxPos = (!mReverseFlowPrimary) ? mState.getItemCount() - 1 : 0;
@@ -2120,7 +2120,7 @@
         }
     }
 
-    private void updateScrollMin() {
+    void updateScrollMin() {
         int lowVisiblePos = (!mReverseFlowPrimary) ? mGrid.getFirstVisibleIndex()
                 : mGrid.getLastVisibleIndex();
         int lowMinPos = (!mReverseFlowPrimary) ? 0 : mState.getItemCount() - 1;
@@ -2243,7 +2243,7 @@
         }
     }
 
-    private void scrollToSelection(int position, int subposition,
+    void scrollToSelection(int position, int subposition,
             boolean smooth, int primaryScrollExtra) {
         if (TRACE) TraceHelper.beginSection("scrollToSelection");
         mPrimaryScrollExtra = primaryScrollExtra;
@@ -2505,7 +2505,7 @@
     /**
      * Scroll to a given child view and change mFocusPosition.
      */
-    private void scrollToView(View view, boolean smooth) {
+    void scrollToView(View view, boolean smooth) {
         scrollToView(view, view == null ? null : view.findFocus(), smooth);
     }
 
@@ -2542,7 +2542,7 @@
         }
     }
 
-    private boolean getScrollPosition(View view, View childView, int[] deltas) {
+    boolean getScrollPosition(View view, View childView, int[] deltas) {
         switch (mFocusScrollStrategy) {
         case BaseGridView.FOCUS_SCROLL_ALIGNED:
         default:
@@ -2967,12 +2967,12 @@
         return true;
     }
 
-    private boolean hasCreatedLastItem() {
+    boolean hasCreatedLastItem() {
         int count = getItemCount();
         return count == 0 || mBaseGridView.findViewHolderForAdapterPosition(count - 1) != null;
     }
 
-    private boolean hasCreatedFirstItem() {
+    boolean hasCreatedFirstItem() {
         int count = getItemCount();
         return count == 0 || mBaseGridView.findViewHolderForAdapterPosition(0) != null;
     }
@@ -3285,7 +3285,7 @@
      * Stops when moves are all consumed or reach first/last visible item.
      * Returning remaining moves.
      */
-    private int processSelectionMoves(boolean preventScroll, int moves) {
+    int processSelectionMoves(boolean preventScroll, int moves) {
         if (mGrid == null) {
             return moves;
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidanceStylingRelativeLayout.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidanceStylingRelativeLayout.java
index 31c5770..2bd7d28 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidanceStylingRelativeLayout.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidanceStylingRelativeLayout.java
@@ -16,8 +16,6 @@
  *
  * Repositioning child views in PreDraw callback in {@link GuidanceStylist} was interfering with
  * fragment transition. To avoid that, we do that in the onLayout pass.
- *
- * @hide
  */
 class GuidanceStylingRelativeLayout extends RelativeLayout {
     private float mTitleKeylinePercent;
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 22ac504..62ff2d7 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedAction.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedAction.java
@@ -575,28 +575,28 @@
 
     }
 
-    private static final int PF_CHECKED = 0x00000001;
-    private static final int PF_MULTI_lINE_DESCRIPTION = 0x00000002;
-    private static final int PF_HAS_NEXT = 0x00000004;
-    private static final int PF_INFO_ONLY = 0x00000008;
-    private static final int PF_ENABLED = 0x00000010;
-    private static final int PF_FOCUSABLE = 0x00000020;
-    private static final int PF_AUTORESTORE = 0x00000040;
-    private int mActionFlags;
+    static final int PF_CHECKED = 0x00000001;
+    static final int PF_MULTI_lINE_DESCRIPTION = 0x00000002;
+    static final int PF_HAS_NEXT = 0x00000004;
+    static final int PF_INFO_ONLY = 0x00000008;
+    static final int PF_ENABLED = 0x00000010;
+    static final int PF_FOCUSABLE = 0x00000020;
+    static final int PF_AUTORESTORE = 0x00000040;
+    int mActionFlags;
 
     private CharSequence mEditTitle;
     private CharSequence mEditDescription;
-    private int mEditable;
-    private int mInputType;
-    private int mDescriptionInputType;
-    private int mEditInputType;
-    private int mDescriptionEditInputType;
+    int mEditable;
+    int mInputType;
+    int mDescriptionInputType;
+    int mEditInputType;
+    int mDescriptionEditInputType;
 
-    private int mCheckSetId;
+    int mCheckSetId;
 
-    private List<GuidedAction> mSubActions;
+    List<GuidedAction> mSubActions;
 
-    private Intent mIntent;
+    Intent mIntent;
 
     protected GuidedAction() {
         super(0);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionAdapter.java
index 04a0674..f0cc699 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionAdapter.java
@@ -16,6 +16,7 @@
 import android.content.Context;
 import android.database.DataSetObserver;
 import android.media.AudioManager;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.support.v7.widget.RecyclerView;
 import android.support.v7.widget.RecyclerView.ViewHolder;
@@ -36,6 +37,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * GuidedActionAdapter instantiates views for guided actions, and manages their interactions.
  * Presentation (view creation and state animation) is delegated to a {@link
@@ -43,12 +46,13 @@
  * {@link GuidedActionAdapter.ClickListener} and {@link GuidedActionAdapter.FocusListener}.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class GuidedActionAdapter extends RecyclerView.Adapter {
-    private static final String TAG = "GuidedActionAdapter";
-    private static final boolean DEBUG = false;
+    static final String TAG = "GuidedActionAdapter";
+    static final boolean DEBUG = false;
 
-    private static final String TAG_EDIT = "EditableAction";
-    private static final boolean DEBUG_EDIT = false;
+    static final String TAG_EDIT = "EditableAction";
+    static final boolean DEBUG_EDIT = false;
 
     /**
      * Object listening for click events within a {@link GuidedActionAdapter}.
@@ -105,7 +109,7 @@
     private final ActionEditListener mActionEditListener;
     private final List<GuidedAction> mActions;
     private ClickListener mClickListener;
-    private final GuidedActionsStylist mStylist;
+    final GuidedActionsStylist mStylist;
     private final View.OnClickListener mOnClickListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
@@ -215,6 +219,7 @@
      * Used for serialization only.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public List<GuidedAction> getActions() {
         return new ArrayList<GuidedAction>(mActions);
     }
@@ -227,7 +232,7 @@
         return mStylist.getItemViewType(mActions.get(position));
     }
 
-    private RecyclerView getRecyclerView() {
+    RecyclerView getRecyclerView() {
         return mIsSubAdapter ? mStylist.getSubActionsGridView() : mStylist.getActionsGridView();
     }
 
@@ -390,6 +395,9 @@
 
         private boolean mKeyPressed = false;
 
+        ActionOnKeyListener() {
+        }
+
         /**
          * Now only handles KEYCODE_ENTER and KEYCODE_NUMPAD_ENTER key event.
          */
@@ -454,6 +462,9 @@
     private class ActionEditListener implements OnEditorActionListener,
             ImeKeyMonitor.ImeKeyListener {
 
+        ActionEditListener() {
+        }
+
         @Override
         public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
             if (DEBUG_EDIT) Log.v(TAG_EDIT, "IME action: " + actionId);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionAdapterGroup.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionAdapterGroup.java
index 7198300..dafa49b 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionAdapterGroup.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionAdapterGroup.java
@@ -14,6 +14,7 @@
 package android.support.v17.leanback.widget;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.widget.GuidedActionAdapter.ClickListener;
 import android.support.v17.leanback.widget.GuidedActionAdapter.EditListener;
 import android.util.Log;
@@ -28,11 +29,14 @@
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Internal implementation manages a group of GuidedActionAdapters, control the next action after
  * editing finished, maintain the Ime open/close status.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class GuidedActionAdapterGroup {
 
     private static final String TAG_EDIT = "EditableAction";
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionItemContainer.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionItemContainer.java
index 47c36f9..f00b870 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionItemContainer.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionItemContainer.java
@@ -14,14 +14,16 @@
 package android.support.v17.leanback.widget;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewParent;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Root view of GuidedAction item, it supports a foreground drawable and can disable focus out
  * of view.
- * @hide
  */
 class GuidedActionItemContainer extends NonOverlappingLinearLayoutWithForeground {
 
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
index 94288a0..9c0b43e 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
@@ -20,6 +20,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build.VERSION;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.support.v17.leanback.transition.TransitionHelper;
 import android.support.v17.leanback.transition.TransitionListener;
@@ -47,6 +48,7 @@
 import java.util.Collections;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v17.leanback.widget.GuidedAction.EDITING_ACTIVATOR_VIEW;
 import static android.support.v17.leanback.widget.GuidedAction.EDITING_DESCRIPTION;
 import static android.support.v17.leanback.widget.GuidedAction.EDITING_NONE;
@@ -163,15 +165,15 @@
      */
     public static class ViewHolder extends RecyclerView.ViewHolder implements FacetProvider {
 
-        private GuidedAction mAction;
+        GuidedAction mAction;
         private View mContentView;
-        private TextView mTitleView;
-        private TextView mDescriptionView;
-        private View mActivatorView;
-        private ImageView mIconView;
-        private ImageView mCheckmarkView;
-        private ImageView mChevronView;
-        private int mEditingMode = EDITING_NONE;
+        TextView mTitleView;
+        TextView mDescriptionView;
+        View mActivatorView;
+        ImageView mIconView;
+        ImageView mCheckmarkView;
+        ImageView mChevronView;
+        int mEditingMode = EDITING_NONE;
         private final boolean mIsSubAction;
 
         final AccessibilityDelegate mDelegate = new AccessibilityDelegate() {
@@ -362,9 +364,9 @@
 
     private static String TAG = "GuidedActionsStylist";
 
-    private ViewGroup mMainView;
+    ViewGroup mMainView;
     private VerticalGridView mActionsGridView;
-    private VerticalGridView mSubActionsGridView;
+    VerticalGridView mSubActionsGridView;
     private View mSubActionsBackground;
     private View mBgView;
     private View mContentView;
@@ -386,7 +388,7 @@
     private EditListener mEditListener;
 
     private GuidedAction mExpandedAction = null;
-    private Object mExpandTransition;
+    Object mExpandTransition;
 
     /**
      * Creates a view appropriate for displaying a list of GuidedActions, using the provided
@@ -890,6 +892,7 @@
      * Sets listener for reporting view being edited.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setEditListener(EditListener listener) {
         mEditListener = listener;
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedDatePickerAction.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedDatePickerAction.java
index 9b9f29f..d655e85 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedDatePickerAction.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedDatePickerAction.java
@@ -125,10 +125,10 @@
         }
     }
 
-    private String mDatePickerFormat;
-    private long mDate;
-    private long mMinDate = Long.MIN_VALUE;
-    private long mMaxDate = Long.MAX_VALUE;
+    String mDatePickerFormat;
+    long mDate;
+    long mMinDate = Long.MIN_VALUE;
+    long mMaxDate = Long.MAX_VALUE;
 
     /**
      * Returns format of date Picker or null if not specified.  The format is a case insensitive
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/InvisibleRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/InvisibleRowPresenter.java
index ff27d92..2b5c7f0 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/InvisibleRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/InvisibleRowPresenter.java
@@ -13,13 +13,17 @@
  */
 package android.support.v17.leanback.widget;
 
+import android.support.annotation.RestrictTo;
 import android.view.ViewGroup;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class InvisibleRowPresenter extends RowPresenter {
 
     public InvisibleRowPresenter() {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapter.java
index 57e8bfe..d2d3356 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ItemBridgeAdapter.java
@@ -25,8 +25,8 @@
  * party Presenters.
  */
 public class ItemBridgeAdapter extends RecyclerView.Adapter implements FacetProviderAdapter {
-    private static final String TAG = "ItemBridgeAdapter";
-    private static final boolean DEBUG = false;
+    static final String TAG = "ItemBridgeAdapter";
+    static final boolean DEBUG = false;
 
     /**
      * Interface for listening to ViewHolder operations.
@@ -56,9 +56,9 @@
     }
 
     private ObjectAdapter mAdapter;
-    private Wrapper mWrapper;
+    Wrapper mWrapper;
     private PresenterSelector mPresenterSelector;
-    private FocusHighlightHandler mFocusHighlight;
+    FocusHighlightHandler mFocusHighlight;
     private AdapterListener mAdapterListener;
     private ArrayList<Presenter> mPresenters = new ArrayList<Presenter>();
 
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ListRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/ListRowPresenter.java
index 94acd99..200b6d9 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ListRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ListRowPresenter.java
@@ -132,7 +132,7 @@
 
         private int mItemPosition;
         private boolean mSmoothScroll = true;
-        private Presenter.ViewHolderTask mItemTask;
+        Presenter.ViewHolderTask mItemTask;
 
         public SelectItemViewHolderTask(int itemPosition) {
             setItemPosition(itemPosition);
@@ -280,7 +280,7 @@
     private boolean mRoundedCornersEnabled = true;
     private boolean mKeepChildForeground = true;
     private HashMap<Presenter, Integer> mRecycledPoolSize = new HashMap<Presenter, Integer>();
-    private ShadowOverlayHelper mShadowOverlayHelper;
+    ShadowOverlayHelper mShadowOverlayHelper;
     private ItemBridgeAdapter.Wrapper mShadowOverlayWrapper;
 
     private static int sSelectedRowTopPadding;
@@ -425,7 +425,7 @@
         FocusHighlightHelper.setupBrowseItemFocusHighlight(rowViewHolder.mItemBridgeAdapter,
                 mFocusZoomFactor, mUseFocusDimmer);
         rowViewHolder.mGridView.setFocusDrawingOrderEnabled(mShadowOverlayHelper.getShadowType()
-                == ShadowOverlayHelper.SHADOW_STATIC);
+                != ShadowOverlayHelper.SHADOW_DYNAMIC);
         rowViewHolder.mGridView.setOnChildSelectedListener(
                 new OnChildSelectedListener() {
             @Override
@@ -484,7 +484,7 @@
     /*
      * Perform operations when a child of horizontal grid view is selected.
      */
-    private void selectChildView(ViewHolder rowViewHolder, View view, boolean fireEvent) {
+    void selectChildView(ViewHolder rowViewHolder, View view, boolean fireEvent) {
         if (view != null) {
             if (rowViewHolder.mSelected) {
                 ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder)
@@ -677,9 +677,9 @@
     }
 
     /**
-     * Returns true if SDK >= 18, where default shadow
-     * is applied to each individual child of {@link HorizontalGridView}.
-     * Subclass may return false to disable.
+     * Default implementation returns true if SDK version >= 21, shadow (either static or z-order
+     * based) will be applied to each individual child of {@link HorizontalGridView}.
+     * Subclass may return false to disable default implementation of shadow and provide its own.
      */
     public boolean isUsingDefaultShadow() {
         return ShadowOverlayHelper.supportsShadow();
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/MediaNowPlayingView.java b/v17/leanback/src/android/support/v17/leanback/widget/MediaNowPlayingView.java
index f62fde5..cb2691c 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/MediaNowPlayingView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/MediaNowPlayingView.java
@@ -17,6 +17,7 @@
 import android.animation.AnimatorInflater;
 import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -24,10 +25,13 @@
 import android.widget.LinearLayout;
 import android.support.v17.leanback.R;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * The view displaying 3 animated peak meters next to each other when a media item is playing.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class MediaNowPlayingView extends LinearLayout{
 
     private final ImageView mImage1;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/NonOverlappingLinearLayoutWithForeground.java b/v17/leanback/src/android/support/v17/leanback/widget/NonOverlappingLinearLayoutWithForeground.java
index a486fc1..8242caa 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/NonOverlappingLinearLayoutWithForeground.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/NonOverlappingLinearLayoutWithForeground.java
@@ -19,12 +19,14 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build.VERSION;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.widget.LinearLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Implements foreground drawable before M and falls back to M's foreground implementation.
- * @hide
  */
 class NonOverlappingLinearLayoutWithForeground extends LinearLayout {
 
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ObjectAdapter.java b/v17/leanback/src/android/support/v17/leanback/widget/ObjectAdapter.java
index c464814..026d9a0 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ObjectAdapter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ObjectAdapter.java
@@ -72,6 +72,9 @@
 
     private static final class DataObservable extends Observable<DataObserver> {
 
+        DataObservable() {
+        }
+
         public void notifyChanged() {
             for (int i = mObservers.size() - 1; i >= 0; i--) {
                 mObservers.get(i).onChanged();
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PagingIndicator.java b/v17/leanback/src/android/support/v17/leanback/widget/PagingIndicator.java
index 94ab8d8..10f2f82 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PagingIndicator.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PagingIndicator.java
@@ -31,6 +31,7 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.support.annotation.ColorInt;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.VisibleForTesting;
 import android.support.v17.leanback.R;
 import android.util.AttributeSet;
@@ -38,10 +39,13 @@
 import android.view.View;
 import android.view.animation.DecelerateInterpolator;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A page indicator with dots.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class PagingIndicator extends View {
     private static final long DURATION_ALPHA = 167;
     private static final long DURATION_DIAMETER = 417;
@@ -88,12 +92,12 @@
     };
 
     // attribute
-    private boolean mIsLtr;
-    private final int mDotDiameter;
-    private final int mDotRadius;
+    boolean mIsLtr;
+    final int mDotDiameter;
+    final int mDotRadius;
     private final int mDotGap;
-    private final int mArrowDiameter;
-    private final int mArrowRadius;
+    final int mArrowDiameter;
+    final int mArrowRadius;
     private final int mArrowGap;
     private final int mShadowRadius;
     private Dot[] mDots;
@@ -103,7 +107,7 @@
     private int[] mDotSelectedPrevX;
     // X position when the dot is located to the right of the selected dot.
     private int[] mDotSelectedNextX;
-    private int mDotCenterY;
+    int mDotCenterY;
 
     // state
     private int mPageCount;
@@ -112,15 +116,15 @@
 
     // drawing
     @ColorInt
-    private final int mDotFgSelectColor;
-    private final Paint mBgPaint;
-    private final Paint mFgPaint;
+    final int mDotFgSelectColor;
+    final Paint mBgPaint;
+    final Paint mFgPaint;
     private final AnimatorSet mShowAnimator;
     private final AnimatorSet mHideAnimator;
     private final AnimatorSet mAnimator = new AnimatorSet();
-    private Bitmap mArrow;
-    private final Rect mArrowRect;
-    private final float mArrowToBgRatio;
+    Bitmap mArrow;
+    final Rect mArrowRect;
+    final float mArrowToBgRatio;
 
     public PagingIndicator(Context context) {
         this(context, null, 0);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PersistentFocusWrapper.java b/v17/leanback/src/android/support/v17/leanback/widget/PersistentFocusWrapper.java
index eb9ada4..ed057de 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PersistentFocusWrapper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PersistentFocusWrapper.java
@@ -31,7 +31,6 @@
 /**
  * Saves the focused grandchild position.
  * Helps add persistent focus feature to various ViewGroups.
- * @hide
  */
 class PersistentFocusWrapper extends FrameLayout {
 
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 17225f8..da6c98d 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsPresenter.java
@@ -179,7 +179,7 @@
         }
     }
 
-    private static void formatTime(int seconds, StringBuilder sb) {
+    static void formatTime(int seconds, StringBuilder sb) {
         int minutes = seconds / 60;
         int hours = minutes / 60;
         seconds -= minutes * 60;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRow.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRow.java
index 642beef..098cf60 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRow.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRow.java
@@ -587,7 +587,7 @@
         }
     }
 
-    private static Bitmap createBitmap(Bitmap bitmap, int color) {
+    static Bitmap createBitmap(Bitmap bitmap, int color) {
         Bitmap dst = bitmap.copy(bitmap.getConfig(), true);
         Canvas canvas = new Canvas(dst);
         Paint paint = new Paint();
@@ -596,7 +596,7 @@
         return dst;
     }
 
-    private static int getIconHighlightColor(Context context) {
+    static int getIconHighlightColor(Context context) {
         TypedValue outValue = new TypedValue();
         if (context.getTheme().resolveAttribute(R.attr.playbackControlsIconHighlightColor,
                 outValue, true)) {
@@ -605,7 +605,7 @@
         return context.getResources().getColor(R.color.lb_playback_icon_highlight_no_theme);
     }
 
-    private static Drawable getStyledDrawable(Context context, int index) {
+    static Drawable getStyledDrawable(Context context, int index) {
         TypedValue outValue = new TypedValue();
         if (!context.getTheme().resolveAttribute(
                 R.attr.playbackControlsActionIcons, outValue, false)) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
index b43fdb7..fc4163e 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowPresenter.java
@@ -154,10 +154,10 @@
     private boolean mProgressColorSet;
     private boolean mSecondaryActionsHidden;
     private Presenter mDescriptionPresenter;
-    private PlaybackControlsPresenter mPlaybackControlsPresenter;
+    PlaybackControlsPresenter mPlaybackControlsPresenter;
     private ControlBarPresenter mSecondaryControlsPresenter;
-    private OnActionClickedListener mOnActionClickedListener;
-    private static float sShadowZ;
+    OnActionClickedListener mOnActionClickedListener;
+    static float sShadowZ;
 
     private final OnControlSelectedListener mOnControlSelectedListener =
             new OnControlSelectedListener() {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowView.java b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowView.java
index 0732d40..277f427 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/PlaybackControlsRowView.java
@@ -25,7 +25,6 @@
 
 /**
  * A LinearLayout that preserves the focused child view.
- * @hide
  */
 class PlaybackControlsRowView extends LinearLayout {
     public interface OnUnhandledKeyListener {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ResizingTextView.java b/v17/leanback/src/android/support/v17/leanback/widget/ResizingTextView.java
index 45aba9f..6b4f875 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ResizingTextView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ResizingTextView.java
@@ -25,7 +25,6 @@
 /**
  * <p>A {@link android.widget.TextView} that adjusts text size automatically in response
  * to certain trigger conditions, such as text that wraps over multiple lines.</p>
- * @hide
  */
 class ResizingTextView extends TextView {
 
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/RoundedRectHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/RoundedRectHelper.java
index 35a5b67..f9382ff 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RoundedRectHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RoundedRectHelper.java
@@ -59,6 +59,9 @@
      * Implementation used prior to L.
      */
     private static final class StubImpl implements Impl {
+        StubImpl() {
+        }
+
         @Override
         public void setClipToRoundedOutline(View view, boolean clip, int radius) {
             // Not supported
@@ -69,6 +72,9 @@
      * Implementation used on api 21 (and above).
      */
     private static final class Api21Impl implements Impl {
+        Api21Impl() {
+        }
+
         @Override
         public void setClipToRoundedOutline(View view, boolean clip, int radius) {
             RoundedRectHelperApi21.setClipToRoundedOutline(view, clip, radius);
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 b7805cf..53a51a4 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RowHeaderPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RowHeaderPresenter.java
@@ -14,12 +14,15 @@
 package android.support.v17.leanback.widget;
 
 import android.graphics.Paint;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * RowHeaderPresenter provides a default presentation for {@link HeaderItem} using a
  * {@link RowHeaderView}. If a subclass creates its own view, the subclass must also override
@@ -39,6 +42,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public RowHeaderPresenter(int layoutResourceId) {
         this(layoutResourceId, true);
     }
@@ -46,6 +50,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public RowHeaderPresenter(int layoutResourceId, boolean animateSelect) {
         mLayoutResourceId = layoutResourceId;
         mAnimateSelect = animateSelect;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
index d53e38c..68f0787 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
@@ -153,7 +153,7 @@
         float mSelectLevel = 0f; // initially unselected
         protected final ColorOverlayDimmer mColorDimmer;
         private View.OnKeyListener mOnKeyListener;
-        private BaseOnItemViewSelectedListener mOnItemViewSelectedListener;
+        BaseOnItemViewSelectedListener mOnItemViewSelectedListener;
         private BaseOnItemViewClickedListener mOnItemViewClickedListener;
 
         /**
@@ -329,7 +329,7 @@
 
     /**
      * Called to create a ViewHolder object for a Row. Subclasses will override
-     * this method to return a different concrete ViewHolder object. 
+     * this method to return a different concrete ViewHolder object.
      *
      * @param parent The parent View for the Row's view holder.
      * @return A ViewHolder for the Row's View.
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ScaleFrameLayout.java b/v17/leanback/src/android/support/v17/leanback/widget/ScaleFrameLayout.java
index 90616a2..50fd737 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ScaleFrameLayout.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ScaleFrameLayout.java
@@ -15,16 +15,20 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Subclass of FrameLayout that support scale layout area size for children.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ScaleFrameLayout extends FrameLayout {
 
     private static final int DEFAULT_CHILD_GRAVITY = Gravity.TOP | Gravity.START;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java b/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
index d9d44d2..09706bb 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
@@ -63,14 +63,14 @@
  * </p>
  */
 public class SearchBar extends RelativeLayout {
-    private static final String TAG = SearchBar.class.getSimpleName();
-    private static final boolean DEBUG = false;
+    static final String TAG = SearchBar.class.getSimpleName();
+    static final boolean DEBUG = false;
 
-    private static final float FULL_LEFT_VOLUME = 1.0f;
-    private static final float FULL_RIGHT_VOLUME = 1.0f;
-    private static final int DEFAULT_PRIORITY = 1;
-    private static final int DO_NOT_LOOP = 0;
-    private static final float DEFAULT_RATE = 1.0f;
+    static final float FULL_LEFT_VOLUME = 1.0f;
+    static final float FULL_RIGHT_VOLUME = 1.0f;
+    static final int DEFAULT_PRIORITY = 1;
+    static final int DO_NOT_LOOP = 0;
+    static final float DEFAULT_RATE = 1.0f;
 
     /**
      * Interface for receiving notification of search query changes.
@@ -125,17 +125,17 @@
                 }
             };
 
-    private SearchBarListener mSearchBarListener;
-    private SearchEditText mSearchTextEditor;
-    private SpeechOrbView mSpeechOrbView;
+    SearchBarListener mSearchBarListener;
+    SearchEditText mSearchTextEditor;
+    SpeechOrbView mSpeechOrbView;
     private ImageView mBadgeView;
-    private String mSearchQuery;
+    String mSearchQuery;
     private String mHint;
     private String mTitle;
     private Drawable mBadgeDrawable;
-    private final Handler mHandler = new Handler();
+    final Handler mHandler = new Handler();
     private final InputMethodManager mInputMethodManager;
-    private boolean mAutoStartRecognition = false;
+    boolean mAutoStartRecognition = false;
     private Drawable mBarBackground;
 
     private final int mTextColor;
@@ -148,9 +148,9 @@
     private SpeechRecognizer mSpeechRecognizer;
     private SpeechRecognitionCallback mSpeechRecognitionCallback;
     private boolean mListening;
-    private SoundPool mSoundPool;
-    private SparseIntArray mSoundMap = new SparseIntArray();
-    private boolean mRecognizing = false;
+    SoundPool mSoundPool;
+    SparseIntArray mSoundMap = new SparseIntArray();
+    boolean mRecognizing = false;
     private final Context mContext;
     private AudioManager mAudioManager;
     private SearchBarPermissionListener mPermissionListener;
@@ -366,7 +366,7 @@
         setSearchQueryInternal(query);
     }
 
-    private void setSearchQueryInternal(String query) {
+    void setSearchQueryInternal(String query) {
         if (DEBUG) Log.v(TAG, "setSearchQueryInternal " + query);
         if (TextUtils.equals(mSearchQuery, query)) {
             return;
@@ -480,12 +480,12 @@
         }
     }
 
-    private void hideNativeKeyboard() {
+    void hideNativeKeyboard() {
         mInputMethodManager.hideSoftInputFromWindow(mSearchTextEditor.getWindowToken(),
                 InputMethodManager.RESULT_UNCHANGED_SHOWN);
     }
 
-    private void showNativeKeyboard() {
+    void showNativeKeyboard() {
         mHandler.post(new Runnable() {
             @Override
             public void run() {
@@ -520,7 +520,7 @@
         }
     }
 
-    private void toggleRecognition() {
+    void toggleRecognition() {
         if (mRecognizing) {
             stopRecognition();
         } else {
@@ -741,7 +741,7 @@
         mSpeechRecognizer.startListening(recognizerIntent);
     }
 
-    private void updateUi(boolean hasFocus) {
+    void updateUi(boolean hasFocus) {
         if (hasFocus) {
             mBarBackground.setAlpha(mBackgroundSpeechAlpha);
             if (isVoiceMode()) {
@@ -764,7 +764,7 @@
         return mSpeechOrbView.isFocused();
     }
 
-    private void submitQuery() {
+    void submitQuery() {
         if (!TextUtils.isEmpty(mSearchQuery) && null != mSearchBarListener) {
             mSearchBarListener.onSearchQuerySubmit(mSearchQuery);
         }
@@ -793,11 +793,11 @@
         });
     }
 
-    private void playSearchOpen() {
+    void playSearchOpen() {
         play(R.raw.lb_voice_open);
     }
 
-    private void playSearchFailure() {
+    void playSearchFailure() {
         play(R.raw.lb_voice_failure);
     }
 
@@ -805,7 +805,7 @@
         play(R.raw.lb_voice_no_input);
     }
 
-    private void playSearchSuccess() {
+    void playSearchSuccess() {
         play(R.raw.lb_voice_success);
     }
 
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java b/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
index 2f315f7..8269f60 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
@@ -146,7 +146,7 @@
         }
     };
 
-    private void setSearchOrbZ(float fraction) {
+    void setSearchOrbZ(float fraction) {
         ShadowHelper.getInstance().setZ(mSearchOrbView,
                 mUnfocusedZ + fraction * (mFocusedZ - mUnfocusedZ));
     }
@@ -359,7 +359,7 @@
         }
     }
 
-    private void setOrbViewColor(int color) {
+    void setOrbViewColor(int color) {
         if (mSearchOrbView.getBackground() instanceof GradientDrawable) {
             ((GradientDrawable) mSearchOrbView.getBackground()).setColor(color);
         }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/ShadowHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/ShadowHelper.java
index aec9673..e5fb61d 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/ShadowHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/ShadowHelper.java
@@ -40,6 +40,9 @@
      * Interface used when we do not support Shadow animations.
      */
     private static final class ShadowHelperStubImpl implements ShadowHelperVersionImpl {
+        ShadowHelperStubImpl() {
+        }
+
         @Override
         public Object addDynamicShadow(
                 View shadowContainer, float focusedZ, float unfocusedZ, int roundedCornerRadius) {
@@ -62,6 +65,9 @@
      * Implementation used on api 21 (and above).
      */
     private static final class ShadowHelperApi21Impl implements ShadowHelperVersionImpl {
+        ShadowHelperApi21Impl() {
+        }
+
         @Override
         public Object addDynamicShadow(
                 View shadowContainer, float unfocusedZ, float focusedZ, int roundedCornerRadius) {
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/StaticShadowHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/StaticShadowHelper.java
index aa82866..6c6e664 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/StaticShadowHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/StaticShadowHelper.java
@@ -42,6 +42,9 @@
      * Interface used when we do not support Shadow animations.
      */
     private static final class ShadowHelperStubImpl implements ShadowHelperVersionImpl {
+        ShadowHelperStubImpl() {
+        }
+
         @Override
         public void prepareParent(ViewGroup parent) {
             // do nothing
@@ -63,6 +66,9 @@
      * Implementation used on JBMR2 (and above).
      */
     private static final class ShadowHelperJbmr2Impl implements ShadowHelperVersionImpl {
+        ShadowHelperJbmr2Impl() {
+        }
+
         @Override
         public void prepareParent(ViewGroup parent) {
             ShadowHelperJbmr2.prepareParent(parent);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/StreamingTextView.java b/v17/leanback/src/android/support/v17/leanback/widget/StreamingTextView.java
index b4b4b8f..5bc0a8c 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/StreamingTextView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/StreamingTextView.java
@@ -49,7 +49,7 @@
     private static final float TEXT_DOT_SCALE = 1.3F;
     private static final boolean DOTS_FOR_STABLE = false;
     private static final boolean DOTS_FOR_PENDING = true;
-    private static final boolean ANIMATE_DOTS_FOR_PENDING = true;
+    static final boolean ANIMATE_DOTS_FOR_PENDING = true;
 
     private static final long STREAM_UPDATE_DELAY_MILLIS = 50;
 
@@ -69,12 +69,12 @@
         }
     };
 
-    private final Random mRandom = new Random();
+    final Random mRandom = new Random();
 
-    private Bitmap mOneDot;
-    private Bitmap mTwoDot;
+    Bitmap mOneDot;
+    Bitmap mTwoDot;
 
-    private int mStreamPosition;
+    int mStreamPosition;
     private ObjectAnimator mStreamingAnimation;
 
     public StreamingTextView(Context context, AttributeSet attrs) {
@@ -154,11 +154,11 @@
         }
     }
 
-    private int getStreamPosition() {
+    int getStreamPosition() {
         return mStreamPosition;
     }
 
-    private void setStreamPosition(int streamPosition) {
+    void setStreamPosition(int streamPosition) {
         mStreamPosition = streamPosition;
         invalidate();
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/TitleHelper.java b/v17/leanback/src/android/support/v17/leanback/widget/TitleHelper.java
index 6f76c0e..c687e07 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/TitleHelper.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/TitleHelper.java
@@ -29,8 +29,8 @@
  */
 public class TitleHelper {
 
-    private ViewGroup mSceneRoot;
-    private View mTitleView;
+    ViewGroup mSceneRoot;
+    View mTitleView;
     private Object mTitleUpTransition;
     private Object mTitleDownTransition;
     private Object mSceneWithTitle;
@@ -48,7 +48,7 @@
             final boolean isRtl = ViewCompat.getLayoutDirection(focused) ==
                     View.LAYOUT_DIRECTION_RTL;
             final int forward = isRtl ? View.FOCUS_LEFT : View.FOCUS_RIGHT;
-            if (mTitleView.hasFocus() && direction == View.FOCUS_DOWN || direction == forward) {
+            if (mTitleView.hasFocus() && (direction == View.FOCUS_DOWN || direction == forward)) {
                 return mSceneRoot;
             }
             return null;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/Util.java b/v17/leanback/src/android/support/v17/leanback/widget/Util.java
index de4b1c7..544e18f 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/Util.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/Util.java
@@ -13,13 +13,17 @@
  */
 package android.support.v17.leanback.widget;
 
+import android.support.annotation.RestrictTo;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewParent;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class Util {
 
     /**
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
index 261cadc..edb3ab2 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
@@ -99,7 +99,7 @@
     private OnItemViewSelectedListener mOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
     private boolean mRoundedCornersEnabled = true;
-    private ShadowOverlayHelper mShadowOverlayHelper;
+    ShadowOverlayHelper mShadowOverlayHelper;
     private ItemBridgeAdapter.Wrapper mShadowOverlayWrapper;
 
     /**
@@ -180,9 +180,9 @@
     }
 
     /**
-     * Returns true if opticalBounds is supported (SDK >= 18) so that default shadow
-     * is applied to each individual child of {@link VerticalGridView}.
-     * Subclass may return false to disable.
+     * Default implementation returns true if SDK version >= 21, shadow (either static or z-order
+     * based) will be applied to each individual child of {@link VerticalGridView}.
+     * Subclass may return false to disable default implementation of shadow and provide its own.
      */
     public boolean isUsingDefaultShadow() {
         return ShadowOverlayHelper.supportsShadow();
@@ -284,7 +284,7 @@
         vh.mItemBridgeAdapter.setWrapper(mShadowOverlayWrapper);
         mShadowOverlayHelper.prepareParentForShadow(vh.mGridView);
         vh.getGridView().setFocusDrawingOrderEnabled(mShadowOverlayHelper.getShadowType()
-                == ShadowOverlayHelper.SHADOW_STATIC);
+                != ShadowOverlayHelper.SHADOW_DYNAMIC);
         FocusHighlightHelper.setupBrowseItemFocusHighlight(vh.mItemBridgeAdapter,
                 mFocusZoomFactor, mUseFocusDimmer);
 
@@ -378,7 +378,7 @@
         return mOnItemViewClickedListener;
     }
 
-    private void selectChildView(ViewHolder vh, View view) {
+    void selectChildView(ViewHolder vh, View view) {
         if (getOnItemViewSelectedListener() != null) {
             ItemBridgeAdapter.ViewHolder ibh = (view == null) ? null :
                     (ItemBridgeAdapter.ViewHolder) vh.getGridView().getChildViewHolder(view);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/WindowAlignment.java b/v17/leanback/src/android/support/v17/leanback/widget/WindowAlignment.java
index ad714e0..0e8ce24 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/WindowAlignment.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/WindowAlignment.java
@@ -38,11 +38,11 @@
          * will be scaled up.
          */
         private float mScrollCenter;
-        /** 
-         * Right or bottom edge of last child. 
+        /**
+         * Right or bottom edge of last child.
          */
         private int mMaxEdge;
-        /** 
+        /**
          * Left or top edge of first child, typically should be zero.
          */
         private int mMinEdge;
@@ -159,7 +159,7 @@
             return scrollTarget;
         }
 
-        private void reset() {
+        void reset() {
             mScrollCenter = Integer.MIN_VALUE;
             mMinEdge = Integer.MIN_VALUE;
             mMaxEdge = Integer.MAX_VALUE;
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/picker/DatePicker.java b/v17/leanback/src/android/support/v17/leanback/widget/picker/DatePicker.java
index 542634b..8000f5f 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/picker/DatePicker.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/picker/DatePicker.java
@@ -16,6 +16,7 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.R;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -29,6 +30,8 @@
 import java.util.Locale;
 import java.util.TimeZone;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * {@link DatePicker} is a directly subclass of {@link Picker}.
  * This class is a widget for selecting a date. The date can be selected by a
@@ -41,6 +44,7 @@
  * @attr ref R.styleable#lbDatePicker_datePickerFormat
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class DatePicker extends Picker {
 
     static final String LOG_TAG = "DatePicker";
@@ -352,7 +356,7 @@
     // scrolling vertically and thus fixes the animation jumps that used to happen when we reached
     // the endpoint date field values since the adapter values do not change while scrolling up
     // & down across a single field.
-    private void updateSpinnersImpl(boolean animation) {
+    void updateSpinnersImpl(boolean animation) {
         // set the spinner ranges respecting the min and max dates
         int dateFieldIndices[] = {mColDayIndex, mColMonthIndex, mColYearIndex};
 
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/picker/Picker.java b/v17/leanback/src/android/support/v17/leanback/widget/picker/Picker.java
index c2048f6..ca539a8 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/picker/Picker.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/picker/Picker.java
@@ -59,8 +59,8 @@
 
     private ViewGroup mRootView;
     private ViewGroup mPickerView;
-    private final List<VerticalGridView> mColumnViews = new ArrayList<VerticalGridView>();
-    private ArrayList<PickerColumn> mColumns;
+    final List<VerticalGridView> mColumnViews = new ArrayList<VerticalGridView>();
+    ArrayList<PickerColumn> mColumns;
 
     private float mUnfocusedAlpha;
     private float mFocusedAlpha;
@@ -283,7 +283,7 @@
         }
     }
 
-    private void updateColumnAlpha(int colIndex, boolean animate) {
+    void updateColumnAlpha(int colIndex, boolean animate) {
         VerticalGridView column = mColumnViews.get(colIndex);
 
         int selected = column.getSelectedPosition();
@@ -297,7 +297,7 @@
         }
     }
 
-    private void setOrAnimateAlpha(View view, boolean selected, int colIndex,
+    void setOrAnimateAlpha(View view, boolean selected, int colIndex,
             boolean animate) {
         boolean columnShownAsActivated = colIndex == mSelectedColumn || !hasFocus();
         if (selected) {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
index afeb175..22fab38 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTest.java
@@ -40,9 +40,6 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
-/**
- * @hide from javadoc
- */
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class BrowseFragmentTest {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTestActivity.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTestActivity.java
index 1fe145e..5e52a22 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTestActivity.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseFragmentTestActivity.java
@@ -22,9 +22,6 @@
 import android.os.Bundle;
 import android.support.v17.leanback.test.R;
 
-/**
- * @hide from javadoc
- */
 public class BrowseFragmentTestActivity extends Activity {
 
     public static final String EXTRA_ADD_TO_BACKSTACK = "addToBackStack";
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
index bab554d..e48a3b1 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTest.java
@@ -42,9 +42,6 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
-/**
- * @hide from javadoc
- */
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class BrowseSupportFragmentTest {
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTestActivity.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTestActivity.java
index fd3ba88..d92b58d 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTestActivity.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseSupportFragmentTestActivity.java
@@ -24,9 +24,6 @@
 import android.os.Bundle;
 import android.support.v17.leanback.test.R;
 
-/**
- * @hide from javadoc
- */
 public class BrowseSupportFragmentTestActivity extends FragmentActivity {
 
     public static final String EXTRA_ADD_TO_BACKSTACK = "addToBackStack";
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseTestFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseTestFragment.java
index a45f51d..62fa32e 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseTestFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseTestFragment.java
@@ -28,9 +28,6 @@
 import android.util.Log;
 import android.view.View;
 
-/**
- * @hide from javadoc
- */
 public class BrowseTestFragment extends BrowseFragment {
     private static final String TAG = "BrowseTestFragment";
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseTestSupportFragment.java b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseTestSupportFragment.java
index 4aa27a5..6031dfa 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseTestSupportFragment.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/BrowseTestSupportFragment.java
@@ -30,9 +30,6 @@
 import android.util.Log;
 import android.view.View;
 
-/**
- * @hide from javadoc
- */
 public class BrowseTestSupportFragment extends BrowseSupportFragment {
     private static final String TAG = "BrowseTestSupportFragment";
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/app/StringPresenter.java b/v17/leanback/tests/java/android/support/v17/leanback/app/StringPresenter.java
index e6e0793..eb66287 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/app/StringPresenter.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/app/StringPresenter.java
@@ -19,9 +19,6 @@
 import android.view.ViewGroup;
 import android.widget.TextView;
 
-/**
- * @hide from javadoc
- */
 public class StringPresenter extends Presenter {
     private static final boolean DEBUG = false;
     private static final String TAG = "StringPresenter";
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 aaf652b..d4c2e89 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
@@ -35,9 +35,6 @@
 
 import java.util.ArrayList;
 
-/**
- * @hide from javadoc
- */
 public class GridActivity extends Activity {
 
     private static final String TAG = "GridActivity";
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridTest.java
index d24d4c0..4577963 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/GridTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/GridTest.java
@@ -20,10 +20,6 @@
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
-/**
- * Base class for testing Grid algorithm
- * @hide
- */
 public abstract class GridTest {
 
     static class Provider implements Grid.Provider {
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 e1739ff..4061c66 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
@@ -42,9 +42,6 @@
 import java.util.Comparator;
 import java.util.HashMap;
 
-/**
- * @hide from javadoc
- */
 @MediumTest
 public class GridWidgetTest extends ActivityInstrumentationTestCase2<GridActivity> {
 
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/PagingIndicatorTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/PagingIndicatorTest.java
index a2ca45c..abc396b 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/PagingIndicatorTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/PagingIndicatorTest.java
@@ -18,10 +18,6 @@
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
-/**
- * Tests for {@link PagingIndicator}.
- * @hide
- */
 @SmallTest
 public class PagingIndicatorTest extends AndroidTestCase {
     private PagingIndicator mIndicator;
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/SingleRowTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/SingleRowTest.java
index 6b9b783..0cb34fb 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/SingleRowTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/SingleRowTest.java
@@ -28,7 +28,6 @@
 
 /**
  * Testing SingleRow algorithm
- * @hide
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
diff --git a/v17/leanback/tests/java/android/support/v17/leanback/widget/StaggeredGridDefaultTest.java b/v17/leanback/tests/java/android/support/v17/leanback/widget/StaggeredGridDefaultTest.java
index 82b63bf..9d933bc 100644
--- a/v17/leanback/tests/java/android/support/v17/leanback/widget/StaggeredGridDefaultTest.java
+++ b/v17/leanback/tests/java/android/support/v17/leanback/widget/StaggeredGridDefaultTest.java
@@ -29,7 +29,6 @@
 
 /**
  * Testing StaggeredGridDefault algorithm
- * @hide
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
diff --git a/v17/preference-leanback/Android.mk b/v17/preference-leanback/Android.mk
index 7d3eb27..2058002 100644
--- a/v17/preference-leanback/Android.mk
+++ b/v17/preference-leanback/Android.mk
@@ -20,7 +20,8 @@
     android-support-v14-preference \
     android-support-v7-preference \
     android-support-v7-appcompat \
-    android-support-v7-recyclerview
+    android-support-v7-recyclerview \
+    android-support-annotations
 
 # Build the resources using the latest applicable SDK version.
 # We do this here because the final static library must be compiled with an older
@@ -47,6 +48,8 @@
 LOCAL_JAVA_LIBRARIES := \
     android-support-v17-preference-leanback-res \
     android-support-v17-leanback
+LOCAL_SHARED_ANDROID_LIBRARIES := \
+    android-support-annotations
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
@@ -61,7 +64,7 @@
 #       android-support-v7-appcompat \
 #       android-support-v7-recyclerview \
 #       android-support-v4 \
-#       android-support-annotions
+#       android-support-annotations
 #
 # in their makefiles to include the resources in their package.
 include $(CLEAR_VARS)
@@ -76,8 +79,7 @@
     android-support-v17-preference-leanback-res
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     $(resource_libs) \
-    android-support-v4 \
-    android-support-annotations
+    android-support-v4
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 LOCAL_AAPT_FLAGS := --add-javadoc-annotation doconly
diff --git a/v17/preference-leanback/api21/android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout.java b/v17/preference-leanback/api21/android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout.java
index 5df1fc8..b67a56f 100644
--- a/v17/preference-leanback/api21/android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout.java
+++ b/v17/preference-leanback/api21/android/support/v17/internal/widget/OutlineOnlyWithChildrenFrameLayout.java
@@ -18,17 +18,21 @@
 
 import android.content.Context;
 import android.graphics.Outline;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewOutlineProvider;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * {@link FrameLayout} subclass that provides an outline only when it has children, so that it does
  * not cast a shadow when empty.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class OutlineOnlyWithChildrenFrameLayout extends FrameLayout {
 
     private ViewOutlineProvider mMagicalOutlineProvider;
diff --git a/v17/preference-leanback/api21/android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21.java b/v17/preference-leanback/api21/android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21.java
index 37e7a79..322fbe3 100644
--- a/v17/preference-leanback/api21/android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21.java
+++ b/v17/preference-leanback/api21/android/support/v17/preference/LeanbackPreferenceFragmentTransitionHelperApi21.java
@@ -16,14 +16,18 @@
 
 package android.support.v17.preference;
 
+import android.support.annotation.RestrictTo;
 import android.support.v17.leanback.transition.FadeAndShortSlide;
 import android.app.Fragment;
 import android.transition.Transition;
 import android.view.Gravity;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class LeanbackPreferenceFragmentTransitionHelperApi21 {
 
     public static void addTransitions(Fragment f) {
diff --git a/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java b/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java
index 40743dc..29d1ed9 100644
--- a/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java
+++ b/v17/preference-leanback/src/android/support/v17/preference/BaseLeanbackPreferenceFragment.java
@@ -18,6 +18,7 @@
 
 import android.app.Fragment;
 import android.os.Bundle;
+import android.support.annotation.RestrictTo;
 import android.support.v14.preference.PreferenceFragment;
 import android.support.v17.leanback.widget.VerticalGridView;
 import android.support.v7.preference.PreferenceRecyclerViewAccessibilityDelegate;
@@ -25,6 +26,8 @@
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This fragment provides a preference fragment with leanback-style behavior, suitable for
  * embedding into broader UI elements.
@@ -46,6 +49,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public Fragment getCallbackFragment() {
         return getParentFragment();
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java
index 685ce03..a9b7788 100644
--- a/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsFragment.java
@@ -22,6 +22,7 @@
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v14.preference.MultiSelectListPreference;
 import android.support.v14.preference.PreferenceFragment;
 import android.support.v7.preference.ListPreference;
@@ -33,6 +34,8 @@
 import android.view.ViewGroup;
 import android.widget.Space;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This fragment provides a container for displaying a {@link LeanbackPreferenceFragment}
  *
@@ -185,6 +188,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class DummyFragment extends Fragment {
 
         @Override
diff --git a/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsRootView.java b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsRootView.java
index 6114f13..463ed08 100644
--- a/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsRootView.java
+++ b/v17/preference-leanback/src/android/support/v17/preference/LeanbackSettingsRootView.java
@@ -18,13 +18,17 @@
 
 import android.content.Context;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class LeanbackSettingsRootView extends FrameLayout {
 
     private OnKeyListener mOnBackKeyListener;
diff --git a/v7/appcompat/res/color/abc_hint_foreground_material_dark.xml b/v7/appcompat/res/color/abc_hint_foreground_material_dark.xml
new file mode 100644
index 0000000..fe86872
--- /dev/null
+++ b/v7/appcompat/res/color/abc_hint_foreground_material_dark.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true"
+          android:state_pressed="true"
+          android:alpha="@dimen/hint_pressed_alpha_material_dark"
+          android:color="@color/foreground_material_dark" />
+    <item android:alpha="@dimen/hint_alpha_material_dark"
+          android:color="@color/foreground_material_dark" />
+</selector>
diff --git a/v7/appcompat/res/color/abc_hint_foreground_material_light.xml b/v7/appcompat/res/color/abc_hint_foreground_material_light.xml
new file mode 100644
index 0000000..1bef5af
--- /dev/null
+++ b/v7/appcompat/res/color/abc_hint_foreground_material_light.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="true"
+          android:state_pressed="true"
+          android:alpha="@dimen/hint_pressed_alpha_material_light"
+          android:color="@color/foreground_material_light" />
+    <item android:alpha="@dimen/hint_alpha_material_light"
+          android:color="@color/foreground_material_light" />
+</selector>
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_alpha.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_alpha.png
deleted file mode 100644
index c9f74b3..0000000
--- a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_dark.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_dark.png
new file mode 100644
index 0000000..ebf3f6c
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_light.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_light.png
new file mode 100644
index 0000000..d3556a8
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_left_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_alpha.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_alpha.png
deleted file mode 100644
index 6f2cf69..0000000
--- a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_dark.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_dark.png
new file mode 100644
index 0000000..428bfab
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_light.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_light.png
new file mode 100644
index 0000000..183c9ac
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_middle_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_alpha.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_alpha.png
deleted file mode 100644
index 87abd4d..0000000
--- a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_dark.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_dark.png
new file mode 100644
index 0000000..829d5b2
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_light.png b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_light.png
new file mode 100644
index 0000000..9b67079
--- /dev/null
+++ b/v7/appcompat/res/drawable-hdpi/abc_text_select_handle_right_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_alpha.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_alpha.png
deleted file mode 100644
index e1a23e2..0000000
--- a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_dark.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_dark.png
new file mode 100644
index 0000000..87e48ec
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_light.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_light.png
new file mode 100644
index 0000000..e243fd8
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_left_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_alpha.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_alpha.png
deleted file mode 100644
index 160119c..0000000
--- a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_dark.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_dark.png
new file mode 100644
index 0000000..d001cea
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_light.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_light.png
new file mode 100644
index 0000000..55b8b36
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_middle_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_alpha.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_alpha.png
deleted file mode 100644
index fe0d09f..0000000
--- a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_dark.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_dark.png
new file mode 100644
index 0000000..f415390
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_light.png b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_light.png
new file mode 100644
index 0000000..e6eff09
--- /dev/null
+++ b/v7/appcompat/res/drawable-mdpi/abc_text_select_handle_right_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_alpha.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_alpha.png
deleted file mode 100644
index f039399..0000000
--- a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_dark.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_dark.png
new file mode 100644
index 0000000..76ed4f3
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_light.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_light.png
new file mode 100644
index 0000000..529d550
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_left_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_alpha.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_alpha.png
deleted file mode 100644
index 4cf089e..0000000
--- a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_dark.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_dark.png
new file mode 100644
index 0000000..3dcebcf
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_light.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_light.png
new file mode 100644
index 0000000..1f8cc88
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_middle_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_alpha.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_alpha.png
deleted file mode 100644
index 0f91f59..0000000
--- a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_dark.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_dark.png
new file mode 100644
index 0000000..8df3718
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_light.png b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_light.png
new file mode 100644
index 0000000..6c8f6a4
--- /dev/null
+++ b/v7/appcompat/res/drawable-xhdpi/abc_text_select_handle_right_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_alpha.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_alpha.png
deleted file mode 100644
index b71ae5b..0000000
--- a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_dark.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_dark.png
new file mode 100644
index 0000000..278cb23
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_light.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_light.png
new file mode 100644
index 0000000..d6a8790
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_left_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_alpha.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_alpha.png
deleted file mode 100644
index 9502eb2..0000000
--- a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_dark.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_dark.png
new file mode 100644
index 0000000..d71dbd1
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_light.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_light.png
new file mode 100644
index 0000000..de00185
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_middle_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_alpha.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_alpha.png
deleted file mode 100644
index c8aa48e..0000000
--- a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_dark.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_dark.png
new file mode 100644
index 0000000..56d677d
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_light.png b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_light.png
new file mode 100644
index 0000000..d186a5b
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxhdpi/abc_text_select_handle_right_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_alpha.png b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_alpha.png
deleted file mode 100644
index c87ee03..0000000
--- a/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_dark.png b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_dark.png
new file mode 100644
index 0000000..2c6d0da
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_light.png b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_light.png
new file mode 100644
index 0000000..565f0b2
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_left_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_alpha.png b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_alpha.png
deleted file mode 100644
index 9372148..0000000
--- a/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_alpha.png
+++ /dev/null
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_dark.png b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_dark.png
new file mode 100644
index 0000000..714b641
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_dark.png
Binary files differ
diff --git a/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_light.png b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_light.png
new file mode 100644
index 0000000..894c734
--- /dev/null
+++ b/v7/appcompat/res/drawable-xxxhdpi/abc_text_select_handle_right_mtrl_light.png
Binary files differ
diff --git a/v7/appcompat/res/values-v11/themes_base.xml b/v7/appcompat/res/values-v11/themes_base.xml
index f787454..e0ac24d 100644
--- a/v7/appcompat/res/values-v11/themes_base.xml
+++ b/v7/appcompat/res/values-v11/themes_base.xml
@@ -50,8 +50,8 @@
         <item name="android:textColorSecondaryInverse">@color/abc_secondary_text_material_light</item>
         <item name="android:textColorTertiary">@color/abc_secondary_text_material_dark</item>
         <item name="android:textColorTertiaryInverse">@color/abc_secondary_text_material_light</item>
-        <item name="android:textColorHint">@color/hint_foreground_material_dark</item>
-        <item name="android:textColorHintInverse">@color/hint_foreground_material_light</item>
+        <item name="android:textColorHint">@color/abc_hint_foreground_material_dark</item>
+        <item name="android:textColorHintInverse">@color/abc_hint_foreground_material_light</item>
         <item name="android:textColorHighlight">@color/highlighted_text_material_dark</item>
         <item name="android:textColorHighlightInverse">@color/highlighted_text_material_light</item>
         <item name="android:textColorLink">?attr/colorAccent</item>
@@ -75,9 +75,9 @@
         <item name="android:actionModeCopyDrawable">?actionModeCopyDrawable</item>
         <item name="android:actionModePasteDrawable">?actionModePasteDrawable</item>
 
-        <item name="android:textSelectHandle">@drawable/abc_text_select_handle_middle_mtrl_alpha</item>
-        <item name="android:textSelectHandleLeft">@drawable/abc_text_select_handle_left_mtrl_alpha</item>
-        <item name="android:textSelectHandleRight">@drawable/abc_text_select_handle_right_mtrl_alpha</item>
+        <item name="android:textSelectHandle">@drawable/abc_text_select_handle_middle_mtrl_dark</item>
+        <item name="android:textSelectHandleLeft">@drawable/abc_text_select_handle_left_mtrl_dark</item>
+        <item name="android:textSelectHandleRight">@drawable/abc_text_select_handle_right_mtrl_dark</item>
     </style>
 
     <style name="Platform.V11.AppCompat.Light" parent="android:Theme.Holo.Light">
@@ -105,8 +105,8 @@
         <item name="android:textColorTertiaryInverse">@color/abc_secondary_text_material_dark</item>
         <item name="android:textColorPrimaryDisableOnly">@color/abc_primary_text_disable_only_material_light</item>
         <item name="android:textColorPrimaryInverseDisableOnly">@color/abc_primary_text_disable_only_material_dark</item>
-        <item name="android:textColorHint">@color/hint_foreground_material_light</item>
-        <item name="android:textColorHintInverse">@color/hint_foreground_material_dark</item>
+        <item name="android:textColorHint">@color/abc_hint_foreground_material_light</item>
+        <item name="android:textColorHintInverse">@color/abc_hint_foreground_material_dark</item>
         <item name="android:textColorHighlight">@color/highlighted_text_material_light</item>
         <item name="android:textColorHighlightInverse">@color/highlighted_text_material_dark</item>
         <item name="android:textColorLink">?attr/colorAccent</item>
@@ -130,9 +130,9 @@
         <item name="android:actionModeCopyDrawable">?actionModeCopyDrawable</item>
         <item name="android:actionModePasteDrawable">?actionModePasteDrawable</item>
 
-        <item name="android:textSelectHandle">@drawable/abc_text_select_handle_middle_mtrl_alpha</item>
-        <item name="android:textSelectHandleLeft">@drawable/abc_text_select_handle_left_mtrl_alpha</item>
-        <item name="android:textSelectHandleRight">@drawable/abc_text_select_handle_right_mtrl_alpha</item>
+        <item name="android:textSelectHandle">@drawable/abc_text_select_handle_middle_mtrl_light</item>
+        <item name="android:textSelectHandleLeft">@drawable/abc_text_select_handle_left_mtrl_light</item>
+        <item name="android:textSelectHandleRight">@drawable/abc_text_select_handle_right_mtrl_light</item>
     </style>
 
     <style name="Base.V11.Theme.AppCompat.Dialog" parent="Base.V7.Theme.AppCompat.Dialog">
diff --git a/v7/appcompat/res/values-v21/themes_base.xml b/v7/appcompat/res/values-v21/themes_base.xml
index 4b479be..3a7b77c 100644
--- a/v7/appcompat/res/values-v21/themes_base.xml
+++ b/v7/appcompat/res/values-v21/themes_base.xml
@@ -23,24 +23,32 @@
         unbundled Action Bar.
     -->
     <eat-comment/>
-    <style name="Platform.AppCompat" parent="android:Theme.Material">
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowActionBar">false</item>
 
+    <style name="Platform.AppCompat" parent="Platform.V21.AppCompat" />
+    <style name="Platform.AppCompat.Light" parent="Platform.V21.AppCompat.Light" />
+
+    <style name="Platform.V21.AppCompat" parent="android:Theme.Material.NoActionBar">
+        <!-- Update link colors pre-v23 -->
         <item name="android:textColorLink">?android:attr/colorAccent</item>
         <item name="android:textColorLinkInverse">?android:attr/colorAccent</item>
 
+        <!-- Update hint colors pre-v25 -->
+        <item name="android:textColorHint">@color/abc_hint_foreground_material_dark</item>
+        <item name="android:textColorHintInverse">@color/abc_hint_foreground_material_light</item>
+
         <item name="android:buttonBarStyle">?attr/buttonBarStyle</item>
         <item name="android:buttonBarButtonStyle">?attr/buttonBarButtonStyle</item>
     </style>
 
-    <style name="Platform.AppCompat.Light" parent="android:Theme.Material.Light">
-        <item name="android:windowNoTitle">true</item>
-        <item name="android:windowActionBar">false</item>
-
+    <style name="Platform.V21.AppCompat.Light" parent="android:Theme.Material.Light.NoActionBar">
+        <!-- Update link colors pre-v23 -->
         <item name="android:textColorLink">?android:attr/colorAccent</item>
         <item name="android:textColorLinkInverse">?android:attr/colorAccent</item>
 
+        <!-- Update hint colors pre-v25 -->
+        <item name="android:textColorHint">@color/abc_hint_foreground_material_light</item>
+        <item name="android:textColorHintInverse">@color/abc_hint_foreground_material_dark</item>
+
         <item name="android:buttonBarStyle">?attr/buttonBarStyle</item>
         <item name="android:buttonBarButtonStyle">?attr/buttonBarButtonStyle</item>
     </style>
diff --git a/v7/appcompat/res/values-v25/themes_base.xml b/v7/appcompat/res/values-v25/themes_base.xml
new file mode 100644
index 0000000..6a9f509
--- /dev/null
+++ b/v7/appcompat/res/values-v25/themes_base.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+
+    <style name="Platform.AppCompat" parent="Platform.V25.AppCompat" />
+    <style name="Platform.AppCompat.Light" parent="Platform.V25.AppCompat.Light" />
+
+    <style name="Platform.V25.AppCompat" parent="android:Theme.Material.NoActionBar">
+    </style>
+
+    <style name="Platform.V25.AppCompat.Light" parent="android:Theme.Material.Light.NoActionBar">
+    </style>
+
+</resources>
diff --git a/v7/appcompat/res/values/attrs.xml b/v7/appcompat/res/values/attrs.xml
index 128ded8..f9990db 100644
--- a/v7/appcompat/res/values/attrs.xml
+++ b/v7/appcompat/res/values/attrs.xml
@@ -1020,6 +1020,7 @@
     <declare-styleable name="TextAppearance">
         <attr name="android:textSize" />
         <attr name="android:textColor" />
+        <attr name="android:textColorHint"/>
         <attr name="android:textStyle" />
         <attr name="android:typeface" />
         <attr name="textAllCaps" />
diff --git a/v7/appcompat/res/values/colors_material.xml b/v7/appcompat/res/values/colors_material.xml
index 70fd21d..a90bf7a 100644
--- a/v7/appcompat/res/values/colors_material.xml
+++ b/v7/appcompat/res/values/colors_material.xml
@@ -60,8 +60,11 @@
     <color name="dim_foreground_disabled_material_dark">#80bebebe</color>
     <color name="dim_foreground_disabled_material_light">#80323232</color>
 
-    <color name="hint_foreground_material_dark">@color/bright_foreground_disabled_material_dark</color>
-    <color name="hint_foreground_material_light">@color/bright_foreground_disabled_material_light</color>
+    <item name="hint_alpha_material_dark" format="float" type="dimen">0.50</item>
+    <item name="hint_alpha_material_light" format="float" type="dimen">0.38</item>
+
+    <item name="hint_pressed_alpha_material_dark" format="float" type="dimen">0.70</item>
+    <item name="hint_pressed_alpha_material_light" format="float" type="dimen">0.54</item>
 
     <!-- TODO: This is 40% alpha on the default accent color. -->
     <color name="highlighted_text_material_dark">#6680cbc4</color>
diff --git a/v7/appcompat/res/values/themes_base.xml b/v7/appcompat/res/values/themes_base.xml
index d16ab89..df3473d 100644
--- a/v7/appcompat/res/values/themes_base.xml
+++ b/v7/appcompat/res/values/themes_base.xml
@@ -42,8 +42,8 @@
         <item name="android:textColorSecondaryInverse">@color/abc_secondary_text_material_light</item>
         <item name="android:textColorTertiary">@color/abc_secondary_text_material_dark</item>
         <item name="android:textColorTertiaryInverse">@color/abc_secondary_text_material_light</item>
-        <item name="android:textColorHint">@color/hint_foreground_material_dark</item>
-        <item name="android:textColorHintInverse">@color/hint_foreground_material_light</item>
+        <item name="android:textColorHint">@color/abc_hint_foreground_material_dark</item>
+        <item name="android:textColorHintInverse">@color/abc_hint_foreground_material_light</item>
         <item name="android:textColorHighlight">@color/highlighted_text_material_dark</item>
         <item name="android:textColorLink">?attr/colorAccent</item>
 
@@ -60,9 +60,9 @@
         <item name="android:listChoiceIndicatorSingle">@drawable/abc_btn_radio_material</item>
         <item name="android:listChoiceIndicatorMultiple">@drawable/abc_btn_check_material</item>
 
-        <item name="android:textSelectHandle">@drawable/abc_text_select_handle_middle_mtrl_alpha</item>
-        <item name="android:textSelectHandleLeft">@drawable/abc_text_select_handle_left_mtrl_alpha</item>
-        <item name="android:textSelectHandleRight">@drawable/abc_text_select_handle_right_mtrl_alpha</item>
+        <item name="android:textSelectHandle">@drawable/abc_text_select_handle_middle_mtrl_dark</item>
+        <item name="android:textSelectHandleLeft">@drawable/abc_text_select_handle_left_mtrl_dark</item>
+        <item name="android:textSelectHandleRight">@drawable/abc_text_select_handle_right_mtrl_dark</item>
     </style>
 
     <style name="Platform.AppCompat.Light" parent="android:Theme.Light">
@@ -86,8 +86,8 @@
         <item name="android:textColorTertiaryInverse">@color/abc_secondary_text_material_dark</item>
         <item name="android:textColorPrimaryDisableOnly">@color/abc_primary_text_disable_only_material_light</item>
         <item name="android:textColorPrimaryInverseDisableOnly">@color/abc_primary_text_disable_only_material_dark</item>
-        <item name="android:textColorHint">@color/hint_foreground_material_light</item>
-        <item name="android:textColorHintInverse">@color/hint_foreground_material_dark</item>
+        <item name="android:textColorHint">@color/abc_hint_foreground_material_light</item>
+        <item name="android:textColorHintInverse">@color/abc_hint_foreground_material_dark</item>
         <item name="android:textColorHighlight">@color/highlighted_text_material_light</item>
         <item name="android:textColorLink">?attr/colorAccent</item>
 
@@ -104,9 +104,9 @@
         <item name="android:listChoiceIndicatorSingle">@drawable/abc_btn_radio_material</item>
         <item name="android:listChoiceIndicatorMultiple">@drawable/abc_btn_check_material</item>
 
-        <item name="android:textSelectHandle">@drawable/abc_text_select_handle_middle_mtrl_alpha</item>
-        <item name="android:textSelectHandleLeft">@drawable/abc_text_select_handle_left_mtrl_alpha</item>
-        <item name="android:textSelectHandleRight">@drawable/abc_text_select_handle_right_mtrl_alpha</item>
+        <item name="android:textSelectHandle">@drawable/abc_text_select_handle_middle_mtrl_light</item>
+        <item name="android:textSelectHandleLeft">@drawable/abc_text_select_handle_left_mtrl_light</item>
+        <item name="android:textSelectHandleRight">@drawable/abc_text_select_handle_right_mtrl_light</item>
     </style>
 
     <!-- Themes in the "Base.Theme" family vary based on the current platform
@@ -584,6 +584,7 @@
         <item name="android:colorForegroundInverse">@color/foreground_material_dark</item>
         <item name="android:colorBackground">@color/background_material_light</item>
         <item name="android:colorBackgroundCacheHint">@color/abc_background_cache_hint_selector_material_light</item>
+        <item name="colorBackgroundFloating">@color/background_floating_material_light</item>
 
         <item name="android:textColorPrimary">@color/abc_primary_text_material_light</item>
         <item name="android:textColorPrimaryInverse">@color/abc_primary_text_material_dark</item>
@@ -593,8 +594,8 @@
         <item name="android:textColorTertiaryInverse">@color/abc_secondary_text_material_dark</item>
         <item name="android:textColorPrimaryDisableOnly">@color/abc_primary_text_disable_only_material_light</item>
         <item name="android:textColorPrimaryInverseDisableOnly">@color/abc_primary_text_disable_only_material_dark</item>
-        <item name="android:textColorHint">@color/hint_foreground_material_light</item>
-        <item name="android:textColorHintInverse">@color/hint_foreground_material_dark</item>
+        <item name="android:textColorHint">@color/abc_hint_foreground_material_light</item>
+        <item name="android:textColorHintInverse">@color/abc_hint_foreground_material_dark</item>
         <item name="android:textColorHighlight">@color/highlighted_text_material_light</item>
 
         <item name="colorControlNormal">?android:attr/textColorSecondary</item>
@@ -612,6 +613,7 @@
         <item name="android:colorForegroundInverse">@color/foreground_material_light</item>
         <item name="android:colorBackground">@color/background_material_dark</item>
         <item name="android:colorBackgroundCacheHint">@color/abc_background_cache_hint_selector_material_dark</item>
+        <item name="colorBackgroundFloating">@color/background_floating_material_dark</item>
 
         <item name="android:textColorPrimary">@color/abc_primary_text_material_dark</item>
         <item name="android:textColorPrimaryInverse">@color/abc_primary_text_material_light</item>
@@ -620,8 +622,8 @@
         <item name="android:textColorSecondaryInverse">@color/abc_secondary_text_material_light</item>
         <item name="android:textColorTertiary">@color/abc_secondary_text_material_dark</item>
         <item name="android:textColorTertiaryInverse">@color/abc_secondary_text_material_light</item>
-        <item name="android:textColorHint">@color/hint_foreground_material_dark</item>
-        <item name="android:textColorHintInverse">@color/hint_foreground_material_light</item>
+        <item name="android:textColorHint">@color/abc_hint_foreground_material_dark</item>
+        <item name="android:textColorHintInverse">@color/abc_hint_foreground_material_light</item>
         <item name="android:textColorHighlight">@color/highlighted_text_material_dark</item>
 
         <item name="colorControlNormal">?android:attr/textColorSecondary</item>
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBar.java b/v7/appcompat/src/android/support/v7/app/ActionBar.java
index dd496f8..4e63b74 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBar.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBar.java
@@ -24,6 +24,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringRes;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentTransaction;
@@ -41,6 +42,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A primary toolbar within the activity that may display the activity title, application-level
  * navigation affordances, and other interactive items.
@@ -88,6 +91,7 @@
 public abstract class ActionBar {
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
     public @interface NavigationMode {}
@@ -132,6 +136,7 @@
     public static final int NAVIGATION_MODE_TABS = 2;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef(flag=true, value={
             DISPLAY_USE_LOGO,
             DISPLAY_SHOW_HOME,
@@ -860,6 +865,7 @@
      * @return true if the Title field has been truncated
      * @hide pending API approval
      */
+    @RestrictTo(GROUP_ID)
     public boolean isTitleTruncated() { return false; }
 
     /**
@@ -1030,52 +1036,63 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void setDefaultDisplayHomeAsUpEnabled(boolean enabled) {
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void setShowHideAnimationEnabled(boolean enabled) {
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void onConfigurationChanged(Configuration config) {
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void dispatchMenuVisibilityChanged(boolean visible) {
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public ActionMode startActionMode(ActionMode.Callback callback) {
         return null;
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean openOptionsMenu() {
         return false;
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean invalidateOptionsMenu() {
         return false;
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean onMenuKeyEvent(KeyEvent event) {
         return false;
     }
 
     /** @hide **/
+    @RestrictTo(GROUP_ID)
     public boolean onKeyShortcut(int keyCode, KeyEvent ev) {
         return false;
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean collapseActionView() {
         return false;
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void setWindowTitle(CharSequence title) {
     }
 
diff --git a/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java b/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java
index 5cbebc6..3db19dc 100644
--- a/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java
+++ b/v7/appcompat/src/android/support/v7/app/ActionBarDrawerToggle.java
@@ -117,12 +117,12 @@
 
     private DrawerArrowDrawable mSlider;
     private Drawable mHomeAsUpIndicator;
-    private boolean mDrawerIndicatorEnabled = true;
+    boolean mDrawerIndicatorEnabled = true;
     private boolean mHasCustomUpIndicator;
     private final int mOpenDrawerContentDescRes;
     private final int mCloseDrawerContentDescRes;
     // used in toolbar mode when DrawerToggle is disabled
-    private View.OnClickListener mToolbarNavigationClickListener;
+    View.OnClickListener mToolbarNavigationClickListener;
     // If developer does not set displayHomeAsUp, DrawerToggle won't show up.
     // DrawerToggle logs a warning if this case is detected
     private boolean mWarnedForDisplayHomeAsUp = false;
@@ -280,7 +280,7 @@
         return false;
     }
 
-    private void toggle() {
+    void toggle() {
         int drawerLockMode = mDrawerLayout.getDrawerLockMode(GravityCompat.START);
         if (mDrawerLayout.isDrawerVisible(GravityCompat.START)
                 && (drawerLockMode != DrawerLayout.LOCK_MODE_LOCKED_OPEN)) {
@@ -499,7 +499,7 @@
         final Activity mActivity;
         ActionBarDrawerToggleHoneycomb.SetIndicatorInfo mSetIndicatorInfo;
 
-        private HoneycombDelegate(Activity activity) {
+        HoneycombDelegate(Activity activity) {
             mActivity = activity;
         }
 
@@ -552,7 +552,7 @@
 
         final Activity mActivity;
 
-        private JellybeanMr2Delegate(Activity activity) {
+        JellybeanMr2Delegate(Activity activity) {
             mActivity = activity;
         }
 
diff --git a/v7/appcompat/src/android/support/v7/app/AlertController.java b/v7/appcompat/src/android/support/v7/app/AlertController.java
index 0dca7fb..c7aad2d 100644
--- a/v7/appcompat/src/android/support/v7/app/AlertController.java
+++ b/v7/appcompat/src/android/support/v7/app/AlertController.java
@@ -60,12 +60,12 @@
 
 class AlertController {
     private final Context mContext;
-    private final AppCompatDialog mDialog;
+    final AppCompatDialog mDialog;
     private final Window mWindow;
 
     private CharSequence mTitle;
     private CharSequence mMessage;
-    private ListView mListView;
+    ListView mListView;
     private View mView;
 
     private int mViewLayoutResId;
@@ -76,19 +76,19 @@
     private int mViewSpacingBottom;
     private boolean mViewSpacingSpecified = false;
 
-    private Button mButtonPositive;
+    Button mButtonPositive;
     private CharSequence mButtonPositiveText;
-    private Message mButtonPositiveMessage;
+    Message mButtonPositiveMessage;
 
-    private Button mButtonNegative;
+    Button mButtonNegative;
     private CharSequence mButtonNegativeText;
-    private Message mButtonNegativeMessage;
+    Message mButtonNegativeMessage;
 
-    private Button mButtonNeutral;
+    Button mButtonNeutral;
     private CharSequence mButtonNeutralText;
-    private Message mButtonNeutralMessage;
+    Message mButtonNeutralMessage;
 
-    private NestedScrollView mScrollView;
+    NestedScrollView mScrollView;
 
     private int mIconId = 0;
     private Drawable mIcon;
@@ -98,20 +98,20 @@
     private TextView mMessageView;
     private View mCustomTitleView;
 
-    private ListAdapter mAdapter;
+    ListAdapter mAdapter;
 
-    private int mCheckedItem = -1;
+    int mCheckedItem = -1;
 
     private int mAlertDialogLayout;
     private int mButtonPanelSideLayout;
-    private int mListLayout;
-    private int mMultiChoiceItemLayout;
-    private int mSingleChoiceItemLayout;
-    private int mListItemLayout;
+    int mListLayout;
+    int mMultiChoiceItemLayout;
+    int mSingleChoiceItemLayout;
+    int mListItemLayout;
 
     private int mButtonPanelLayoutHint = AlertDialog.LAYOUT_HINT_NONE;
 
-    private Handler mHandler;
+    Handler mHandler;
 
     private final View.OnClickListener mButtonHandler = new View.OnClickListener() {
         @Override
@@ -700,7 +700,7 @@
         }
     }
 
-    private static void manageScrollIndicators(View v, View upIndicator, View downIndicator) {
+    static void manageScrollIndicators(View v, View upIndicator, View downIndicator) {
         if (upIndicator != null) {
             upIndicator.setVisibility(
                     ViewCompat.canScrollVertically(v, -1) ? View.VISIBLE : View.INVISIBLE);
diff --git a/v7/appcompat/src/android/support/v7/app/AlertDialog.java b/v7/appcompat/src/android/support/v7/app/AlertDialog.java
index 5c0a1d7..0ca2569 100644
--- a/v7/appcompat/src/android/support/v7/app/AlertDialog.java
+++ b/v7/appcompat/src/android/support/v7/app/AlertDialog.java
@@ -28,6 +28,7 @@
 import android.support.annotation.DrawableRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringRes;
 import android.support.annotation.StyleRes;
 import android.support.v7.appcompat.R;
@@ -41,6 +42,8 @@
 import android.widget.ListAdapter;
 import android.widget.ListView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A subclass of Dialog that can display one, two or three buttons. If you only want to
  * display a String in this dialog box, use the setMessage() method.  If you
@@ -69,7 +72,7 @@
  */
 public class AlertDialog extends AppCompatDialog implements DialogInterface {
 
-    private final AlertController mAlert;
+    final AlertController mAlert;
 
     /**
      * No layout hint.
@@ -103,7 +106,7 @@
         setOnCancelListener(cancelListener);
     }
 
-    private static int resolveDialogTheme(@NonNull Context context, @StyleRes int resid) {
+    static int resolveDialogTheme(@NonNull Context context, @StyleRes int resid) {
         if (resid >= 0x01000000) {   // start of real resource IDs.
             return resid;
         } else {
@@ -185,8 +188,6 @@
 
     /**
      * Internal api to allow hinting for the best button panel layout.
-     *
-     * @hide
      */
     void setButtonPanelLayoutHint(int layoutHint) {
         mAlert.setButtonPanelLayoutHint(layoutHint);
@@ -875,6 +876,7 @@
          * be able to put padding around the view.
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         @Deprecated
         public Builder setView(View view, int viewSpacingLeft, int viewSpacingTop,
                 int viewSpacingRight, int viewSpacingBottom) {
@@ -907,6 +909,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public Builder setRecycleOnMeasureEnabled(boolean enabled) {
             P.mRecycleOnMeasure = enabled;
             return this;
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java b/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
index c57758f..35e5ddc 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatActivity.java
@@ -26,6 +26,7 @@
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.app.FragmentActivity;
@@ -42,6 +43,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Base class for activities that use the
  * <a href="{@docRoot}tools/extras/support-library.html">support library</a> action bar features.
@@ -242,6 +245,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void invalidateOptionsMenu() {
         getDelegate().invalidateOptionsMenu();
     }
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
index aecdd79..606fcba 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegate.java
@@ -27,6 +27,7 @@
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.os.BuildCompat;
 import android.support.v4.view.WindowCompat;
@@ -43,6 +44,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This class represents a delegate which you can use to extend AppCompat's support to any
  * {@link android.app.Activity}.
@@ -130,6 +133,7 @@
     private static boolean sCompatVectorFromResourcesEnabled = false;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({MODE_NIGHT_NO, MODE_NIGHT_YES, MODE_NIGHT_AUTO, MODE_NIGHT_FOLLOW_SYSTEM,
             MODE_NIGHT_UNSPECIFIED})
     @Retention(RetentionPolicy.SOURCE)
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
index f680b6d..b26f3df 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplBase.java
@@ -43,7 +43,7 @@
     private static boolean sInstalledExceptionHandler;
     private static final boolean SHOULD_INSTALL_EXCEPTION_HANDLER = Build.VERSION.SDK_INT < 21;
 
-    private static final String EXCEPTION_HANDLER_MESSAGE_SUFFIX= ". If the resource you are"
+    static final String EXCEPTION_HANDLER_MESSAGE_SUFFIX= ". If the resource you are"
             + " trying to use is a vector resource, you may be referencing it in an unsupported"
             + " way. See AppCompatDelegate.setCompatVectorFromResourcesEnabled() for more info.";
 
@@ -195,6 +195,9 @@
     }
 
     private class ActionBarDrawableToggleImpl implements ActionBarDrawerToggle.Delegate {
+        ActionBarDrawableToggleImpl() {
+        }
+
         @Override
         public Drawable getThemeUpIndicator() {
             final TintTypedArray a = TintTypedArray.obtainStyledAttributes(
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
index 3279666..631fc35 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV14.java
@@ -30,6 +30,7 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.view.SupportActionModeWrapper;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.ActionMode;
 import android.view.Window;
@@ -38,6 +39,8 @@
 
     private static final String KEY_LOCAL_NIGHT_MODE = "appcompat:local_night_mode";
 
+    private static final boolean FLUSH_RESOURCE_CACHES_ON_NIGHT_CHANGE = true;
+
     @NightMode
     private int mLocalNightMode = MODE_NIGHT_UNSPECIFIED;
     private boolean mApplyDayNightCalled;
@@ -205,10 +208,25 @@
                 if (DEBUG) {
                     Log.d(TAG, "applyNightMode() | Night mode changed, updating configuration");
                 }
-                final Configuration newConf = new Configuration(conf);
-                newConf.uiMode = newNightMode
-                        | (newConf.uiMode & ~Configuration.UI_MODE_NIGHT_MASK);
-                res.updateConfiguration(newConf, null);
+                final Configuration config = new Configuration(conf);
+                final DisplayMetrics metrics = res.getDisplayMetrics();
+                final float originalFontScale = config.fontScale;
+
+                // Update the UI Mode to reflect the new night mode
+                config.uiMode = newNightMode | (config.uiMode & ~Configuration.UI_MODE_NIGHT_MASK);
+                if (FLUSH_RESOURCE_CACHES_ON_NIGHT_CHANGE) {
+                    // Set a fake font scale value to flush any resource caches
+                    config.fontScale = originalFontScale * 2;
+                }
+                // Now update the configuration
+                res.updateConfiguration(config, metrics);
+
+                if (FLUSH_RESOURCE_CACHES_ON_NIGHT_CHANGE) {
+                    // If we're flushing the resources cache, revert back to the original
+                    // font scale value
+                    config.fontScale = originalFontScale;
+                    res.updateConfiguration(config, metrics);
+                }
             }
             return true;
         } else {
@@ -233,7 +251,7 @@
 
     private boolean shouldRecreateOnNightModeChange() {
         if (mApplyDayNightCalled && mContext instanceof Activity) {
-            // If we've already appliedDayNight() (via setTheme), we need to check if the
+            // If we've already applyDayNight() (via setTheme), we need to check if the
             // Activity has configChanges set to handle uiMode changes
             final PackageManager pm = mContext.getPackageManager();
             try {
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
index 299bad0..4e25f71 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDelegateImplV9.java
@@ -120,8 +120,8 @@
 
     private boolean mLongPressBackDown;
 
-    private boolean mInvalidatePanelMenuPosted;
-    private int mInvalidatePanelMenuFeatures;
+    boolean mInvalidatePanelMenuPosted;
+    int mInvalidatePanelMenuFeatures;
     private final Runnable mInvalidatePanelMenuRunnable = new Runnable() {
         @Override
         public void run() {
@@ -870,7 +870,7 @@
         return mSubDecorInstalled && mSubDecor != null && ViewCompat.isLaidOut(mSubDecor);
     }
 
-    private void endOnGoingFadeAnimation() {
+    void endOnGoingFadeAnimation() {
         if (mFadeAnim != null) {
             mFadeAnim.cancel();
         }
@@ -1403,7 +1403,7 @@
         return true;
     }
 
-    private void checkCloseActionMenu(MenuBuilder menu) {
+    void checkCloseActionMenu(MenuBuilder menu) {
         if (mClosingActionMenu) {
             return;
         }
@@ -1417,11 +1417,11 @@
         mClosingActionMenu = false;
     }
 
-    private void closePanel(int featureId) {
+    void closePanel(int featureId) {
         closePanel(getPanelState(featureId, true), true);
     }
 
-    private void closePanel(PanelFeatureState st, boolean doCallback) {
+    void closePanel(PanelFeatureState st, boolean doCallback) {
         if (doCallback && st.featureId == FEATURE_OPTIONS_PANEL &&
                 mDecorContentParent != null && mDecorContentParent.isOverflowMenuShowing()) {
             checkCloseActionMenu(st.menu);
@@ -1517,7 +1517,7 @@
         return handled;
     }
 
-    private void callOnPanelClosed(int featureId, PanelFeatureState panel, Menu menu) {
+    void callOnPanelClosed(int featureId, PanelFeatureState panel, Menu menu) {
         // Try to get a menu
         if (menu == null) {
             // Need a panel to grab the menu, so try to get that
@@ -1545,7 +1545,7 @@
         }
     }
 
-    private PanelFeatureState findMenuPanel(Menu menu) {
+    PanelFeatureState findMenuPanel(Menu menu) {
         final PanelFeatureState[] panels = mPanels;
         final int N = panels != null ? panels.length : 0;
         for (int i = 0; i < N; i++) {
@@ -1608,7 +1608,7 @@
         }
     }
 
-    private void doInvalidatePanelMenu(int featureId) {
+    void doInvalidatePanelMenu(int featureId) {
         PanelFeatureState st = getPanelState(featureId, true);
         Bundle savedActionViewStates = null;
         if (st.menu != null) {
@@ -1641,7 +1641,7 @@
      * @param insetTop the current top system window inset
      * @return the new top system window inset
      */
-    private int updateStatusGuard(int insetTop) {
+    int updateStatusGuard(int insetTop) {
         boolean showStatusGuard = false;
         // Show the status guard when the non-overlay contextual action bar is showing
         if (mActionModeView != null) {
@@ -1736,7 +1736,7 @@
         return mSubDecor;
     }
 
-    private void dismissPopups() {
+    void dismissPopups() {
         if (mDecorContentParent != null) {
             mDecorContentParent.dismissPopups();
         }
@@ -1819,6 +1819,9 @@
     }
 
     private final class PanelMenuPresenterCallback implements MenuPresenter.Callback {
+        PanelMenuPresenterCallback() {
+        }
+
         @Override
         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
             final Menu parentMenu = menu.getRootMenu();
@@ -1849,6 +1852,9 @@
     }
 
     private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
+        ActionMenuPresenterCallback() {
+        }
+
         @Override
         public boolean onOpenSubMenu(MenuBuilder subMenu) {
             Window.Callback cb = getWindowCallback();
@@ -2046,6 +2052,9 @@
             boolean isOpen;
             Bundle menuState;
 
+            SavedState() {
+            }
+
             @Override
             public int describeContents() {
                 return 0;
@@ -2061,7 +2070,7 @@
                 }
             }
 
-            private static SavedState readFromParcel(Parcel source, ClassLoader loader) {
+            static SavedState readFromParcel(Parcel source, ClassLoader loader) {
                 SavedState savedState = new SavedState();
                 savedState.featureId = source.readInt();
                 savedState.isOpen = source.readInt() == 1;
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDialog.java b/v7/appcompat/src/android/support/v7/app/AppCompatDialog.java
index 9a66004..89a9368 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDialog.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDialog.java
@@ -22,12 +22,15 @@
 import android.support.annotation.IdRes;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v7.appcompat.R;
 import android.support.v7.view.ActionMode;
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Base class for AppCompat themed {@link android.app.Dialog}s.
  */
@@ -140,6 +143,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void invalidateOptionsMenu() {
         getDelegate().invalidateOptionsMenu();
     }
diff --git a/v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java b/v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java
index 10457b7..dcccfad 100644
--- a/v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java
+++ b/v7/appcompat/src/android/support/v7/app/AppCompatDialogFragment.java
@@ -19,10 +19,13 @@
 
 import android.app.Dialog;
 import android.os.Bundle;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.DialogFragment;
 import android.view.Window;
 import android.view.WindowManager;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A special version of {@link DialogFragment} which uses an {@link AppCompatDialog} in place of a
  * platform-styled dialog.
@@ -37,6 +40,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setupDialog(Dialog dialog, int style) {
         if (dialog instanceof AppCompatDialog) {
diff --git a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
index 6a3c91f..cd6f57e 100644
--- a/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
+++ b/v7/appcompat/src/android/support/v7/app/NotificationCompat.java
@@ -25,6 +25,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.Parcel;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.BundleCompat;
 import android.support.v4.app.NotificationBuilderWithBuilderAccessor;
 import android.support.v4.media.session.MediaSessionCompat;
@@ -38,6 +39,8 @@
 
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * An extension of {@link android.support.v4.app.NotificationCompat} which supports
  * {@link android.support.v7.app.NotificationCompat.MediaStyle},
@@ -382,6 +385,7 @@
          *
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         @Override
         protected CharSequence resolveText() {
             if (mStyle instanceof MessagingStyle) {
@@ -401,6 +405,7 @@
          *
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         @Override
         protected CharSequence resolveTitle() {
             if (mStyle instanceof MessagingStyle) {
@@ -417,6 +422,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         @Override
         protected BuilderExtender getExtender() {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@@ -435,6 +441,9 @@
 
     private static class IceCreamSandwichExtender extends BuilderExtender {
 
+        IceCreamSandwichExtender() {
+        }
+
         @Override
         public Notification build(android.support.v4.app.NotificationCompat.Builder b,
                 NotificationBuilderWithBuilderAccessor builder) {
@@ -453,6 +462,9 @@
 
     private static class JellybeanExtender extends BuilderExtender {
 
+        JellybeanExtender() {
+        }
+
         @Override
         public Notification build(android.support.v4.app.NotificationCompat.Builder b,
                 NotificationBuilderWithBuilderAccessor builder) {
@@ -470,6 +482,9 @@
 
     private static class LollipopExtender extends BuilderExtender {
 
+        LollipopExtender() {
+        }
+
         @Override
         public Notification build(android.support.v4.app.NotificationCompat.Builder b,
                 NotificationBuilderWithBuilderAccessor builder) {
diff --git a/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java b/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java
index 2c9a124..4776812 100644
--- a/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java
+++ b/v7/appcompat/src/android/support/v7/app/ToolbarActionBar.java
@@ -45,9 +45,9 @@
 import java.util.ArrayList;
 
 class ToolbarActionBar extends ActionBar {
-    private DecorToolbar mDecorToolbar;
-    private boolean mToolbarMenuPrepared;
-    private Window.Callback mWindowCallback;
+    DecorToolbar mDecorToolbar;
+    boolean mToolbarMenuPrepared;
+    Window.Callback mWindowCallback;
     private boolean mMenuCallbackSet;
 
     private boolean mLastMenuVisibility;
@@ -511,7 +511,7 @@
         }
     }
 
-    private View getListMenuView(Menu menu) {
+    View getListMenuView(Menu menu) {
         ensureListMenuPresenter(menu);
 
         if (menu == null || mListMenuPresenter == null) {
@@ -598,6 +598,9 @@
     private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
         private boolean mClosingActionMenu;
 
+        ActionMenuPresenterCallback() {
+        }
+
         @Override
         public boolean onOpenSubMenu(MenuBuilder subMenu) {
             if (mWindowCallback != null) {
@@ -623,6 +626,9 @@
     }
 
     private final class PanelMenuPresenterCallback implements MenuPresenter.Callback {
+        PanelMenuPresenterCallback() {
+        }
+
         @Override
         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
             if (mWindowCallback != null) {
@@ -641,6 +647,9 @@
 
     private final class MenuBuilderCallback implements MenuBuilder.Callback {
 
+        MenuBuilderCallback() {
+        }
+
         @Override
         public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
             return false;
diff --git a/v7/appcompat/src/android/support/v7/app/TwilightManager.java b/v7/appcompat/src/android/support/v7/app/TwilightManager.java
index fceb78c..61bb136 100644
--- a/v7/appcompat/src/android/support/v7/app/TwilightManager.java
+++ b/v7/appcompat/src/android/support/v7/app/TwilightManager.java
@@ -195,5 +195,8 @@
         long todaySunset;
         long tomorrowSunrise;
         long nextUpdate;
+
+        TwilightState() {
+        }
     }
 }
diff --git a/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java b/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
index 96a02a6..0279cb0 100644
--- a/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
+++ b/v7/appcompat/src/android/support/v7/app/WindowDecorActionBar.java
@@ -24,6 +24,7 @@
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.FragmentTransaction;
 import android.support.v4.view.ViewCompat;
@@ -65,12 +66,15 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * WindowDecorActionBar is the ActionBar implementation used
  * by devices of all screen sizes as part of the window decor layout.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class WindowDecorActionBar extends ActionBar implements
         ActionBarOverlayLayout.ActionBarVisibilityCallback {
     private static final String TAG = "WindowDecorActionBar";
@@ -83,17 +87,17 @@
      */
     private static final boolean ALLOW_SHOW_HIDE_ANIMATIONS = Build.VERSION.SDK_INT >= 14;
 
-    private Context mContext;
+    Context mContext;
     private Context mThemedContext;
     private Activity mActivity;
     private Dialog mDialog;
 
-    private ActionBarOverlayLayout mOverlayLayout;
-    private ActionBarContainer mContainerView;
-    private DecorToolbar mDecorToolbar;
-    private ActionBarContextView mContextView;
-    private View mContentView;
-    private ScrollingTabContainerView mTabScrollView;
+    ActionBarOverlayLayout mOverlayLayout;
+    ActionBarContainer mContainerView;
+    DecorToolbar mDecorToolbar;
+    ActionBarContextView mContextView;
+    View mContentView;
+    ScrollingTabContainerView mTabScrollView;
 
     private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
 
@@ -120,14 +124,14 @@
 
     private int mCurWindowVisibility = View.VISIBLE;
 
-    private boolean mContentAnimations = true;
-    private boolean mHiddenByApp;
-    private boolean mHiddenBySystem;
+    boolean mContentAnimations = true;
+    boolean mHiddenByApp;
+    boolean mHiddenBySystem;
     private boolean mShowingForMode;
 
     private boolean mNowShowing = true;
 
-    private ViewPropertyAnimatorCompatSet mCurrentShowAnim;
+    ViewPropertyAnimatorCompatSet mCurrentShowAnim;
     private boolean mShowHideAnimationEnabled;
     boolean mHideOnContentScroll;
 
@@ -184,6 +188,7 @@
      * Only for edit mode.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public WindowDecorActionBar(View layout) {
         assert layout.isInEditMode();
         init(layout);
@@ -729,7 +734,7 @@
         mOverlayLayout.setActionBarHideOffset(offset);
     }
 
-    private static boolean checkShowingFlags(boolean hiddenByApp, boolean hiddenBySystem,
+    static boolean checkShowingFlags(boolean hiddenByApp, boolean hiddenBySystem,
             boolean showingForMode) {
         if (showingForMode) {
             return true;
@@ -956,6 +961,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public class ActionModeImpl extends ActionMode implements MenuBuilder.Callback {
         private final Context mActionModeContext;
         private final MenuBuilder mMenu;
@@ -1129,6 +1135,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public class TabImpl extends ActionBar.Tab {
         private ActionBar.TabListener mCallback;
         private Object mTag;
diff --git a/v7/appcompat/src/android/support/v7/graphics/drawable/DrawableWrapper.java b/v7/appcompat/src/android/support/v7/graphics/drawable/DrawableWrapper.java
index b97d07c..adef493 100644
--- a/v7/appcompat/src/android/support/v7/graphics/drawable/DrawableWrapper.java
+++ b/v7/appcompat/src/android/support/v7/graphics/drawable/DrawableWrapper.java
@@ -23,9 +23,12 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Drawable which delegates all calls to it's wrapped {@link Drawable}.
  * <p>
@@ -34,6 +37,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class DrawableWrapper extends Drawable implements Drawable.Callback {
 
     private Drawable mDrawable;
diff --git a/v7/appcompat/src/android/support/v7/graphics/drawable/DrawerArrowDrawable.java b/v7/appcompat/src/android/support/v7/graphics/drawable/DrawerArrowDrawable.java
index 19428dd..e9af7b1 100644
--- a/v7/appcompat/src/android/support/v7/graphics/drawable/DrawerArrowDrawable.java
+++ b/v7/appcompat/src/android/support/v7/graphics/drawable/DrawerArrowDrawable.java
@@ -28,6 +28,7 @@
 import android.support.annotation.ColorInt;
 import android.support.annotation.FloatRange;
 import android.support.annotation.IntDef;
+import android.support.annotation.RestrictTo;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
@@ -35,6 +36,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A drawable that can draw a "Drawer hamburger" menu or an arrow and animate between them.
  * <p>
@@ -84,6 +87,7 @@
     public static final int ARROW_DIRECTION_END = 3;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({ARROW_DIRECTION_LEFT, ARROW_DIRECTION_RIGHT,
             ARROW_DIRECTION_START, ARROW_DIRECTION_END})
     @Retention(RetentionPolicy.SOURCE)
diff --git a/v7/appcompat/src/android/support/v7/text/AllCapsTransformationMethod.java b/v7/appcompat/src/android/support/v7/text/AllCapsTransformationMethod.java
index 7150262..73f02e2 100644
--- a/v7/appcompat/src/android/support/v7/text/AllCapsTransformationMethod.java
+++ b/v7/appcompat/src/android/support/v7/text/AllCapsTransformationMethod.java
@@ -18,14 +18,18 @@
 
 import android.content.Context;
 import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
 import android.text.method.TransformationMethod;
 import android.view.View;
 
 import java.util.Locale;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class AllCapsTransformationMethod implements TransformationMethod {
     private Locale mLocale;
 
diff --git a/v7/appcompat/src/android/support/v7/transition/ActionBarTransition.java b/v7/appcompat/src/android/support/v7/transition/ActionBarTransition.java
index 6cffd53..8df2796 100644
--- a/v7/appcompat/src/android/support/v7/transition/ActionBarTransition.java
+++ b/v7/appcompat/src/android/support/v7/transition/ActionBarTransition.java
@@ -17,11 +17,15 @@
 
 package android.support.v7.transition;
 
+import android.support.annotation.RestrictTo;
 import android.view.ViewGroup;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ActionBarTransition {
 
     private static final boolean TRANSITIONS_ENABLED = false;
diff --git a/v7/appcompat/src/android/support/v7/view/ActionBarPolicy.java b/v7/appcompat/src/android/support/v7/view/ActionBarPolicy.java
index 7d4f403..e8415ac 100644
--- a/v7/appcompat/src/android/support/v7/view/ActionBarPolicy.java
+++ b/v7/appcompat/src/android/support/v7/view/ActionBarPolicy.java
@@ -21,18 +21,22 @@
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.ConfigurationHelper;
 import android.support.v4.view.ViewConfigurationCompat;
 import android.support.v7.appcompat.R;
 import android.util.DisplayMetrics;
 import android.view.ViewConfiguration;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Allows components to query for various configuration policy decisions about how the action bar
  * should lay out and behave on the current device.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ActionBarPolicy {
 
     private Context mContext;
diff --git a/v7/appcompat/src/android/support/v7/view/ActionMode.java b/v7/appcompat/src/android/support/v7/view/ActionMode.java
index ff9cd49..50fae7e 100644
--- a/v7/appcompat/src/android/support/v7/view/ActionMode.java
+++ b/v7/appcompat/src/android/support/v7/view/ActionMode.java
@@ -16,11 +16,14 @@
 
 package android.support.v7.view;
 
+import android.support.annotation.RestrictTo;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Represents a contextual mode of the user interface. Action modes can be used to provide
  * alternative interaction modes and replace parts of the normal UI until finished.
@@ -216,6 +219,7 @@
      * @return true if the UI used to show this action mode can take focus
      * @hide Internal use only
      */
+    @RestrictTo(GROUP_ID)
     public boolean isUiFocusable() {
         return true;
     }
diff --git a/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java b/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java
index 6b77fd6..8841d12 100644
--- a/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java
+++ b/v7/appcompat/src/android/support/v7/view/ContextThemeWrapper.java
@@ -19,16 +19,20 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.res.Resources;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.v7.appcompat.R;
 import android.view.LayoutInflater;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A ContextWrapper that allows you to modify the theme from what is in the
  * wrapped context.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ContextThemeWrapper extends ContextWrapper {
     private int mThemeResource;
     private Resources.Theme mTheme;
diff --git a/v7/appcompat/src/android/support/v7/view/StandaloneActionMode.java b/v7/appcompat/src/android/support/v7/view/StandaloneActionMode.java
index 38dbb02..d328de8 100644
--- a/v7/appcompat/src/android/support/v7/view/StandaloneActionMode.java
+++ b/v7/appcompat/src/android/support/v7/view/StandaloneActionMode.java
@@ -16,6 +16,7 @@
 package android.support.v7.view;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.MenuItemCompat;
 import android.support.v7.view.menu.MenuBuilder;
 import android.support.v7.view.menu.MenuPopupHelper;
@@ -29,9 +30,12 @@
 
 import java.lang.ref.WeakReference;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class StandaloneActionMode extends ActionMode implements MenuBuilder.Callback {
     private Context mContext;
     private ActionBarContextView mContextView;
diff --git a/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java b/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
index 7eb6354..ddbfacb 100644
--- a/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
+++ b/v7/appcompat/src/android/support/v7/view/SupportActionModeWrapper.java
@@ -19,6 +19,7 @@
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.internal.view.SupportMenu;
 import android.support.v4.internal.view.SupportMenuItem;
 import android.support.v4.util.SimpleArrayMap;
@@ -30,12 +31,15 @@
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Wraps a support {@link android.support.v7.view.ActionMode} as a framework
  * {@link android.view.ActionMode}.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
 public class SupportActionModeWrapper extends ActionMode {
 
@@ -136,6 +140,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class CallbackWrapper implements android.support.v7.view.ActionMode.Callback {
         final Callback mWrappedCallback;
         final Context mContext;
diff --git a/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java b/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
index c8004ee..c11bb77 100644
--- a/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
+++ b/v7/appcompat/src/android/support/v7/view/SupportMenuInflater.java
@@ -24,6 +24,7 @@
 import android.content.ContextWrapper;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
+import android.support.annotation.RestrictTo;
 import android.support.v4.internal.view.SupportMenu;
 import android.support.v4.view.ActionProvider;
 import android.support.v4.view.MenuItemCompat;
@@ -44,6 +45,8 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This class is used to instantiate menu XML files into Menu objects.
  * <p>
@@ -55,8 +58,9 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class SupportMenuInflater extends MenuInflater {
-    private static final String LOG_TAG = "SupportMenuInflater";
+    static final String LOG_TAG = "SupportMenuInflater";
 
     /** Menu tag name in XML. */
     private static final String XML_MENU = "menu";
@@ -67,18 +71,18 @@
     /** Item tag name in XML. */
     private static final String XML_ITEM = "item";
 
-    private static final int NO_ID = 0;
+    static final int NO_ID = 0;
 
-    private static final Class<?>[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[] {Context.class};
+    static final Class<?>[] ACTION_VIEW_CONSTRUCTOR_SIGNATURE = new Class[] {Context.class};
 
-    private static final Class<?>[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE =
+    static final Class<?>[] ACTION_PROVIDER_CONSTRUCTOR_SIGNATURE =
             ACTION_VIEW_CONSTRUCTOR_SIGNATURE;
 
-    private final Object[] mActionViewConstructorArguments;
+    final Object[] mActionViewConstructorArguments;
 
-    private final Object[] mActionProviderConstructorArguments;
+    final Object[] mActionProviderConstructorArguments;
 
-    private Context mContext;
+    Context mContext;
     private Object mRealOwner;
 
     /**
@@ -209,7 +213,7 @@
         }
     }
 
-    private Object getRealOwner() {
+    Object getRealOwner() {
         if (mRealOwner == null) {
             mRealOwner = findRealOwner(mContext);
         }
@@ -315,7 +319,7 @@
 
         private String itemListenerMethodName;
 
-        private ActionProvider itemActionProvider;
+        ActionProvider itemActionProvider;
 
         private static final int defaultGroupId = NO_ID;
         private static final int defaultItemId = NO_ID;
diff --git a/v7/appcompat/src/android/support/v7/view/ViewPropertyAnimatorCompatSet.java b/v7/appcompat/src/android/support/v7/view/ViewPropertyAnimatorCompatSet.java
index 8727c9d..c5e9c72 100644
--- a/v7/appcompat/src/android/support/v7/view/ViewPropertyAnimatorCompatSet.java
+++ b/v7/appcompat/src/android/support/v7/view/ViewPropertyAnimatorCompatSet.java
@@ -16,6 +16,7 @@
 
 package android.support.v7.view;
 
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewPropertyAnimatorCompat;
 import android.support.v4.view.ViewPropertyAnimatorListener;
 import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
@@ -24,19 +25,22 @@
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A very naive implementation of a set of
  * {@link android.support.v4.view.ViewPropertyAnimatorCompat}.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ViewPropertyAnimatorCompatSet {
 
-    private final ArrayList<ViewPropertyAnimatorCompat> mAnimators;
+    final ArrayList<ViewPropertyAnimatorCompat> mAnimators;
 
     private long mDuration = -1;
     private Interpolator mInterpolator;
-    private ViewPropertyAnimatorListener mListener;
+    ViewPropertyAnimatorListener mListener;
 
     private boolean mIsStarted;
 
@@ -77,7 +81,7 @@
         mIsStarted = true;
     }
 
-    private void onAnimationsEnded() {
+    void onAnimationsEnded() {
         mIsStarted = false;
     }
 
diff --git a/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java b/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java
index ea1395f..0225400 100644
--- a/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java
+++ b/v7/appcompat/src/android/support/v7/view/WindowCallbackWrapper.java
@@ -16,6 +16,7 @@
 
 package android.support.v7.view;
 
+import android.support.annotation.RestrictTo;
 import android.view.ActionMode;
 import android.view.KeyEvent;
 import android.view.KeyboardShortcutGroup;
@@ -30,6 +31,8 @@
 
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A simple decorator stub for Window.Callback that passes through any calls
  * to the wrapped instance as a base implementation. Call super.foo() to call into
@@ -37,6 +40,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class WindowCallbackWrapper implements Window.Callback {
 
     final Window.Callback mWrapped;
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
index 5e6ea31..c62cd18 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItem.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.internal.view.SupportMenuItem;
 import android.support.v4.view.ActionProvider;
@@ -28,9 +29,12 @@
 import android.view.SubMenu;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ActionMenuItem implements SupportMenuItem {
 
     private final int mId;
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
index 47d794e..2429ad4 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ActionMenuItemView.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.ConfigurationHelper;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
@@ -40,21 +41,24 @@
 import android.view.View;
 import android.widget.Toast;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ActionMenuItemView extends AppCompatTextView
         implements MenuView.ItemView, View.OnClickListener, View.OnLongClickListener,
         ActionMenuView.ActionMenuChildView {
 
     private static final String TAG = "ActionMenuItemView";
 
-    private MenuItemImpl mItemData;
+    MenuItemImpl mItemData;
     private CharSequence mTitle;
     private Drawable mIcon;
-    private MenuBuilder.ItemInvoker mItemInvoker;
+    MenuBuilder.ItemInvoker mItemInvoker;
     private ForwardingListener mForwardingListener;
-    private PopupCallback mPopupCallback;
+    PopupCallback mPopupCallback;
 
     private boolean mAllowTextWithIcon;
     private boolean mExpandedFormat;
diff --git a/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java b/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java
index 868ff41..0e3cf5b 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/BaseMenuPresenter.java
@@ -17,6 +17,7 @@
 package android.support.v7.view.menu;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -24,6 +25,8 @@
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Base class for MenuPresenters that have a consistent container view and item views. Behaves
  * similarly to an AdapterView in that existing item views will be reused if possible when items
@@ -31,6 +34,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public abstract class BaseMenuPresenter implements MenuPresenter {
 
     protected Context mSystemContext;
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 7649fd5..b62127e 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/CascadingMenuPopup.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/CascadingMenuPopup.java
@@ -66,21 +66,21 @@
     @IntDef({HORIZ_POSITION_LEFT, HORIZ_POSITION_RIGHT})
     public @interface HorizPosition {}
 
-    private static final int HORIZ_POSITION_LEFT = 0;
-    private static final int HORIZ_POSITION_RIGHT = 1;
+    static final int HORIZ_POSITION_LEFT = 0;
+    static final int HORIZ_POSITION_RIGHT = 1;
 
     /**
      * Delay between hovering over a menu item with a mouse and receiving
      * side-effects (ex. opening a sub-menu or closing unrelated menus).
      */
-    private static final int SUBMENU_TIMEOUT_MS = 200;
+    static final int SUBMENU_TIMEOUT_MS = 200;
 
     private final Context mContext;
     private final int mMenuMaxWidth;
     private final int mPopupStyleAttr;
     private final int mPopupStyleRes;
     private final boolean mOverflowOnly;
-    private final Handler mSubMenuHoverHandler;
+    final Handler mSubMenuHoverHandler;
 
     /** List of menus that were added before this popup was shown. */
     private final List<MenuBuilder> mPendingMenus = new LinkedList<>();
@@ -89,7 +89,7 @@
      * List of open menus. The first item is the root menu and each
      * subsequent item is a direct submenu of the previous item.
      */
-    private final List<CascadingMenuInfo> mShowingMenus = new ArrayList<>();
+    final List<CascadingMenuInfo> mShowingMenus = new ArrayList<>();
 
     private final OnGlobalLayoutListener mGlobalLayoutListener = new OnGlobalLayoutListener() {
         @Override
@@ -175,7 +175,7 @@
     private int mRawDropDownGravity = Gravity.NO_GRAVITY;
     private int mDropDownGravity = Gravity.NO_GRAVITY;
     private View mAnchorView;
-    private View mShownAnchorView;
+    View mShownAnchorView;
     private int mLastPosition;
     private boolean mHasXOffset;
     private boolean mHasYOffset;
@@ -188,7 +188,7 @@
     private PopupWindow.OnDismissListener mOnDismissListener;
 
     /** Whether popup menus should disable exit animations when closing. */
-    private boolean mShouldCloseImmediately;
+    boolean mShouldCloseImmediately;
 
     /**
      * Initializes a new cascading-capable menu popup.
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ExpandedMenuView.java b/v7/appcompat/src/android/support/v7/view/menu/ExpandedMenuView.java
index 202c46a..5b06be7 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ExpandedMenuView.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ExpandedMenuView.java
@@ -17,6 +17,7 @@
 package android.support.v7.view.menu;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v7.view.menu.MenuBuilder.ItemInvoker;
 import android.support.v7.widget.TintTypedArray;
 import android.util.AttributeSet;
@@ -25,12 +26,15 @@
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ListView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * The expanded menu view is a list-like menu with all of the available menu items.  It is opened
  * by the user clicking no the 'More' button on the icon menu view.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class ExpandedMenuView extends ListView
         implements ItemInvoker, MenuView, OnItemClickListener {
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java b/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java
index 48bbbdc..8498350 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ListMenuItemView.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
 import android.support.v7.widget.TintTypedArray;
@@ -32,11 +33,14 @@
 import android.widget.RadioButton;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * The item view for each item in the ListView-based MenuViews.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ListMenuItemView extends LinearLayout implements MenuView.ItemView {
     private static final String TAG = "ListMenuItemView";
     private MenuItemImpl mItemData;
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ListMenuPresenter.java b/v7/appcompat/src/android/support/v7/view/menu/ListMenuPresenter.java
index a0b7359..580d7f9 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ListMenuPresenter.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ListMenuPresenter.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.os.Bundle;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v7.appcompat.R;
 import android.util.SparseArray;
 import android.view.ContextThemeWrapper;
@@ -31,11 +32,14 @@
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * MenuPresenter for list-style menus.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ListMenuPresenter implements MenuPresenter, AdapterView.OnItemClickListener {
     private static final String TAG = "ListMenuPresenter";
 
@@ -45,7 +49,7 @@
 
     ExpandedMenuView mMenuView;
 
-    private int mItemIndexOffset;
+    int mItemIndexOffset;
     int mThemeRes;
     int mItemLayoutRes;
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuAdapter.java b/v7/appcompat/src/android/support/v7/view/menu/MenuAdapter.java
index 5f00cf2..eba2d89 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuAdapter.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuAdapter.java
@@ -15,6 +15,7 @@
  */
 package android.support.v7.view.menu;
 
+import android.support.annotation.RestrictTo;
 import android.support.v7.appcompat.R;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -23,9 +24,12 @@
 
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class MenuAdapter extends BaseAdapter {
     static final int ITEM_LAYOUT = R.layout.abc_popup_menu_item_layout;
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java b/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java
index e8f8e56..2ee07d8 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuBuilder.java
@@ -27,6 +27,7 @@
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.internal.view.SupportMenu;
 import android.support.v4.internal.view.SupportMenuItem;
@@ -46,12 +47,15 @@
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Implementation of the {@link android.support.v4.internal.view.SupportMenu} interface for creating a
  * standard menu UI.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class MenuBuilder implements SupportMenu {
 
     private static final String TAG = "MenuBuilder";
@@ -184,6 +188,8 @@
      * Called by menu to notify of close and selection changes.
      * @hide
      */
+
+    @RestrictTo(GROUP_ID)
     public interface Callback {
 
         /**
@@ -193,22 +199,23 @@
          * @param item The menu item that is selected
          * @return whether the menu item selection was handled
          */
-        public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item);
+        boolean onMenuItemSelected(MenuBuilder menu, MenuItem item);
 
         /**
          * Called when the mode of the menu changes (for example, from icon to expanded).
          *
          * @param menu the menu that has changed modes
          */
-        public void onMenuModeChange(MenuBuilder menu);
+        void onMenuModeChange(MenuBuilder menu);
     }
 
     /**
      * Called by menu items to execute their associated action
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public interface ItemInvoker {
-        public boolean invokeItem(MenuItemImpl item);
+        boolean invokeItem(MenuItemImpl item);
     }
 
     public MenuBuilder(Context context) {
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java b/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
index 6f5f07d..b6374db 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuItemImpl.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.internal.view.SupportMenuItem;
 import android.support.v4.view.ActionProvider;
 import android.support.v4.view.MenuItemCompat;
@@ -34,9 +35,12 @@
 import android.view.ViewDebug;
 import android.widget.LinearLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class MenuItemImpl implements SupportMenuItem {
 
     private static final String TAG = "MenuItemImpl";
@@ -66,7 +70,7 @@
     private int mIconResId = NO_ICON;
 
     /** The menu to which this item belongs */
-    private MenuBuilder mMenu;
+    MenuBuilder mMenu;
     /** If this item should launch a sub menu, this is the sub menu to launch */
     private SubMenuBuilder mSubMenu;
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
index a717628..1a9e4e2 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperICS.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.internal.view.SupportMenuItem;
 import android.support.v4.view.ActionProvider;
 import android.support.v4.view.MenuItemCompat;
@@ -34,10 +35,13 @@
 
 import java.lang.reflect.Method;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Wraps a support {@link SupportMenuItem} as a framework {@link android.view.MenuItem}
  * @hide
  */
+@RestrictTo(GROUP_ID)
 @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
 public class MenuItemWrapperICS extends BaseMenuWrapper<SupportMenuItem> implements MenuItem {
     static final String LOG_TAG = "MenuItemWrapper";
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java
index 9a02b4f..bdcfc71 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuItemWrapperJB.java
@@ -19,15 +19,19 @@
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.internal.view.SupportMenuItem;
 import android.support.v4.view.ActionProvider;
 import android.view.MenuItem;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Wraps a support {@link SupportMenuItem} as a framework {@link android.view.MenuItem}
  * @hide
  */
+@RestrictTo(GROUP_ID)
 @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
 class MenuItemWrapperJB extends MenuItemWrapperICS {
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuPopupHelper.java b/v7/appcompat/src/android/support/v7/view/menu/MenuPopupHelper.java
index 9ecc829..dde4bb4 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuPopupHelper.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuPopupHelper.java
@@ -23,6 +23,7 @@
 import android.support.annotation.AttrRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
@@ -33,11 +34,14 @@
 import android.view.WindowManager;
 import android.widget.PopupWindow.OnDismissListener;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Presents a menu as a small, simple popup anchored to another view.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class MenuPopupHelper implements MenuHelper {
     private static final int TOUCH_EPICENTER_SIZE_DP = 48;
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuPresenter.java b/v7/appcompat/src/android/support/v7/view/menu/MenuPresenter.java
index 5ad52b9..b8cca24 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuPresenter.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuPresenter.java
@@ -18,28 +18,30 @@
 
 import android.content.Context;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.view.ViewGroup;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A MenuPresenter is responsible for building views for a Menu object. It takes over some
  * responsibility from the old style monolithic MenuBuilder class.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface MenuPresenter {
 
     /**
      * Called by menu implementation to notify another component of open/close events.
-     *
-     * @hide
      */
-    public interface Callback {
+    interface Callback {
         /**
          * Called when a menu is closing.
          * @param menu
          * @param allMenusAreClosing
          */
-        public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing);
+        void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing);
 
         /**
          * Called when a submenu opens. Useful for notifying the application
@@ -50,7 +52,7 @@
          * @return true if the Callback will handle presenting the submenu, false if
          *         the presenter should attempt to do so.
          */
-        public boolean onOpenSubMenu(MenuBuilder subMenu);
+        boolean onOpenSubMenu(MenuBuilder subMenu);
     }
 
     /**
@@ -61,7 +63,7 @@
      * @param context Context for this presenter; used for view creation and resource management
      * @param menu Menu to host
      */
-    public void initForMenu(Context context, MenuBuilder menu);
+    void initForMenu(Context context, MenuBuilder menu);
 
     /**
      * Retrieve a MenuView to display the menu specified in
@@ -70,7 +72,7 @@
      * @param root Intended parent of the MenuView.
      * @return A freshly created MenuView.
      */
-    public MenuView getMenuView(ViewGroup root);
+    MenuView getMenuView(ViewGroup root);
 
     /**
      * Update the menu UI in response to a change. Called by
@@ -78,14 +80,14 @@
      *
      * @param cleared true if the menu was entirely cleared
      */
-    public void updateMenuView(boolean cleared);
+    void updateMenuView(boolean cleared);
 
     /**
      * Set a callback object that will be notified of menu events
      * related to this specific presentation.
      * @param cb Callback that will be notified of future events
      */
-    public void setCallback(Callback cb);
+    void setCallback(Callback cb);
 
     /**
      * Called by Menu implementations to indicate that a submenu item
@@ -95,7 +97,7 @@
      * @param subMenu SubMenu being opened
      * @return true if the the event was handled, false otherwise.
      */
-    public boolean onSubMenuSelected(SubMenuBuilder subMenu);
+    boolean onSubMenuSelected(SubMenuBuilder subMenu);
 
     /**
      * Called by Menu implementations to indicate that a menu or submenu is
@@ -105,13 +107,13 @@
      * @param menu Menu or submenu that is closing.
      * @param allMenusAreClosing True if all associated menus are closing.
      */
-    public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing);
+    void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing);
 
     /**
      * Called by Menu implementations to flag items that will be shown as actions.
      * @return true if this presenter changed the action status of any items.
      */
-    public boolean flagActionItems();
+    boolean flagActionItems();
 
     /**
      * Called when a menu item with a collapsible action view should expand its action view.
@@ -120,7 +122,7 @@
      * @param item Item to be expanded
      * @return true if this presenter expanded the action view, false otherwise.
      */
-    public boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item);
+    boolean expandItemActionView(MenuBuilder menu, MenuItemImpl item);
 
     /**
      * Called when a menu item with a collapsible action view should collapse its action view.
@@ -129,13 +131,13 @@
      * @param item Item to be collapsed
      * @return true if this presenter collapsed the action view, false otherwise.
      */
-    public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item);
+    boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item);
 
     /**
      * Returns an ID for determining how to save/restore instance state.
      * @return a valid ID value.
      */
-    public int getId();
+    int getId();
 
     /**
      * Returns a Parcelable describing the current state of the presenter.
@@ -143,11 +145,11 @@
      * method of the presenter sharing the same ID later.
      * @return The saved instance state
      */
-    public Parcelable onSaveInstanceState();
+    Parcelable onSaveInstanceState();
 
     /**
      * Supplies the previously saved instance state to be restored.
      * @param state The previously saved instance state
      */
-    public void onRestoreInstanceState(Parcelable state);
+    void onRestoreInstanceState(Parcelable state);
 }
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuView.java b/v7/appcompat/src/android/support/v7/view/menu/MenuView.java
index a4d9310..9e542e4 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuView.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuView.java
@@ -17,6 +17,9 @@
 package android.support.v7.view.menu;
 
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * Minimal interface for a menu view.  {@link #initialize(MenuBuilder)} must be called for the
@@ -24,6 +27,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface MenuView {
     /**
      * Initializes the menu to the given menu. This should be called after the
@@ -31,19 +35,19 @@
      *
      * @param menu The menu that this MenuView should display.
      */
-    public void initialize(MenuBuilder menu);
+    void initialize(MenuBuilder menu);
 
     /**
      * Returns the default animations to be used for this menu when entering/exiting.
      * @return A resource ID for the default animations to be used for this menu.
      */
-    public int getWindowAnimations();
+    int getWindowAnimations();
 
     /**
      * Minimal interface for a menu item view.  {@link #initialize(MenuItemImpl, int)} must be called
      * for the item to be functional.
      */
-    public interface ItemView {
+    interface ItemView {
         /**
          * Initializes with the provided MenuItemData.  This should be called after the view is
          * inflated.
@@ -52,39 +56,39 @@
          *            {@link MenuBuilder#TYPE_ICON}, {@link MenuBuilder#TYPE_EXPANDED},
          *            {@link MenuBuilder#TYPE_DIALOG}).
          */
-        public void initialize(MenuItemImpl itemData, int menuType);
+        void initialize(MenuItemImpl itemData, int menuType);
 
         /**
          * Gets the item data that this view is displaying.
          * @return the item data, or null if there is not one
          */
-        public MenuItemImpl getItemData();
+        MenuItemImpl getItemData();
 
         /**
          * Sets the title of the item view.
          * @param title The title to set.
          */
-        public void setTitle(CharSequence title);
+        void setTitle(CharSequence title);
 
         /**
          * Sets the enabled state of the item view.
          * @param enabled Whether the item view should be enabled.
          */
-        public void setEnabled(boolean enabled);
+        void setEnabled(boolean enabled);
 
         /**
          * Displays the checkbox for the item view.  This does not ensure the item view will be
          * checked, for that use {@link #setChecked}.
          * @param checkable Whether to display the checkbox or to hide it
          */
-        public void setCheckable(boolean checkable);
+        void setCheckable(boolean checkable);
 
         /**
          * Checks the checkbox for the item view.  If the checkbox is hidden, it will NOT be
          * made visible, call {@link #setCheckable(boolean)} for that.
          * @param checked Whether the checkbox should be checked
          */
-        public void setChecked(boolean checked);
+        void setChecked(boolean checked);
 
         /**
          * Sets the shortcut for the item.
@@ -92,13 +96,13 @@
          * shortcutKey should be ignored).
          * @param shortcutKey The shortcut key that should be shown on the ItemView.
          */
-        public void setShortcut(boolean showShortcut, char shortcutKey);
+        void setShortcut(boolean showShortcut, char shortcutKey);
 
         /**
          * Set the icon of this item view.
          * @param icon The icon of this item. null to hide the icon.
          */
-        public void setIcon(Drawable icon);
+        void setIcon(Drawable icon);
 
         /**
          * Whether this item view prefers displaying the condensed title rather
@@ -108,13 +112,13 @@
          * @return Whether this item view prefers displaying the condensed
          *         title.
          */
-        public boolean prefersCondensedTitle();
+        boolean prefersCondensedTitle();
 
         /**
          * Whether this item view shows an icon.
          *
          * @return Whether this item view shows an icon.
          */
-        public boolean showsIcon();
+        boolean showsIcon();
     }
 }
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperFactory.java b/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperFactory.java
index 0130822..aa261aa 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperFactory.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperFactory.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.internal.view.SupportMenu;
 import android.support.v4.internal.view.SupportMenuItem;
 import android.support.v4.internal.view.SupportSubMenu;
@@ -25,9 +26,12 @@
 import android.view.MenuItem;
 import android.view.SubMenu;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class MenuWrapperFactory {
     private MenuWrapperFactory() {
     }
diff --git a/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java b/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java
index e733427..9bf58fa 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/MenuWrapperICS.java
@@ -27,7 +27,6 @@
 
 /**
  * Wraps a support {@link SupportMenu} as a framework {@link android.view.Menu}
- * @hide
  */
 class MenuWrapperICS extends BaseMenuWrapper<SupportMenu> implements Menu {
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/ShowableListMenu.java b/v7/appcompat/src/android/support/v7/view/menu/ShowableListMenu.java
index addebd7..49be9ec 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/ShowableListMenu.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/ShowableListMenu.java
@@ -16,22 +16,26 @@
 
 package android.support.v7.view.menu;
 
+import android.support.annotation.RestrictTo;
 import android.widget.ListView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A list menu which can be shown and hidden and which is internally represented by a ListView.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface ShowableListMenu {
-    public void show();
+    void show();
 
-    public void dismiss();
+    void dismiss();
 
-    public boolean isShowing();
+    boolean isShowing();
 
     /**
      * @return The internal ListView for the visible menu.
      */
-    public ListView getListView();
+    ListView getListView();
 }
\ No newline at end of file
diff --git a/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java b/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java
index 55ed1a1..2ab1a0c 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/StandardMenuPopup.java
@@ -53,7 +53,7 @@
     private final int mPopupStyleRes;
     // The popup window is final in order to couple its lifecycle to the lifecycle of the
     // StandardMenuPopup.
-    private final MenuPopupWindow mPopup;
+    final MenuPopupWindow mPopup;
 
     private final OnGlobalLayoutListener mGlobalLayoutListener = new OnGlobalLayoutListener() {
         @Override
@@ -76,7 +76,7 @@
     private PopupWindow.OnDismissListener mOnDismissListener;
 
     private View mAnchorView;
-    private View mShownAnchorView;
+    View mShownAnchorView;
     private Callback mPresenterCallback;
     private ViewTreeObserver mTreeObserver;
 
diff --git a/v7/appcompat/src/android/support/v7/view/menu/SubMenuBuilder.java b/v7/appcompat/src/android/support/v7/view/menu/SubMenuBuilder.java
index 7a6273f..f1d2980 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/SubMenuBuilder.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/SubMenuBuilder.java
@@ -18,18 +18,22 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.ContextCompat;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.SubMenu;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * The model for a sub menu, which is an extension of the menu.  Most methods are proxied to the
  * parent menu.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class SubMenuBuilder extends MenuBuilder implements SubMenu {
     private MenuBuilder mParentMenu;
     private MenuItemImpl mItem;
diff --git a/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java b/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java
index 9c1d5e5..185d443 100644
--- a/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java
+++ b/v7/appcompat/src/android/support/v7/view/menu/SubMenuWrapperICS.java
@@ -18,15 +18,19 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.internal.view.SupportSubMenu;
 import android.view.MenuItem;
 import android.view.SubMenu;
 import android.view.View;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Wraps a support {@link SupportSubMenu} as a framework {@link android.view.SubMenu}
  * @hide
  */
+@RestrictTo(GROUP_ID)
 class SubMenuWrapperICS extends MenuWrapperICS implements SubMenu {
 
     SubMenuWrapperICS(Context context, SupportSubMenu subMenu) {
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java b/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java
index bb94460..abac33e 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionBarContainer.java
@@ -20,6 +20,7 @@
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
 import android.support.v7.view.ActionMode;
@@ -29,11 +30,14 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This class acts as a container for the action bar view and action mode context views.
  * It applies special styles as needed to help handle animated transitions between them.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ActionBarContainer extends FrameLayout {
     private boolean mIsTransitioning;
     private View mTabContainer;
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarContextView.java b/v7/appcompat/src/android/support/v7/widget/ActionBarContextView.java
index 52391d1..580bfd6 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionBarContextView.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionBarContextView.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
 import android.support.v7.view.ActionMode;
@@ -31,9 +32,12 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ActionBarContextView extends AbsActionBarView {
     private static final String TAG = "ActionBarContextView";
 
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java b/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java
index d2ded94..98c64b4 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionBarOverlayLayout.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.NestedScrollingParent;
 import android.support.v4.view.NestedScrollingParentHelper;
 import android.support.v4.view.ViewCompat;
@@ -41,12 +42,15 @@
 import android.view.ViewGroup;
 import android.view.Window;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Special layout for the containing of an overlay action bar (and its content) to correctly handle
  * fitting system windows when the content has request that its layout ignore them.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ActionBarOverlayLayout extends ViewGroup implements DecorContentParent,
         NestedScrollingParent {
     private static final String TAG = "ActionBarOverlayLayout";
@@ -57,7 +61,7 @@
 
     // The main UI elements that we handle the layout of.
     private ContentFrameLayout mContent;
-    private ActionBarContainer mActionBarTop;
+    ActionBarContainer mActionBarTop;
 
     // Some interior UI elements.
     private DecorToolbar mDecorToolbar;
@@ -69,7 +73,7 @@
     private boolean mOverlayMode;
     private boolean mHasNonEmbeddedTabs;
     private boolean mHideOnContentScroll;
-    private boolean mAnimatingForFling;
+    boolean mAnimatingForFling;
     private int mHideOnContentScrollReference;
     private int mLastSystemUiVisibility;
     private final Rect mBaseContentInsets = new Rect();
@@ -85,9 +89,9 @@
 
     private ScrollerCompat mFlingEstimator;
 
-    private ViewPropertyAnimatorCompat mCurrentActionBarTopAnimator;
+    ViewPropertyAnimatorCompat mCurrentActionBarTopAnimator;
 
-    private final ViewPropertyAnimatorListener mTopAnimatorListener
+    final ViewPropertyAnimatorListener mTopAnimatorListener
             = new ViewPropertyAnimatorListenerAdapter() {
         @Override
         public void onAnimationEnd(View view) {
@@ -565,7 +569,7 @@
         ViewCompat.setTranslationY(mActionBarTop, -offset);
     }
 
-    private void haltActionBarHideOffsetAnimations() {
+    void haltActionBarHideOffsetAnimations() {
         removeCallbacks(mRemoveActionBarHideOffset);
         removeCallbacks(mAddActionBarHideOffset);
         if (mCurrentActionBarTopAnimator != null) {
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java b/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
index c3d9893..3abc33b 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionMenuPresenter.java
@@ -55,7 +55,7 @@
 
     private static final String TAG = "ActionMenuPresenter";
 
-    private OverflowMenuButton mOverflowButton;
+    OverflowMenuButton mOverflowButton;
     private Drawable mPendingOverflowIcon;
     private boolean mPendingOverflowIconSet;
     private boolean mReserveOverflow;
@@ -75,10 +75,10 @@
 
     private View mScrapActionButtonView;
 
-    private OverflowPopup mOverflowPopup;
-    private ActionButtonSubmenu mActionButtonPopup;
+    OverflowPopup mOverflowPopup;
+    ActionButtonSubmenu mActionButtonPopup;
 
-    private OpenOverflowRunnable mPostedOpenRunnable;
+    OpenOverflowRunnable mPostedOpenRunnable;
     private ActionMenuPopupCallback mPopupCallback;
 
     final PopupPresenterCallback mPopupPresenterCallback = new PopupPresenterCallback();
@@ -764,6 +764,9 @@
     }
 
     private class PopupPresenterCallback implements Callback {
+        PopupPresenterCallback() {
+        }
+
         @Override
         public boolean onOpenSubMenu(MenuBuilder subMenu) {
             if (subMenu == null) return false;
@@ -805,6 +808,9 @@
     }
 
     private class ActionMenuPopupCallback extends ActionMenuItemView.PopupCallback {
+        ActionMenuPopupCallback() {
+        }
+
         @Override
         public ShowableListMenu getPopup() {
             return mActionButtonPopup != null ? mActionButtonPopup.getPopup() : null;
diff --git a/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java b/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java
index bf5ab6a..c9aecc0 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActionMenuView.java
@@ -20,6 +20,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.v7.view.menu.ActionMenuItemView;
 import android.support.v7.view.menu.MenuBuilder;
@@ -36,6 +37,8 @@
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * ActionMenuView is a presentation of a series of menu options as a View. It provides
  * several top level options as action buttons while spilling remaining options over as
@@ -61,13 +64,13 @@
     private boolean mReserveOverflow;
     private ActionMenuPresenter mPresenter;
     private MenuPresenter.Callback mActionMenuPresenterCallback;
-    private MenuBuilder.Callback mMenuBuilderCallback;
+    MenuBuilder.Callback mMenuBuilderCallback;
     private boolean mFormatItems;
     private int mFormatItemsWidth;
     private int mMinCellSize;
     private int mGeneratedItemPadding;
 
-    private OnMenuItemClickListener mOnMenuItemClickListener;
+    OnMenuItemClickListener mOnMenuItemClickListener;
 
     public ActionMenuView(Context context) {
         this(context, null);
@@ -114,6 +117,7 @@
      * @param presenter Menu presenter used to display popup menu
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setPresenter(ActionMenuPresenter presenter) {
         mPresenter = presenter;
         mPresenter.setMenuView(this);
@@ -563,11 +567,13 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean isOverflowReserved() {
         return mReserveOverflow;
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void setOverflowReserved(boolean reserveOverflow) {
         mReserveOverflow = reserveOverflow;
     }
@@ -605,6 +611,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public LayoutParams generateOverflowButtonLayoutParams() {
         LayoutParams result = generateDefaultLayoutParams();
         result.isOverflowButton = true;
@@ -612,16 +619,19 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean invokeItem(MenuItemImpl item) {
         return mMenu.performItemAction(item, 0);
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public int getWindowAnimations() {
         return 0;
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void initialize(MenuBuilder menu) {
         mMenu = menu;
     }
@@ -654,6 +664,7 @@
      * Must be called before the first call to getMenu()
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb) {
         mActionMenuPresenterCallback = pcb;
         mMenuBuilderCallback = mcb;
@@ -663,6 +674,7 @@
      * Returns the current menu or null if one has not yet been configured.
      * @hide Internal use only for action bar integration
      */
+    @RestrictTo(GROUP_ID)
     public MenuBuilder peekMenu() {
         return mMenu;
     }
@@ -696,6 +708,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean isOverflowMenuShowPending() {
         return mPresenter != null && mPresenter.isOverflowMenuShowPending();
     }
@@ -712,6 +725,7 @@
     /**
      * @hide Private LinearLayout (superclass) API. Un-hide if LinearLayout API is made public.
      */
+    @RestrictTo(GROUP_ID)
     protected boolean hasSupportDividerBeforeChildAt(int childIndex) {
         if (childIndex == 0) {
             return false;
@@ -733,6 +747,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void setExpandedActionViewsExclusive(boolean exclusive) {
         mPresenter.setExpandedActionViewsExclusive(exclusive);
     }
@@ -753,6 +768,9 @@
     }
 
     private class MenuBuilderCallback implements MenuBuilder.Callback {
+        MenuBuilderCallback() {
+        }
+
         @Override
         public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
             return mOnMenuItemClickListener != null &&
@@ -768,6 +786,9 @@
     }
 
     private class ActionMenuPresenterCallback implements ActionMenuPresenter.Callback {
+        ActionMenuPresenterCallback() {
+        }
+
         @Override
         public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
         }
@@ -779,9 +800,10 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public interface ActionMenuChildView {
-        public boolean needsDividerBefore();
-        public boolean needsDividerAfter();
+        boolean needsDividerBefore();
+        boolean needsDividerAfter();
     }
 
     public static class LayoutParams extends LinearLayoutCompat.LayoutParams {
diff --git a/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java b/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java
index c4867f0..bdd3435 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActivityChooserModel.java
@@ -150,37 +150,37 @@
     /**
      * Flag for selecting debug mode.
      */
-    private static final boolean DEBUG = false;
+    static final boolean DEBUG = false;
 
     /**
      * Tag used for logging.
      */
-    private static final String LOG_TAG = ActivityChooserModel.class.getSimpleName();
+    static final String LOG_TAG = ActivityChooserModel.class.getSimpleName();
 
     /**
      * The root tag in the history file.
      */
-    private static final String TAG_HISTORICAL_RECORDS = "historical-records";
+    static final String TAG_HISTORICAL_RECORDS = "historical-records";
 
     /**
      * The tag for a record in the history file.
      */
-    private static final String TAG_HISTORICAL_RECORD = "historical-record";
+    static final String TAG_HISTORICAL_RECORD = "historical-record";
 
     /**
      * Attribute for the activity.
      */
-    private static final String ATTRIBUTE_ACTIVITY = "activity";
+    static final String ATTRIBUTE_ACTIVITY = "activity";
 
     /**
      * Attribute for the choice time.
      */
-    private static final String ATTRIBUTE_TIME = "time";
+    static final String ATTRIBUTE_TIME = "time";
 
     /**
      * Attribute for the choice weight.
      */
-    private static final String ATTRIBUTE_WEIGHT = "weight";
+    static final String ATTRIBUTE_WEIGHT = "weight";
 
     /**
      * The default name of the choice history file.
@@ -242,12 +242,12 @@
     /**
      * Context for accessing resources.
      */
-    private final Context mContext;
+    final Context mContext;
 
     /**
      * The name of the history file that backs this model.
      */
-    private final String mHistoryFileName;
+    final String mHistoryFileName;
 
     /**
      * The intent for which a activity is being chosen.
@@ -272,7 +272,7 @@
      * only after a call to {@link #persistHistoricalDataIfNeeded()} followed by change
      * of the share records.
      */
-    private boolean mCanReadHistoricalData = true;
+    boolean mCanReadHistoricalData = true;
 
     /**
      * Flag whether the choice history was read. This is used to enforce that
@@ -918,6 +918,9 @@
         private final Map<ComponentName, ActivityResolveInfo> mPackageNameToActivityMap =
                 new HashMap<ComponentName, ActivityResolveInfo>();
 
+        DefaultSorter() {
+        }
+
         public void sort(Intent intent, List<ActivityResolveInfo> activities,
                 List<HistoricalRecord> historicalRecords) {
             Map<ComponentName, ActivityResolveInfo> componentNameToActivityMap =
@@ -1032,6 +1035,9 @@
      */
     private final class PersistHistoryAsyncTask extends AsyncTask<Object, Void, Void> {
 
+        PersistHistoryAsyncTask() {
+        }
+
         @Override
         @SuppressWarnings("unchecked")
         public Void doInBackground(Object... args) {
diff --git a/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java b/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java
index 16c240a..7a6f688 100644
--- a/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java
+++ b/v7/appcompat/src/android/support/v7/widget/ActivityChooserView.java
@@ -24,6 +24,7 @@
 import android.content.res.TypedArray;
 import android.database.DataSetObserver;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ActionProvider;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
@@ -41,6 +42,8 @@
 import android.widget.PopupWindow;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This class is a view for choosing an activity for handling a given {@link Intent}.
  * <p>
@@ -64,6 +67,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ActivityChooserView extends ViewGroup implements
         ActivityChooserModel.ActivityChooserModelClient {
 
@@ -72,7 +76,7 @@
     /**
      * An adapter for displaying the activities in an {@link android.widget.AdapterView}.
      */
-    private final ActivityChooserViewAdapter mAdapter;
+    final ActivityChooserViewAdapter mAdapter;
 
     /**
      * Implementation of various interfaces to avoid publishing them in the APIs.
@@ -92,7 +96,7 @@
     /**
      * The expand activities action button;
      */
-    private final FrameLayout mExpandActivityOverflowButton;
+    final FrameLayout mExpandActivityOverflowButton;
 
     /**
      * The image for the expand activities action button;
@@ -102,7 +106,7 @@
     /**
      * The default activities action button;
      */
-    private final FrameLayout mDefaultActivityButton;
+    final FrameLayout mDefaultActivityButton;
 
     /**
      * The image for the default activities action button;
@@ -122,7 +126,7 @@
     /**
      * Observer for the model data.
      */
-    private final DataSetObserver mModelDataSetObserver = new DataSetObserver() {
+    final DataSetObserver mModelDataSetObserver = new DataSetObserver() {
 
         @Override
         public void onChanged() {
@@ -160,17 +164,17 @@
     /**
      * Listener for the dismissal of the popup/alert.
      */
-    private PopupWindow.OnDismissListener mOnDismissListener;
+    PopupWindow.OnDismissListener mOnDismissListener;
 
     /**
      * Flag whether a default activity currently being selected.
      */
-    private boolean mIsSelectingDefaultActivity;
+    boolean mIsSelectingDefaultActivity;
 
     /**
      * The count of activities in the popup.
      */
-    private int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT;
+    int mInitialActivityCount = ActivityChooserViewAdapter.MAX_ACTIVITY_COUNT_DEFAULT;
 
     /**
      * Flag whether this view is attached to a window.
@@ -321,6 +325,7 @@
      * Set the provider hosting this view, if applicable.
      * @hide Internal use only
      */
+    @RestrictTo(GROUP_ID)
     public void setProvider(ActionProvider provider) {
         mProvider = provider;
     }
@@ -344,7 +349,7 @@
      *
      * @param maxActivityCount The max number of activities to display.
      */
-    private void showPopupUnchecked(int maxActivityCount) {
+    void showPopupUnchecked(int maxActivityCount) {
         if (mAdapter.getDataModel() == null) {
             throw new IllegalStateException("No data model. Did you call #setDataModel?");
         }
@@ -501,7 +506,7 @@
      *
      * @return The popup.
      */
-    private ListPopupWindow getListPopupWindow() {
+    ListPopupWindow getListPopupWindow() {
         if (mListPopupWindow == null) {
             mListPopupWindow = new ListPopupWindow(getContext());
             mListPopupWindow.setAdapter(mAdapter);
@@ -516,7 +521,7 @@
     /**
      * Updates the buttons state.
      */
-    private void updateAppearance() {
+    void updateAppearance() {
         // Expand overflow button.
         if (mAdapter.getCount() > 0) {
             mExpandActivityOverflowButton.setEnabled(true);
@@ -554,6 +559,9 @@
     private class Callbacks implements AdapterView.OnItemClickListener,
             View.OnClickListener, View.OnLongClickListener, PopupWindow.OnDismissListener {
 
+        Callbacks() {
+        }
+
         // AdapterView#OnItemClickListener
         @Override
         public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
@@ -661,6 +669,9 @@
 
         private boolean mShowFooterView;
 
+        ActivityChooserViewAdapter() {
+        }
+
         public void setDataModel(ActivityChooserModel dataModel) {
             ActivityChooserModel oldDataModel = mAdapter.getDataModel();
             if (oldDataModel != null && isShown()) {
@@ -834,6 +845,7 @@
      * Allows us to set the background using TintTypedArray
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class InnerLayout extends LinearLayoutCompat {
 
         private static final int[] TINT_ATTRS = {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java
index 2c73df6..c996cef 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatAutoCompleteTextView.java
@@ -22,12 +22,15 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
 import android.support.v7.appcompat.R;
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
 import android.widget.AutoCompleteTextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link AutoCompleteTextView} which supports compatible features on older version of the
  * platform, including:
@@ -106,6 +109,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
         if (mBackgroundTintHelper != null) {
@@ -119,6 +123,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public ColorStateList getSupportBackgroundTintList() {
@@ -132,6 +137,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mBackgroundTintHelper != null) {
@@ -145,6 +151,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public PorterDuff.Mode getSupportBackgroundTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
index 60f3976..09e4a28 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatBackgroundHelper.java
@@ -222,6 +222,9 @@
         // modified for actual tinting purposes
         public ColorStateList mOriginalTintList;
 
+        BackgroundTintInfo() {
+        }
+
         @Override
         void clear() {
             super.clear();
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java b/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
index 2a16f67..af5ff2d 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatButton.java
@@ -22,6 +22,7 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
@@ -29,6 +30,8 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Button;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link Button} which supports compatible features on older version of the platform,
  * including:
@@ -90,6 +93,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
         if (mBackgroundTintHelper != null) {
@@ -103,6 +107,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public ColorStateList getSupportBackgroundTintList() {
@@ -116,6 +121,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mBackgroundTintHelper != null) {
@@ -129,6 +135,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public PorterDuff.Mode getSupportBackgroundTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java b/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java
index eac40eb..2f5bd90 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatCheckBox.java
@@ -22,12 +22,15 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.widget.TintableCompoundButton;
 import android.support.v7.appcompat.R;
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
 import android.widget.CheckBox;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link CheckBox} which supports compatible features on older version of the platform,
  * including:
@@ -84,6 +87,7 @@
      * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportButtonTintList(@Nullable ColorStateList tint) {
         if (mCompoundButtonHelper != null) {
@@ -95,6 +99,7 @@
      * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Nullable
     @Override
     public ColorStateList getSupportButtonTintList() {
@@ -107,6 +112,7 @@
      * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportButtonTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mCompoundButtonHelper != null) {
@@ -118,6 +124,7 @@
      * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Nullable
     @Override
     public PorterDuff.Mode getSupportButtonTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java b/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
index 6523d12..6f42ea9 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatDrawableManager.java
@@ -16,6 +16,7 @@
 
 package android.support.v7.widget;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v4.graphics.ColorUtils.compositeColors;
 import static android.support.v7.content.res.AppCompatResources.getColorStateList;
 import static android.support.v7.widget.ThemeUtils.getDisabledThemeAttrColor;
@@ -36,6 +37,7 @@
 import android.support.annotation.DrawableRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.graphics.drawable.AnimatedVectorDrawableCompat;
 import android.support.graphics.drawable.VectorDrawableCompat;
 import android.support.v4.content.ContextCompat;
@@ -59,6 +61,7 @@
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class AppCompatDrawableManager {
 
     private interface InflateDelegate {
@@ -85,7 +88,8 @@
 
     private static void installDefaultInflateDelegates(@NonNull AppCompatDrawableManager manager) {
         final int sdk = Build.VERSION.SDK_INT;
-        if (sdk < 23) {
+        // This sdk version check will affect src:appCompat code path.
+        if (sdk < 24) {
             // We only want to use the automatic VectorDrawableCompat handling where it's
             // needed: on devices running before Lollipop
             manager.addDelegate("vector", new VdcInflateDelegate());
@@ -132,9 +136,12 @@
             R.drawable.abc_textfield_search_activated_mtrl_alpha,
             R.drawable.abc_cab_background_top_mtrl_alpha,
             R.drawable.abc_text_cursor_material,
-            R.drawable.abc_text_select_handle_left_mtrl_alpha,
-            R.drawable.abc_text_select_handle_middle_mtrl_alpha,
-            R.drawable.abc_text_select_handle_right_mtrl_alpha
+            R.drawable.abc_text_select_handle_left_mtrl_dark,
+            R.drawable.abc_text_select_handle_middle_mtrl_dark,
+            R.drawable.abc_text_select_handle_right_mtrl_dark,
+            R.drawable.abc_text_select_handle_left_mtrl_light,
+            R.drawable.abc_text_select_handle_middle_mtrl_light,
+            R.drawable.abc_text_select_handle_right_mtrl_light
     };
 
     /**
@@ -728,6 +735,9 @@
     }
 
     private static class VdcInflateDelegate implements InflateDelegate {
+        VdcInflateDelegate() {
+        }
+
         @Override
         public Drawable createFromXmlInner(@NonNull Context context, @NonNull XmlPullParser parser,
                 @NonNull AttributeSet attrs, @Nullable Resources.Theme theme) {
@@ -742,6 +752,9 @@
     }
 
     private static class AvdcInflateDelegate implements InflateDelegate {
+        AvdcInflateDelegate() {
+        }
+
         @Override
         public Drawable createFromXmlInner(@NonNull Context context, @NonNull XmlPullParser parser,
                 @NonNull AttributeSet attrs, @Nullable Resources.Theme theme) {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java b/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java
index 1e447a3..4d62ea5 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatEditText.java
@@ -22,11 +22,14 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
 import android.widget.EditText;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link EditText} which supports compatible features on older version of the platform,
  * including:
@@ -88,6 +91,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
         if (mBackgroundTintHelper != null) {
@@ -101,6 +105,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public ColorStateList getSupportBackgroundTintList() {
@@ -114,6 +119,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mBackgroundTintHelper != null) {
@@ -127,6 +133,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public PorterDuff.Mode getSupportBackgroundTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java b/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
index 7ef9c4d..653ed26 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatImageButton.java
@@ -22,11 +22,14 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
 import android.widget.ImageButton;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link ImageButton} which supports compatible features on older version of the platform,
  * including:
@@ -91,6 +94,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
         if (mBackgroundTintHelper != null) {
@@ -104,6 +108,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public ColorStateList getSupportBackgroundTintList() {
@@ -117,6 +122,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mBackgroundTintHelper != null) {
@@ -130,6 +136,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public PorterDuff.Mode getSupportBackgroundTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java
index c5f236d..87a45b7 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatImageHelper.java
@@ -18,14 +18,18 @@
 
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v7.appcompat.R;
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class AppCompatImageHelper {
 
     private final ImageView mView;
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
index 85b1778..87df13d 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatImageView.java
@@ -22,11 +22,14 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link ImageView} which supports compatible features on older version of the platform,
  * including:
@@ -100,6 +103,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
         if (mBackgroundTintHelper != null) {
@@ -113,6 +117,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public ColorStateList getSupportBackgroundTintList() {
@@ -126,6 +131,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mBackgroundTintHelper != null) {
@@ -139,6 +145,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public PorterDuff.Mode getSupportBackgroundTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
index 5cb9ef7..c850f11 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatMultiAutoCompleteTextView.java
@@ -22,12 +22,15 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
 import android.support.v7.appcompat.R;
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
 import android.widget.MultiAutoCompleteTextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link MultiAutoCompleteTextView} which supports compatible features on older version of the
  * platform, including:
@@ -106,6 +109,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
         if (mBackgroundTintHelper != null) {
@@ -119,6 +123,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public ColorStateList getSupportBackgroundTintList() {
@@ -132,6 +137,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mBackgroundTintHelper != null) {
@@ -145,6 +151,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public PorterDuff.Mode getSupportBackgroundTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java b/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java
index 13bb3ed..3b6cf44 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatPopupWindow.java
@@ -22,6 +22,7 @@
 import android.support.annotation.AttrRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.v4.widget.PopupWindowCompat;
 import android.support.v7.appcompat.R;
@@ -34,6 +35,8 @@
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 class AppCompatPopupWindow extends PopupWindow {
 
     private static final String TAG = "AppCompatPopupWindow";
@@ -148,6 +151,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setSupportOverlapAnchor(boolean overlapAnchor) {
         if (COMPAT_OVERLAP_ANCHOR) {
             mOverlapAnchor = overlapAnchor;
@@ -159,6 +163,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public boolean getSupportOverlapAnchor() {
         if (COMPAT_OVERLAP_ANCHOR) {
             return mOverlapAnchor;
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java b/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java
index 67d0de0..5edbc83 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatRadioButton.java
@@ -22,12 +22,15 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.widget.TintableCompoundButton;
 import android.support.v7.appcompat.R;
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
 import android.widget.RadioButton;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link RadioButton} which supports compatible features on older version of the platform,
  * including:
@@ -84,6 +87,7 @@
      * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportButtonTintList(@Nullable ColorStateList tint) {
         if (mCompoundButtonHelper != null) {
@@ -95,6 +99,7 @@
      * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Nullable
     @Override
     public ColorStateList getSupportButtonTintList() {
@@ -107,6 +112,7 @@
      * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportButtonTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mCompoundButtonHelper != null) {
@@ -118,6 +124,7 @@
      * This should be accessed from {@link android.support.v4.widget.CompoundButtonCompat}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Nullable
     @Override
     public PorterDuff.Mode getSupportButtonTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java b/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java
index a497b86..cb026ed 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatSpinner.java
@@ -27,6 +27,7 @@
 import android.os.Build;
 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.view.ViewCompat;
 import android.support.v7.appcompat.R;
@@ -47,6 +48,8 @@
 import android.widget.Spinner;
 import android.widget.SpinnerAdapter;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 
 /**
  * A {@link Spinner} which supports compatible features on older versions of the platform,
@@ -64,7 +67,7 @@
  */
 public class AppCompatSpinner extends Spinner implements TintableBackgroundView {
 
-    private static final boolean IS_AT_LEAST_M = Build.VERSION.SDK_INT >= 23;
+    static final boolean IS_AT_LEAST_M = Build.VERSION.SDK_INT >= 23;
     private static final boolean IS_AT_LEAST_JB = Build.VERSION.SDK_INT >= 16;
 
     private static final int[] ATTRS_ANDROID_SPINNERMODE = {android.R.attr.spinnerMode};
@@ -90,11 +93,11 @@
 
     private boolean mPopupSet;
 
-    private DropdownPopup mPopup;
+    DropdownPopup mPopup;
 
-    private int mDropDownWidth;
+    int mDropDownWidth;
 
-    private final Rect mTempRect = new Rect();
+    final Rect mTempRect = new Rect();
 
     /**
      * Construct a new spinner with the given context's theme.
@@ -475,6 +478,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
         if (mBackgroundTintHelper != null) {
@@ -488,6 +492,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public ColorStateList getSupportBackgroundTintList() {
@@ -502,6 +507,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mBackgroundTintHelper != null) {
@@ -515,6 +521,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public PorterDuff.Mode getSupportBackgroundTintMode() {
@@ -530,7 +537,7 @@
         }
     }
 
-    private int compatMeasureContentWidth(SpinnerAdapter adapter, Drawable background) {
+    int compatMeasureContentWidth(SpinnerAdapter adapter, Drawable background) {
         if (adapter == null) {
             return 0;
         }
@@ -693,7 +700,7 @@
 
     private class DropdownPopup extends ListPopupWindow {
         private CharSequence mHintText;
-        private ListAdapter mAdapter;
+        ListAdapter mAdapter;
         private final Rect mVisibleRect = new Rect();
 
         public DropdownPopup(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -821,7 +828,7 @@
         /**
          * Simplified version of the the hidden View.isVisibleToUser()
          */
-        private boolean isVisibleToUser(View view) {
+        boolean isVisibleToUser(View view) {
             return ViewCompat.isAttachedToWindow(view) && view.getGlobalVisibleRect(mVisibleRect);
         }
     }
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java b/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
index 6f5637c..01c9849 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatTextHelper.java
@@ -81,6 +81,7 @@
         boolean allCaps = false;
         boolean allCapsSet = false;
         ColorStateList textColor = null;
+        ColorStateList textColorHint = null;
 
         // First check TextAppearance's textAllCaps value
         if (ap != -1) {
@@ -89,11 +90,16 @@
                 allCapsSet = true;
                 allCaps = a.getBoolean(R.styleable.TextAppearance_textAllCaps, false);
             }
-            if (Build.VERSION.SDK_INT < 23
-                    && a.hasValue(R.styleable.TextAppearance_android_textColor)) {
+            if (Build.VERSION.SDK_INT < 23) {
                 // If we're running on < API 23, the text color may contain theme references
                 // so let's re-set using our own inflater
-                textColor = a.getColorStateList(R.styleable.TextAppearance_android_textColor);
+                if (a.hasValue(R.styleable.TextAppearance_android_textColor)) {
+                    textColor = a.getColorStateList(R.styleable.TextAppearance_android_textColor);
+                }
+                if (a.hasValue(R.styleable.TextAppearance_android_textColorHint)) {
+                    textColorHint = a.getColorStateList(
+                            R.styleable.TextAppearance_android_textColorHint);
+                }
             }
             a.recycle();
         }
@@ -105,18 +111,25 @@
             allCapsSet = true;
             allCaps = a.getBoolean(R.styleable.TextAppearance_textAllCaps, false);
         }
-        if (Build.VERSION.SDK_INT < 23
-                && a.hasValue(R.styleable.TextAppearance_android_textColor)) {
+        if (Build.VERSION.SDK_INT < 23) {
             // If we're running on < API 23, the text color may contain theme references
             // so let's re-set using our own inflater
-            textColor = a.getColorStateList(R.styleable.TextAppearance_android_textColor);
+            if (a.hasValue(R.styleable.TextAppearance_android_textColor)) {
+                textColor = a.getColorStateList(R.styleable.TextAppearance_android_textColor);
+            }
+            if (a.hasValue(R.styleable.TextAppearance_android_textColorHint)) {
+                textColorHint = a.getColorStateList(
+                        R.styleable.TextAppearance_android_textColorHint);
+            }
         }
         a.recycle();
 
         if (textColor != null) {
             mView.setTextColor(textColor);
         }
-
+        if (textColorHint != null) {
+            mView.setHintTextColor(textColorHint);
+        }
         if (!hasPwdTm && allCapsSet) {
             setAllCaps(allCaps);
         }
diff --git a/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java b/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java
index 242541e..276d5c4 100644
--- a/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java
+++ b/v7/appcompat/src/android/support/v7/widget/AppCompatTextView.java
@@ -22,11 +22,14 @@
 import android.graphics.drawable.Drawable;
 import android.support.annotation.DrawableRes;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.TintableBackgroundView;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link TextView} which supports compatible features on older version of the platform,
  * including:
@@ -88,6 +91,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintList(@Nullable ColorStateList tint) {
         if (mBackgroundTintHelper != null) {
@@ -101,6 +105,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public ColorStateList getSupportBackgroundTintList() {
@@ -114,6 +119,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void setSupportBackgroundTintMode(@Nullable PorterDuff.Mode tintMode) {
         if (mBackgroundTintHelper != null) {
@@ -127,6 +133,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     @Nullable
     public PorterDuff.Mode getSupportBackgroundTintMode() {
diff --git a/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java b/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
index a2827b6..4f08f90 100644
--- a/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/ButtonBarLayout.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.ConfigurationHelper;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
@@ -26,12 +27,15 @@
 import android.view.View;
 import android.widget.LinearLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * An extension of LinearLayout that automatically switches to vertical
  * orientation when it can't fit its child views horizontally.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ButtonBarLayout extends LinearLayout {
     // Whether to allow vertically stacked button bars. This is disabled for
     // configurations with a small (e.g. less than 320dp) screen height. -->
diff --git a/v7/appcompat/src/android/support/v7/widget/ContentFrameLayout.java b/v7/appcompat/src/android/support/v7/widget/ContentFrameLayout.java
index 9a0de68..f656370 100644
--- a/v7/appcompat/src/android/support/v7/widget/ContentFrameLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/ContentFrameLayout.java
@@ -18,12 +18,14 @@
 
 import android.content.Context;
 import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.TypedValue;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.view.View.MeasureSpec.AT_MOST;
 import static android.view.View.MeasureSpec.EXACTLY;
 import static android.view.View.MeasureSpec.getMode;
@@ -65,6 +67,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void dispatchFitSystemWindows(Rect insets) {
         fitSystemWindows(insets);
     }
@@ -79,6 +82,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setDecorPadding(int left, int top, int right, int bottom) {
         mDecorPadding.set(left, top, right, bottom);
         if (ViewCompat.isLaidOut(this)) {
diff --git a/v7/appcompat/src/android/support/v7/widget/DecorContentParent.java b/v7/appcompat/src/android/support/v7/widget/DecorContentParent.java
index a311416..ca83469 100644
--- a/v7/appcompat/src/android/support/v7/widget/DecorContentParent.java
+++ b/v7/appcompat/src/android/support/v7/widget/DecorContentParent.java
@@ -19,17 +19,21 @@
 
 import android.graphics.drawable.Drawable;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v7.view.menu.MenuPresenter;
 import android.util.SparseArray;
 import android.view.Menu;
 import android.view.Window;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Implemented by the top-level decor layout for a window. DecorContentParent offers
  * entry points for a number of title/window decor features.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface DecorContentParent {
     void setWindowCallback(Window.Callback cb);
     void setWindowTitle(CharSequence title);
diff --git a/v7/appcompat/src/android/support/v7/widget/DecorToolbar.java b/v7/appcompat/src/android/support/v7/widget/DecorToolbar.java
index a334139..fb9081c 100644
--- a/v7/appcompat/src/android/support/v7/widget/DecorToolbar.java
+++ b/v7/appcompat/src/android/support/v7/widget/DecorToolbar.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewPropertyAnimatorCompat;
 import android.support.v7.view.menu.MenuBuilder;
 import android.support.v7.view.menu.MenuPresenter;
@@ -31,6 +32,8 @@
 import android.widget.AdapterView;
 import android.widget.SpinnerAdapter;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Common interface for a toolbar that sits as part of the window decor.
  * Layouts that control window decor use this as a point of interaction with different
@@ -38,6 +41,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface DecorToolbar {
     ViewGroup getViewGroup();
     Context getContext();
diff --git a/v7/appcompat/src/android/support/v7/widget/DialogTitle.java b/v7/appcompat/src/android/support/v7/widget/DialogTitle.java
index 052efff..bc81ca4 100644
--- a/v7/appcompat/src/android/support/v7/widget/DialogTitle.java
+++ b/v7/appcompat/src/android/support/v7/widget/DialogTitle.java
@@ -18,18 +18,22 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.support.annotation.RestrictTo;
 import android.support.v7.appcompat.R;
 import android.text.Layout;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Used by dialogs to change the font size and number of lines to try to fit
  * the text to the available space.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class DialogTitle extends TextView {
 
     public DialogTitle(Context context, AttributeSet attrs, int defStyleAttr) {
diff --git a/v7/appcompat/src/android/support/v7/widget/DrawableUtils.java b/v7/appcompat/src/android/support/v7/widget/DrawableUtils.java
index 9bdcad3..51383e9 100644
--- a/v7/appcompat/src/android/support/v7/widget/DrawableUtils.java
+++ b/v7/appcompat/src/android/support/v7/widget/DrawableUtils.java
@@ -27,13 +27,17 @@
 import android.graphics.drawable.StateListDrawable;
 import android.os.Build;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.util.Log;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /** @hide */
+@RestrictTo(GROUP_ID)
 public class DrawableUtils {
 
     private static final String TAG = "DrawableUtils";
diff --git a/v7/appcompat/src/android/support/v7/widget/FitWindowsFrameLayout.java b/v7/appcompat/src/android/support/v7/widget/FitWindowsFrameLayout.java
index 53750f8..1ec3c3e 100644
--- a/v7/appcompat/src/android/support/v7/widget/FitWindowsFrameLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/FitWindowsFrameLayout.java
@@ -18,12 +18,16 @@
 
 import android.content.Context;
 import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.widget.FrameLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class FitWindowsFrameLayout extends FrameLayout implements FitWindowsViewGroup {
 
     private OnFitSystemWindowsListener mListener;
diff --git a/v7/appcompat/src/android/support/v7/widget/FitWindowsLinearLayout.java b/v7/appcompat/src/android/support/v7/widget/FitWindowsLinearLayout.java
index fd8737f..359849b 100644
--- a/v7/appcompat/src/android/support/v7/widget/FitWindowsLinearLayout.java
+++ b/v7/appcompat/src/android/support/v7/widget/FitWindowsLinearLayout.java
@@ -18,12 +18,16 @@
 
 import android.content.Context;
 import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.widget.LinearLayout;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class FitWindowsLinearLayout extends LinearLayout implements FitWindowsViewGroup {
 
     private OnFitSystemWindowsListener mListener;
diff --git a/v7/appcompat/src/android/support/v7/widget/FitWindowsViewGroup.java b/v7/appcompat/src/android/support/v7/widget/FitWindowsViewGroup.java
index 098a23e..16a07c8 100644
--- a/v7/appcompat/src/android/support/v7/widget/FitWindowsViewGroup.java
+++ b/v7/appcompat/src/android/support/v7/widget/FitWindowsViewGroup.java
@@ -17,16 +17,19 @@
 package android.support.v7.widget;
 
 import android.graphics.Rect;
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface FitWindowsViewGroup {
 
-    public interface OnFitSystemWindowsListener {
+    interface OnFitSystemWindowsListener {
         void onFitSystemWindows(Rect insets);
     }
 
-    public void setOnFitSystemWindowsListener(OnFitSystemWindowsListener listener);
-
+    void setOnFitSystemWindowsListener(OnFitSystemWindowsListener listener);
 }
diff --git a/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java b/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java
index 3e4d063..0a6e158 100644
--- a/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java
+++ b/v7/appcompat/src/android/support/v7/widget/ForwardingListener.java
@@ -18,6 +18,7 @@
 
 import android.os.Build;
 import android.os.SystemClock;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.MotionEventCompat;
 import android.support.v7.view.menu.ShowableListMenu;
 import android.view.MotionEvent;
@@ -27,12 +28,15 @@
 import android.view.ViewParent;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 
 /**
  * Abstract class that forwards touch events to a {@link ShowableListMenu}.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public abstract class ForwardingListener implements View.OnTouchListener {
 
     /** Scaled touch slop, used for detecting movement outside bounds. */
@@ -45,7 +49,7 @@
     private final int mLongPressTimeout;
 
     /** Source view from which events are forwarded. */
-    private final View mSrc;
+    final View mSrc;
 
     /** Runnable used to prevent conflicts with scrolling parents. */
     private Runnable mDisallowIntercept;
@@ -248,7 +252,7 @@
         }
     }
 
-    private void onLongPress() {
+    void onLongPress() {
         clearCallbacks();
 
         final View src = mSrc;
@@ -339,6 +343,9 @@
     }
 
     private class DisallowIntercept implements Runnable {
+        DisallowIntercept() {
+        }
+
         @Override
         public void run() {
             final ViewParent parent = mSrc.getParent();
@@ -349,6 +356,9 @@
     }
 
     private class TriggerLongPress implements Runnable {
+        TriggerLongPress() {
+        }
+
         @Override
         public void run() {
             onLongPress();
diff --git a/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java b/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java
index 523336b..eacd17d 100644
--- a/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java
+++ b/v7/appcompat/src/android/support/v7/widget/LinearLayoutCompat.java
@@ -22,6 +22,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.support.annotation.IntDef;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.appcompat.R;
@@ -35,6 +36,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 
 /**
  * A Layout that arranges its children in a single column or a single row. The direction of
@@ -53,6 +56,7 @@
  */
 public class LinearLayoutCompat extends ViewGroup {
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef({HORIZONTAL, VERTICAL})
     @Retention(RetentionPolicy.SOURCE)
     public @interface OrientationMode {}
@@ -61,6 +65,7 @@
     public static final int VERTICAL = 1;
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @IntDef(flag = true,
             value = {
                     SHOW_DIVIDER_NONE,
@@ -268,6 +273,7 @@
      *
      * @hide Used internally by framework.
      */
+    @RestrictTo(GROUP_ID)
     public int getDividerWidth() {
         return mDividerWidth;
     }
diff --git a/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java b/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java
index de11489..0fe68d6 100644
--- a/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java
+++ b/v7/appcompat/src/android/support/v7/widget/ListPopupWindow.java
@@ -26,6 +26,7 @@
 import android.support.annotation.AttrRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StyleRes;
 import android.support.v4.os.BuildCompat;
 import android.support.v4.view.ViewCompat;
@@ -53,6 +54,8 @@
 
 import java.lang.reflect.Method;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Static library support version of the framework's {@link android.widget.ListPopupWindow}.
  * Used to write apps that run on platforms prior to Android L. When running
@@ -71,7 +74,7 @@
      * must leave a pointer down without scrolling to expand
      * the autocomplete dropdown list to cover the IME.
      */
-    private static final int EXPAND_LIST_TIMEOUT = 250;
+    static final int EXPAND_LIST_TIMEOUT = 250;
 
     private static Method sClipToWindowEnabledMethod;
     private static Method sGetMaxAvailableHeightMethod;
@@ -101,7 +104,7 @@
 
     private Context mContext;
     private ListAdapter mAdapter;
-    private DropDownListView mDropDownList;
+    DropDownListView mDropDownList;
 
     private int mDropDownHeight = ViewGroup.LayoutParams.WRAP_CONTENT;
     private int mDropDownWidth = ViewGroup.LayoutParams.WRAP_CONTENT;
@@ -129,13 +132,13 @@
     private AdapterView.OnItemClickListener mItemClickListener;
     private OnItemSelectedListener mItemSelectedListener;
 
-    private final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable();
+    final ResizePopupRunnable mResizePopupRunnable = new ResizePopupRunnable();
     private final PopupTouchInterceptor mTouchInterceptor = new PopupTouchInterceptor();
     private final PopupScrollListener mScrollListener = new PopupScrollListener();
     private final ListSelectorHider mHideSelector = new ListSelectorHider();
     private Runnable mShowDropDownRunnable;
 
-    private final Handler mHandler;
+    final Handler mHandler;
 
     private final Rect mTempRect = new Rect();
 
@@ -346,6 +349,7 @@
      *
      * @hide Used only by AutoCompleteTextView to handle some internal special cases.
      */
+    @RestrictTo(GROUP_ID)
     public void setForceIgnoreOutsideTouch(boolean forceIgnoreOutsideTouch) {
         mForceIgnoreOutsideTouch = forceIgnoreOutsideTouch;
     }
@@ -361,6 +365,7 @@
      *
      * @hide Only used by AutoCompleteTextView under special conditions.
      */
+    @RestrictTo(GROUP_ID)
     public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) {
         mDropDownAlwaysVisible = dropDownAlwaysVisible;
     }
@@ -370,6 +375,7 @@
      *
      * @hide Only used by AutoCompleteTextView under special conditions.
      */
+    @RestrictTo(GROUP_ID)
     public boolean isDropDownAlwaysVisible() {
         return mDropDownAlwaysVisible;
     }
@@ -504,6 +510,7 @@
      * @param bounds anchor-relative bounds
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setEpicenterBounds(Rect bounds) {
         mEpicenterBounds = bounds;
     }
@@ -1291,6 +1298,9 @@
     }
 
     private class PopupDataSetObserver extends DataSetObserver {
+        PopupDataSetObserver() {
+        }
+
         @Override
         public void onChanged() {
             if (isShowing()) {
@@ -1306,6 +1316,9 @@
     }
 
     private class ListSelectorHider implements Runnable {
+        ListSelectorHider() {
+        }
+
         @Override
         public void run() {
             clearListSelection();
@@ -1313,6 +1326,9 @@
     }
 
     private class ResizePopupRunnable implements Runnable {
+        ResizePopupRunnable() {
+        }
+
         @Override
         public void run() {
             if (mDropDownList != null && ViewCompat.isAttachedToWindow(mDropDownList)
@@ -1325,6 +1341,9 @@
     }
 
     private class PopupTouchInterceptor implements OnTouchListener {
+        PopupTouchInterceptor() {
+        }
+
         @Override
         public boolean onTouch(View v, MotionEvent event) {
             final int action = event.getAction();
@@ -1343,6 +1362,9 @@
     }
 
     private class PopupScrollListener implements ListView.OnScrollListener {
+        PopupScrollListener() {
+        }
+
         @Override
         public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                 int totalItemCount) {
diff --git a/v7/appcompat/src/android/support/v7/widget/ListViewCompat.java b/v7/appcompat/src/android/support/v7/widget/ListViewCompat.java
index 87056d1..fab68d1 100644
--- a/v7/appcompat/src/android/support/v7/widget/ListViewCompat.java
+++ b/v7/appcompat/src/android/support/v7/widget/ListViewCompat.java
@@ -20,6 +20,7 @@
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.graphics.drawable.DrawableCompat;
 import android.support.v7.graphics.drawable.DrawableWrapper;
 import android.util.AttributeSet;
@@ -32,12 +33,15 @@
 
 import java.lang.reflect.Field;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This class contains a number of useful things for ListView. Mainly used by
  * {@link android.support.v7.widget.ListPopupWindow}.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ListViewCompat extends ListView {
 
     public static final int INVALID_POSITION = -1;
diff --git a/v7/appcompat/src/android/support/v7/widget/MenuItemHoverListener.java b/v7/appcompat/src/android/support/v7/widget/MenuItemHoverListener.java
index a1e5645..02b71a8 100644
--- a/v7/appcompat/src/android/support/v7/widget/MenuItemHoverListener.java
+++ b/v7/appcompat/src/android/support/v7/widget/MenuItemHoverListener.java
@@ -17,15 +17,19 @@
 package android.support.v7.widget;
 
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v7.view.menu.MenuBuilder;
 import android.view.MenuItem;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * An interface notified when a menu item is hovered. Useful for cases when hover should trigger
  * some behavior at a higher level, like managing the opening and closing of submenus.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public interface MenuItemHoverListener {
     /**
      * Called when hover exits a menu item.
diff --git a/v7/appcompat/src/android/support/v7/widget/MenuPopupWindow.java b/v7/appcompat/src/android/support/v7/widget/MenuPopupWindow.java
index 7d3f77c..e877c19 100644
--- a/v7/appcompat/src/android/support/v7/widget/MenuPopupWindow.java
+++ b/v7/appcompat/src/android/support/v7/widget/MenuPopupWindow.java
@@ -21,6 +21,7 @@
 import android.content.res.Resources;
 import android.os.Build;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.widget.PopupWindowCompat;
 import android.support.v7.view.menu.ListMenuItemView;
@@ -40,6 +41,8 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A MenuPopupWindow represents the popup window for menu.
  *
@@ -48,6 +51,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class MenuPopupWindow extends ListPopupWindow implements MenuItemHoverListener {
     private static final String TAG = "MenuPopupWindow";
 
@@ -124,6 +128,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class MenuDropDownListView extends DropDownListView {
         final int mAdvanceKey;
         final int mRetreatKey;
diff --git a/v7/appcompat/src/android/support/v7/widget/PopupMenu.java b/v7/appcompat/src/android/support/v7/widget/PopupMenu.java
index 066c7e0..8377010 100644
--- a/v7/appcompat/src/android/support/v7/widget/PopupMenu.java
+++ b/v7/appcompat/src/android/support/v7/widget/PopupMenu.java
@@ -45,10 +45,10 @@
     private final Context mContext;
     private final MenuBuilder mMenu;
     private final View mAnchor;
-    private final MenuPopupHelper mPopup;
+    final MenuPopupHelper mPopup;
 
-    private OnMenuItemClickListener mMenuItemClickListener;
-    private OnDismissListener mOnDismissListener;
+    OnMenuItemClickListener mMenuItemClickListener;
+    OnDismissListener mOnDismissListener;
     private View.OnTouchListener mDragListener;
 
     /**
diff --git a/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java b/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
index 670579a..7069965 100644
--- a/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
+++ b/v7/appcompat/src/android/support/v7/widget/ScrollingTabContainerView.java
@@ -19,6 +19,7 @@
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.GravityCompat;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.ViewPropertyAnimatorCompat;
@@ -45,12 +46,15 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This widget implements the dynamic action bar tab behavior that can change across different
  * configurations or circumstances.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ScrollingTabContainerView extends HorizontalScrollView
         implements AdapterView.OnItemSelectedListener {
 
@@ -58,7 +62,7 @@
     Runnable mTabSelector;
     private TabClickListener mTabClickListener;
 
-    private LinearLayoutCompat mTabLayout;
+    LinearLayoutCompat mTabLayout;
     private Spinner mTabSpinner;
     private boolean mAllowCollapse;
 
@@ -285,7 +289,7 @@
         }
     }
 
-    private TabView createTabView(ActionBar.Tab tab, boolean forAdapter) {
+    TabView createTabView(ActionBar.Tab tab, boolean forAdapter) {
         final TabView tabView = new TabView(getContext(), tab, forAdapter);
         if (forAdapter) {
             tabView.setBackgroundDrawable(null);
@@ -543,6 +547,9 @@
     }
 
     private class TabAdapter extends BaseAdapter {
+        TabAdapter() {
+        }
+
         @Override
         public int getCount() {
             return mTabLayout.getChildCount();
@@ -570,6 +577,9 @@
     }
 
     private class TabClickListener implements OnClickListener {
+        TabClickListener() {
+        }
+
         @Override
         public void onClick(View view) {
             TabView tabView = (TabView) view;
diff --git a/v7/appcompat/src/android/support/v7/widget/SearchView.java b/v7/appcompat/src/android/support/v7/widget/SearchView.java
index d823324..b224b42 100644
--- a/v7/appcompat/src/android/support/v7/widget/SearchView.java
+++ b/v7/appcompat/src/android/support/v7/widget/SearchView.java
@@ -16,6 +16,7 @@
 
 package android.support.v7.widget;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v7.widget.SuggestionsAdapter.getColumnString;
 
 import android.annotation.TargetApi;
@@ -41,6 +42,7 @@
 import android.os.ResultReceiver;
 import android.speech.RecognizerIntent;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.ConfigurationHelper;
 import android.support.v4.os.ParcelableCompat;
 import android.support.v4.os.ParcelableCompatCreatorCallbacks;
@@ -113,22 +115,22 @@
  */
 public class SearchView extends LinearLayoutCompat implements CollapsibleActionView {
 
-    private static final boolean DBG = false;
-    private static final String LOG_TAG = "SearchView";
+    static final boolean DBG = false;
+    static final String LOG_TAG = "SearchView";
 
     /**
      * Private constant for removing the microphone in the keyboard.
      */
     private static final String IME_OPTION_NO_MICROPHONE = "nm";
 
-    private final SearchAutoComplete mSearchSrcTextView;
+    final SearchAutoComplete mSearchSrcTextView;
     private final View mSearchEditFrame;
     private final View mSearchPlate;
     private final View mSubmitArea;
-    private final ImageView mSearchButton;
-    private final ImageView mGoButton;
-    private final ImageView mCloseButton;
-    private final ImageView mVoiceButton;
+    final ImageView mSearchButton;
+    final ImageView mGoButton;
+    final ImageView mCloseButton;
+    final ImageView mVoiceButton;
     private final View mDropDownAnchor;
 
     private UpdatableTouchDelegate mTouchDelegate;
@@ -155,13 +157,13 @@
 
     private OnQueryTextListener mOnQueryChangeListener;
     private OnCloseListener mOnCloseListener;
-    private OnFocusChangeListener mOnQueryTextFocusChangeListener;
+    OnFocusChangeListener mOnQueryTextFocusChangeListener;
     private OnSuggestionListener mOnSuggestionListener;
     private OnClickListener mOnSearchClickListener;
 
     private boolean mIconifiedByDefault;
     private boolean mIconified;
-    private CursorAdapter mSuggestionsAdapter;
+    CursorAdapter mSuggestionsAdapter;
     private boolean mSubmitButtonEnabled;
     private CharSequence mQueryHint;
     private boolean mQueryRefinement;
@@ -173,7 +175,7 @@
     private boolean mExpandedInActionView;
     private int mCollapsedImeOptions;
 
-    private SearchableInfo mSearchable;
+    SearchableInfo mSearchable;
     private Bundle mAppSearchData;
 
     static final AutoCompleteTextViewReflector HIDDEN_METHOD_INVOKER = new AutoCompleteTextViewReflector();
@@ -459,6 +461,7 @@
      * @param appSearchData bundle provided by the app when launching the search dialog
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setAppSearchData(Bundle appSearchData) {
         mAppSearchData = appSearchData;
     }
@@ -509,6 +512,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
         // Don't accept focus if in the middle of clearing focus
@@ -528,6 +532,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     public void clearFocus() {
         mClearingFocus = true;
@@ -979,7 +984,7 @@
         post(mUpdateDrawableStateRunnable);
     }
 
-    private void updateFocusedState() {
+    void updateFocusedState() {
         final boolean focused = mSearchSrcTextView.hasFocus();
         final int[] stateSet = focused ? FOCUSED_STATE_SET : EMPTY_STATE_SET;
         final Drawable searchPlateBg = mSearchPlate.getBackground();
@@ -1000,7 +1005,7 @@
         super.onDetachedFromWindow();
     }
 
-    private void setImeVisibility(final boolean visible) {
+    void setImeVisibility(final boolean visible) {
         if (visible) {
             post(mShowImeRunnable);
         } else {
@@ -1016,9 +1021,8 @@
 
     /**
      * Called by the SuggestionsAdapter
-     * @hide
      */
-    /* package */void onQueryRefine(CharSequence queryText) {
+    void onQueryRefine(CharSequence queryText) {
         setQuery(queryText);
     }
 
@@ -1087,7 +1091,7 @@
      * action keys. If not handled, try refocusing regular characters into the
      * EditText.
      */
-    private boolean onSuggestionsKey(View v, int keyCode, KeyEvent event) {
+    boolean onSuggestionsKey(View v, int keyCode, KeyEvent event) {
         // guard against possible race conditions (late arrival after dismiss)
         if (mSearchable == null) {
             return false;
@@ -1219,7 +1223,7 @@
         }
     };
 
-    private void onTextChanged(CharSequence newText) {
+    void onTextChanged(CharSequence newText) {
         CharSequence text = mSearchSrcTextView.getText();
         mUserQuery = text;
         boolean hasText = !TextUtils.isEmpty(text);
@@ -1233,7 +1237,7 @@
         mOldQueryText = newText.toString();
     }
 
-    private void onSubmitQuery() {
+    void onSubmitQuery() {
         CharSequence query = mSearchSrcTextView.getText();
         if (query != null && TextUtils.getTrimmedLength(query) > 0) {
             if (mOnQueryChangeListener == null
@@ -1251,7 +1255,7 @@
         mSearchSrcTextView.dismissDropDown();
     }
 
-    private void onCloseClicked() {
+    void onCloseClicked() {
         CharSequence text = mSearchSrcTextView.getText();
         if (TextUtils.isEmpty(text)) {
             if (mIconifiedByDefault) {
@@ -1271,7 +1275,7 @@
 
     }
 
-    private void onSearchClicked() {
+    void onSearchClicked() {
         updateViewsVisibility(false);
         mSearchSrcTextView.requestFocus();
         setImeVisibility(true);
@@ -1280,7 +1284,7 @@
         }
     }
 
-    private void onVoiceClicked() {
+    void onVoiceClicked() {
         // guard against possible race conditions
         if (mSearchable == null) {
             return;
@@ -1405,7 +1409,7 @@
         requestLayout();
     }
 
-    private void adjustDropDownSizeAndPosition() {
+    void adjustDropDownSizeAndPosition() {
         if (mDropDownAnchor.getWidth() > 1) {
             Resources res = getContext().getResources();
             int anchorPadding = mSearchPlate.getPaddingLeft();
@@ -1429,7 +1433,7 @@
         }
     }
 
-    private boolean onItemClicked(int position, int actionKey, String actionMsg) {
+    boolean onItemClicked(int position, int actionKey, String actionMsg) {
         if (mOnSuggestionListener == null
                 || !mOnSuggestionListener.onSuggestionClick(position)) {
             launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null);
@@ -1440,7 +1444,7 @@
         return false;
     }
 
-    private boolean onItemSelected(int position) {
+    boolean onItemSelected(int position) {
         if (mOnSuggestionListener == null
                 || !mOnSuggestionListener.onSuggestionSelect(position)) {
             rewriteQueryFromSuggestion(position);
@@ -1557,7 +1561,7 @@
         mSearchSrcTextView.setSelection(TextUtils.isEmpty(query) ? 0 : query.length());
     }
 
-    private void launchQuerySearch(int actionKey, String actionMsg, String query) {
+    void launchQuerySearch(int actionKey, String actionMsg, String query) {
         String action = Intent.ACTION_SEARCH;
         Intent intent = createIntent(action, null, null, query, actionKey, actionMsg);
         getContext().startActivity(intent);
@@ -1738,7 +1742,7 @@
         }
     }
 
-    private void forceSuggestionQuery() {
+    void forceSuggestionQuery() {
         HIDDEN_METHOD_INVOKER.doBeforeTextChanged(mSearchSrcTextView);
         HIDDEN_METHOD_INVOKER.doAfterTextChanged(mSearchSrcTextView);
     }
@@ -1865,6 +1869,7 @@
      * Local subclass for AutoCompleteTextView.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class SearchAutoComplete extends AppCompatAutoCompleteTextView {
 
         private int mThreshold;
diff --git a/v7/appcompat/src/android/support/v7/widget/ShareActionProvider.java b/v7/appcompat/src/android/support/v7/widget/ShareActionProvider.java
index 8928130..046252b 100644
--- a/v7/appcompat/src/android/support/v7/widget/ShareActionProvider.java
+++ b/v7/appcompat/src/android/support/v7/widget/ShareActionProvider.java
@@ -176,14 +176,14 @@
     /**
      * Context for accessing resources.
      */
-    private final Context mContext;
+    final Context mContext;
 
     /**
      * The name of the file with share history data.
      */
-    private String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME;
+    String mShareHistoryFileName = DEFAULT_SHARE_HISTORY_FILE_NAME;
 
-    private OnShareTargetSelectedListener mOnShareTargetSelectedListener;
+    OnShareTargetSelectedListener mOnShareTargetSelectedListener;
 
     private OnChooseActivityListener mOnChooseActivityListener;
 
@@ -353,6 +353,9 @@
      * Reusable listener for handling share item clicks.
      */
     private class ShareMenuItemOnMenuItemClickListener implements OnMenuItemClickListener {
+        ShareMenuItemOnMenuItemClickListener() {
+        }
+
         @Override
         public boolean onMenuItemClick(MenuItem item) {
             ActivityChooserModel dataModel = ActivityChooserModel.get(mContext,
@@ -390,6 +393,9 @@
      * Policy that delegates to the {@link OnShareTargetSelectedListener}, if such.
      */
     private class ShareActivityChooserModelPolicy implements OnChooseActivityListener {
+        ShareActivityChooserModelPolicy() {
+        }
+
         @Override
         public boolean onChooseActivity(ActivityChooserModel host, Intent intent) {
             if (mOnShareTargetSelectedListener != null) {
@@ -400,7 +406,7 @@
         }
     }
 
-    private void updateIntent(Intent intent) {
+    void updateIntent(Intent intent) {
         if (Build.VERSION.SDK_INT >= 21) {
             // If we're on Lollipop, we can open the intent as a document
             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
diff --git a/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java b/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java
index 0f4351d..9f2975f 100644
--- a/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java
+++ b/v7/appcompat/src/android/support/v7/widget/SuggestionsAdapter.java
@@ -53,7 +53,6 @@
 
 /**
  * Provides the contents for the suggestion drop-down list.in {@link SearchView}.
- * @hide
  */
 class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListener {
 
diff --git a/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java b/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
index f0ac9db..c9e1dc8 100644
--- a/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
+++ b/v7/appcompat/src/android/support/v7/widget/SwitchCompat.java
@@ -160,7 +160,7 @@
     private Layout mOnLayout;
     private Layout mOffLayout;
     private TransformationMethod mSwitchTransformationMethod;
-    private ThumbAnimation mPositionAnimator;
+    ThumbAnimation mPositionAnimator;
 
     @SuppressWarnings("hiding")
     private final Rect mTempRect = new Rect();
@@ -282,7 +282,8 @@
      * @attr ref android.support.v7.appcompat.R.styleable#SwitchCompat_switchTextAppearance
      */
     public void setSwitchTextAppearance(Context context, int resid) {
-        TypedArray appearance = context.obtainStyledAttributes(resid, R.styleable.TextAppearance);
+        final TintTypedArray appearance = TintTypedArray.obtainStyledAttributes(context, resid,
+                R.styleable.TextAppearance);
 
         ColorStateList colors;
         int ts;
@@ -1046,7 +1047,7 @@
      *
      * @param position new position between [0,1]
      */
-    private void setThumbPosition(float position) {
+    void setThumbPosition(float position) {
         mThumbPosition = position;
         invalidate();
     }
@@ -1424,7 +1425,7 @@
         final float mEndPosition;
         final float mDiff;
 
-        private ThumbAnimation(float startPosition, float endPosition) {
+        ThumbAnimation(float startPosition, float endPosition) {
             mStartPosition = startPosition;
             mEndPosition = endPosition;
             mDiff = endPosition - startPosition;
diff --git a/v7/appcompat/src/android/support/v7/widget/TintContextWrapper.java b/v7/appcompat/src/android/support/v7/widget/TintContextWrapper.java
index f15ca46..19c62db 100644
--- a/v7/appcompat/src/android/support/v7/widget/TintContextWrapper.java
+++ b/v7/appcompat/src/android/support/v7/widget/TintContextWrapper.java
@@ -21,18 +21,22 @@
 import android.content.res.Resources;
 import android.os.Build;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v7.app.AppCompatDelegate;
 import android.support.v7.widget.VectorEnabledTintResources;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link android.content.ContextWrapper} which returns a tint-aware
  * {@link android.content.res.Resources} instance from {@link #getResources()}.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class TintContextWrapper extends ContextWrapper {
 
     private static final ArrayList<WeakReference<TintContextWrapper>> sCache = new ArrayList<>();
diff --git a/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java b/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
index 977df96..5725b37 100644
--- a/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
+++ b/v7/appcompat/src/android/support/v7/widget/TintTypedArray.java
@@ -22,10 +22,13 @@
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v7.content.res.AppCompatResources;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A class that wraps a {@link android.content.res.TypedArray} and provides the same public API
  * surface. The purpose of this class is so that we can intercept the {@link #getDrawable(int)}
@@ -33,6 +36,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class TintTypedArray {
 
     private final Context mContext;
diff --git a/v7/appcompat/src/android/support/v7/widget/Toolbar.java b/v7/appcompat/src/android/support/v7/widget/Toolbar.java
index a6e7434..c69f147 100644
--- a/v7/appcompat/src/android/support/v7/widget/Toolbar.java
+++ b/v7/appcompat/src/android/support/v7/widget/Toolbar.java
@@ -26,6 +26,7 @@
 import android.support.annotation.MenuRes;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.StringRes;
 import android.support.annotation.StyleRes;
 import android.support.v4.os.ParcelableCompat;
@@ -64,6 +65,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A standard toolbar for use within application content.
  *
@@ -149,7 +152,7 @@
 
     private Drawable mCollapseIcon;
     private CharSequence mCollapseDescription;
-    private ImageButton mCollapseButtonView;
+    ImageButton mCollapseButtonView;
     View mExpandedActionView;
 
     /** Context against which to inflate popup menus. */
@@ -161,7 +164,7 @@
     private int mTitleTextAppearance;
     private int mSubtitleTextAppearance;
 
-    private int mButtonGravity;
+    int mButtonGravity;
 
     private int mMaxButtonHeight;
 
@@ -193,7 +196,7 @@
 
     private final int[] mTempMargins = new int[2];
 
-    private OnMenuItemClickListener mOnMenuItemClickListener;
+    OnMenuItemClickListener mOnMenuItemClickListener;
 
     private final ActionMenuView.OnMenuItemClickListener mMenuViewItemClickListener =
             new ActionMenuView.OnMenuItemClickListener() {
@@ -500,6 +503,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean canShowOverflowMenu() {
         return getVisibility() == VISIBLE && mMenuView != null && mMenuView.isOverflowReserved();
     }
@@ -515,6 +519,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean isOverflowMenuShowPending() {
         return mMenuView != null && mMenuView.isOverflowMenuShowPending();
     }
@@ -538,6 +543,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public void setMenu(MenuBuilder menu, ActionMenuPresenter outerPresenter) {
         if (menu == null && mMenuView == null) {
             return;
@@ -583,6 +589,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public boolean isTitleTruncated() {
         if (mTitleTextView == null) {
             return false;
@@ -1361,7 +1368,7 @@
         }
     }
 
-    private void ensureCollapseButtonView() {
+    void ensureCollapseButtonView() {
         if (mCollapseButtonView == null) {
             mCollapseButtonView = new AppCompatImageButton(getContext(), null,
                     R.attr.toolbarNavigationButtonStyle);
@@ -2102,6 +2109,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     public DecorToolbar getWrapper() {
         if (mWrapper == null) {
             mWrapper = new ToolbarWidgetWrapper(this, true);
@@ -2140,6 +2148,7 @@
      * it could be considered "empty" (no visible elements with nonzero measured size)
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setCollapsible(boolean collapsible) {
         mCollapsible = collapsible;
         requestLayout();
@@ -2149,6 +2158,7 @@
      * Must be called before the menu is accessed
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void setMenuCallbacks(MenuPresenter.Callback pcb, MenuBuilder.Callback mcb) {
         mActionMenuPresenterCallback = pcb;
         mMenuBuilderCallback = mcb;
@@ -2284,6 +2294,9 @@
         MenuBuilder mMenu;
         MenuItemImpl mCurrentExpandedItem;
 
+        ExpandedActionViewMenuPresenter() {
+        }
+
         @Override
         public void initForMenu(Context context, MenuBuilder menu) {
             // Clear the expanded action view when menus change.
diff --git a/v7/appcompat/src/android/support/v7/widget/ToolbarWidgetWrapper.java b/v7/appcompat/src/android/support/v7/widget/ToolbarWidgetWrapper.java
index 040fc90..eee9cf0 100644
--- a/v7/appcompat/src/android/support/v7/widget/ToolbarWidgetWrapper.java
+++ b/v7/appcompat/src/android/support/v7/widget/ToolbarWidgetWrapper.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.ViewPropertyAnimatorCompat;
 import android.support.v4.view.ViewPropertyAnimatorListenerAdapter;
@@ -43,6 +44,8 @@
 import android.widget.Spinner;
 import android.widget.SpinnerAdapter;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Internal class used to interact with the Toolbar widget without
  * exposing interface methods to the public API.
@@ -54,6 +57,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ToolbarWidgetWrapper implements DecorToolbar {
     private static final String TAG = "ToolbarWidgetWrapper";
 
@@ -62,7 +66,7 @@
     // Default fade duration for fading in/out tool bar.
     private static final long DEFAULT_FADE_DURATION_MS = 200;
 
-    private Toolbar mToolbar;
+    Toolbar mToolbar;
 
     private int mDisplayOpts;
     private View mTabView;
@@ -74,12 +78,12 @@
     private Drawable mNavIcon;
 
     private boolean mTitleSet;
-    private CharSequence mTitle;
+    CharSequence mTitle;
     private CharSequence mSubtitle;
     private CharSequence mHomeDescription;
 
-    private Window.Callback mWindowCallback;
-    private boolean mMenuPrepared;
+    Window.Callback mWindowCallback;
+    boolean mMenuPrepared;
     private ActionMenuPresenter mActionMenuPresenter;
 
     private int mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
diff --git a/v7/appcompat/src/android/support/v7/widget/VectorEnabledTintResources.java b/v7/appcompat/src/android/support/v7/widget/VectorEnabledTintResources.java
index 3dffa07..89423ce 100644
--- a/v7/appcompat/src/android/support/v7/widget/VectorEnabledTintResources.java
+++ b/v7/appcompat/src/android/support/v7/widget/VectorEnabledTintResources.java
@@ -21,16 +21,20 @@
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v7.app.AppCompatDelegate;
 
 import java.lang.ref.WeakReference;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * This class allows us to intercept calls so that we can tint resources (if applicable), and
  * inflate vector resources from within drawable containers pre-L.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class VectorEnabledTintResources extends Resources {
 
     public static boolean shouldBeUsed() {
diff --git a/v7/appcompat/src/android/support/v7/widget/ViewStubCompat.java b/v7/appcompat/src/android/support/v7/widget/ViewStubCompat.java
index 2b9c58e..eb9194b 100644
--- a/v7/appcompat/src/android/support/v7/widget/ViewStubCompat.java
+++ b/v7/appcompat/src/android/support/v7/widget/ViewStubCompat.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
+import android.support.annotation.RestrictTo;
 import android.support.v7.appcompat.R;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
@@ -28,12 +29,15 @@
 
 import java.lang.ref.WeakReference;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Backport of {@link android.view.ViewStub} so that we can set the
  * {@link android.view.LayoutInflater} on devices before Jelly Bean.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public final class ViewStubCompat extends View {
     private int mLayoutResource = 0;
     private int mInflatedId;
diff --git a/v7/appcompat/src/android/support/v7/widget/ViewUtils.java b/v7/appcompat/src/android/support/v7/widget/ViewUtils.java
index 0ae4951..72799ec 100644
--- a/v7/appcompat/src/android/support/v7/widget/ViewUtils.java
+++ b/v7/appcompat/src/android/support/v7/widget/ViewUtils.java
@@ -18,6 +18,7 @@
 
 import android.graphics.Rect;
 import android.os.Build;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.util.Log;
 import android.view.View;
@@ -25,9 +26,12 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class ViewUtils {
     private static final String TAG = "ViewUtils";
 
diff --git a/v7/appcompat/tests/res/drawable/test_night_color_conversion_background.xml b/v7/appcompat/tests/res/drawable/test_night_color_conversion_background.xml
new file mode 100644
index 0000000..dd32112
--- /dev/null
+++ b/v7/appcompat/tests/res/drawable/test_night_color_conversion_background.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@color/color_sky" />
+</selector>
\ No newline at end of file
diff --git a/v7/appcompat/tests/res/layout/activity_night_mode.xml b/v7/appcompat/tests/res/layout/activity_night_mode.xml
index 8f3463d..5cd8563 100644
--- a/v7/appcompat/tests/res/layout/activity_night_mode.xml
+++ b/v7/appcompat/tests/res/layout/activity_night_mode.xml
@@ -25,4 +25,10 @@
         android:layout_height="wrap_content"
         android:text="@string/night_mode" />
 
+    <View
+        android:id="@+id/view_background"
+        android:layout_width="100dp"
+        android:layout_height="100dp"
+        android:background="@drawable/test_night_color_conversion_background" />
+
 </LinearLayout>
\ No newline at end of file
diff --git a/v7/appcompat/tests/res/values-night/colors.xml b/v7/appcompat/tests/res/values-night/colors.xml
new file mode 100644
index 0000000..cf0fc9f
--- /dev/null
+++ b/v7/appcompat/tests/res/values-night/colors.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<resources>
+    <color name="color_sky">@color/color_sky_night</color>
+</resources>
diff --git a/v7/appcompat/tests/res/values/colors.xml b/v7/appcompat/tests/res/values/colors.xml
index 1f6fab2..8ec92b7 100644
--- a/v7/appcompat/tests/res/values/colors.xml
+++ b/v7/appcompat/tests/res/values/colors.xml
@@ -31,4 +31,9 @@
 
     <color name="emerald_translucent_default">#8020A060</color>
     <color name="emerald_translucent_disabled">#8070C090</color>
+
+    <color name="color_sky_day">#90F0FF</color>
+    <color name="color_sky_night">#3050CF</color>
+    <color name="color_sky">@color/color_sky_day</color>
+
 </resources>
diff --git a/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutTest.java b/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutTest.java
index ff63834..636e7d1 100755
--- a/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutTest.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/DrawerLayoutTest.java
@@ -16,6 +16,7 @@
 package android.support.v7.app;
 
 import android.os.Build;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.espresso.action.GeneralLocation;
 import android.support.test.espresso.action.GeneralSwipeAction;
 import android.support.test.espresso.action.Press;
@@ -94,6 +95,31 @@
 
     @Test
     @MediumTest
+    public void testDrawerOpenCloseFocus() {
+        assertFalse("Initial state", mDrawerLayout.isDrawerOpen(GravityCompat.START));
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mContentView.setFocusableInTouchMode(true);
+                mContentView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+                    @Override
+                    public void onFocusChange(View v, boolean hasFocus) {
+                        fail("Unnecessary focus change");
+                    }
+                });
+            }
+        });
+
+        onView(withId(R.id.drawer_layout)).perform(openDrawer(GravityCompat.START));
+        assertTrue("Opened drawer", mDrawerLayout.isDrawerOpen(GravityCompat.START));
+
+        onView(withId(R.id.drawer_layout)).perform(closeDrawer(GravityCompat.START));
+        assertFalse("Closed drawer", mDrawerLayout.isDrawerOpen(GravityCompat.START));
+    }
+
+    @Test
+    @MediumTest
     public void testDrawerOpenCloseWithRedundancyViaAPI() {
         assertFalse("Initial state", mDrawerLayout.isDrawerOpen(GravityCompat.START));
 
diff --git a/v7/appcompat/tests/src/android/support/v7/app/NightModeActivity.java b/v7/appcompat/tests/src/android/support/v7/app/NightModeActivity.java
index a2d038b..a52d26b 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/NightModeActivity.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/NightModeActivity.java
@@ -20,8 +20,31 @@
 import android.support.v7.testutils.BaseTestActivity;
 
 public class NightModeActivity extends BaseTestActivity {
+
+    /**
+     * Warning, gross hack here. Since night mode uses recreate(), we need a way to be able to
+     * grab the top activity. The test runner only keeps reference to the original Activity which
+     * is no good for these tests. Fixed by keeping a static reference to the 'top' instance, and
+     * updating it in onResume and onPause. I said it was gross.
+     */
+    static NightModeActivity TOP_ACTIVITY = null;
+
     @Override
     protected int getContentViewLayoutResId() {
         return R.layout.activity_night_mode;
     }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        TOP_ACTIVITY = this;
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        if (TOP_ACTIVITY == this) {
+            TOP_ACTIVITY = null;
+        }
+    }
 }
diff --git a/v7/appcompat/tests/src/android/support/v7/app/NightModeTestCase.java b/v7/appcompat/tests/src/android/support/v7/app/NightModeTestCase.java
index 6ea0077..a3d91d2 100644
--- a/v7/appcompat/tests/src/android/support/v7/app/NightModeTestCase.java
+++ b/v7/appcompat/tests/src/android/support/v7/app/NightModeTestCase.java
@@ -20,12 +20,12 @@
 import static android.support.test.espresso.assertion.ViewAssertions.matches;
 import static android.support.test.espresso.matcher.ViewMatchers.withId;
 import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static android.support.v7.app.NightModeActivity.TOP_ACTIVITY;
+import static android.support.v7.testutils.TestUtils.setLocalNightModeAndWaitForRecreate;
+import static android.support.v7.testutils.TestUtilsMatchers.isBackground;
 
 import static org.junit.Assert.assertFalse;
 
-import android.app.Instrumentation;
-import android.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SdkSuppress;
 import android.support.v7.appcompat.test.R;
 import android.test.suitebuilder.annotation.MediumTest;
@@ -53,26 +53,39 @@
 
     @Test
     public void testLocalDayNightModeRecreatesActivity() {
-        final NightModeActivity activity = getActivity();
-
         // Verify first that we're in day mode
         onView(withId(R.id.text_night_mode)).check(matches(withText(STRING_DAY)));
 
         // Now force the local night mode to be yes (aka night mode)
-        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        instrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                activity.getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES);
-            }
-        });
-        instrumentation.waitForIdleSync();
+        setLocalNightModeAndWaitForRecreate(getActivity(), AppCompatDelegate.MODE_NIGHT_YES);
 
         // Now check the text has changed, signifying that night resources are being used
         onView(withId(R.id.text_night_mode)).check(matches(withText(STRING_NIGHT)));
     }
 
     @Test
+    public void testColorConvertedDrawableChangesWithNightMode() {
+        final NightModeActivity activity = getActivity();
+        final int dayColor = activity.getResources().getColor(R.color.color_sky_day);
+        final int nightColor = activity.getResources().getColor(R.color.color_sky_night);
+
+        // Loop through and switching from day to night and vice-versa multiple times. It needs
+        // to be looped since the issue is with drawable caching, therefore we need to prime the
+        // cache for the issue to happen
+        for (int i = 0; i < 5; i++) {
+            // First force it to not be night mode
+            setLocalNightModeAndWaitForRecreate(TOP_ACTIVITY, AppCompatDelegate.MODE_NIGHT_NO);
+            // ... and verify first that we're in day mode
+            onView(withId(R.id.view_background)).check(matches(isBackground(dayColor)));
+
+            // Now force the local night mode to be yes (aka night mode)
+            setLocalNightModeAndWaitForRecreate(TOP_ACTIVITY, AppCompatDelegate.MODE_NIGHT_YES);
+            // ... and verify first that we're in night mode
+            onView(withId(R.id.view_background)).check(matches(isBackground(nightColor)));
+        }
+    }
+
+    @Test
     public void testNightModeAutoRecreatesOnTimeChange() {
         // Create a fake TwilightManager and set it as the app instance
         final FakeTwilightManager twilightManager = new FakeTwilightManager();
@@ -85,21 +98,13 @@
         onView(withId(R.id.text_night_mode)).check(matches(withText(STRING_DAY)));
 
         // Now set MODE_NIGHT_AUTO so that we will change to night mode automatically
-        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        instrumentation.runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                // Force the local night mode to be auto
-                delegate.setLocalNightMode(AppCompatDelegate.MODE_NIGHT_AUTO);
-            }
-        });
-        instrumentation.waitForIdleSync();
+        setLocalNightModeAndWaitForRecreate(activity, AppCompatDelegate.MODE_NIGHT_AUTO);
 
         // Assert that the original Activity has not been destroyed yet
         assertFalse(activity.isDestroyed());
 
         // Now update the fake twilight manager to be in night and trigger a fake 'time' change
-        instrumentation.runOnMainSync(new Runnable() {
+        getInstrumentation().runOnMainSync(new Runnable() {
             @Override
             public void run() {
                 twilightManager.setIsNight(true);
diff --git a/v7/appcompat/tests/src/android/support/v7/testutils/TestUtils.java b/v7/appcompat/tests/src/android/support/v7/testutils/TestUtils.java
index b904127..37a3732 100644
--- a/v7/appcompat/tests/src/android/support/v7/testutils/TestUtils.java
+++ b/v7/appcompat/tests/src/android/support/v7/testutils/TestUtils.java
@@ -16,6 +16,7 @@
 
 package android.support.v7.testutils;
 
+import android.app.Instrumentation;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
@@ -24,10 +25,14 @@
 import android.os.SystemClock;
 import android.support.annotation.ColorInt;
 import android.support.annotation.NonNull;
+import android.support.test.InstrumentationRegistry;
 import android.support.v4.util.Pair;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.app.AppCompatDelegate;
 import android.support.v7.widget.TintTypedArray;
 import android.view.View;
 import android.view.ViewParent;
+
 import junit.framework.Assert;
 
 import java.util.ArrayList;
@@ -249,4 +254,16 @@
             a.recycle();
         }
     }
+
+    public static void setLocalNightModeAndWaitForRecreate(final AppCompatActivity activity,
+            @AppCompatDelegate.NightMode final int nightMode) {
+        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
+        instrumentation.runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                activity.getDelegate().setLocalNightMode(nightMode);
+            }
+        });
+        instrumentation.waitForIdleSync();
+    }
 }
\ No newline at end of file
diff --git a/v7/cardview/src/android/support/v7/widget/CardView.java b/v7/cardview/src/android/support/v7/widget/CardView.java
index 3da3243..3b47a54 100644
--- a/v7/cardview/src/android/support/v7/widget/CardView.java
+++ b/v7/cardview/src/android/support/v7/widget/CardView.java
@@ -100,11 +100,11 @@
      * CardView works around this issue by recording user given parameters and using an internal
      * method to set them.
      */
-    private int mUserSetMinWidth, mUserSetMinHeight;
+    int mUserSetMinWidth, mUserSetMinHeight;
 
-    private final Rect mContentPadding = new Rect();
+    final Rect mContentPadding = new Rect();
 
-    private final Rect mShadowBounds = new Rect();
+    final Rect mShadowBounds = new Rect();
 
     public CardView(Context context) {
         super(context);
diff --git a/v7/gridlayout/src/android/support/v7/widget/GridLayout.java b/v7/gridlayout/src/android/support/v7/widget/GridLayout.java
index bcc66f4..9aa7871 100644
--- a/v7/gridlayout/src/android/support/v7/widget/GridLayout.java
+++ b/v7/gridlayout/src/android/support/v7/widget/GridLayout.java
@@ -231,7 +231,7 @@
     private static final int DEFAULT_ORIENTATION = HORIZONTAL;
     private static final int DEFAULT_COUNT = UNDEFINED;
     private static final boolean DEFAULT_USE_DEFAULT_MARGINS = false;
-    private static final boolean DEFAULT_ORDER_PRESERVED = true;
+    static final boolean DEFAULT_ORDER_PRESERVED = true;
     private static final int DEFAULT_ALIGNMENT_MODE = ALIGN_MARGINS;
 
     // TypedArray indices
@@ -798,7 +798,7 @@
         return (LayoutParams) c.getLayoutParams();
     }
 
-    private static void handleInvalidParams(String msg) {
+    static void handleInvalidParams(String msg) {
         throw new IllegalArgumentException(msg + ". ");
     }
 
@@ -1090,9 +1090,9 @@
      for the vertical one.
      */
     final class Axis {
-        private static final int NEW = 0;
-        private static final int PENDING = 1;
-        private static final int COMPLETE = 2;
+        static final int NEW = 0;
+        static final int PENDING = 1;
+        static final int COMPLETE = 2;
 
         public final boolean horizontal;
 
@@ -1129,7 +1129,7 @@
         private MutableInt parentMin = new MutableInt(0);
         private MutableInt parentMax = new MutableInt(-MAX_SIZE);
 
-        private Axis(boolean horizontal) {
+        Axis(boolean horizontal) {
             this.horizontal = horizontal;
         }
 
@@ -2195,7 +2195,7 @@
         public final K[] keys;
         public final V[] values;
 
-        private PackedMap(K[] keys, V[] values) {
+        PackedMap(K[] keys, V[] values) {
             this.index = createIndex(keys);
 
             this.keys = compact(keys, index);
@@ -2255,7 +2255,7 @@
         public int after;
         public int flexibility; // we're flexible iff all included specs are flexible
 
-        private Bounds() {
+        Bounds() {
             reset();
         }
 
@@ -2433,7 +2433,7 @@
             this.weight = weight;
         }
 
-        private Spec(boolean startDefined, int start, int size, Alignment alignment, float weight) {
+        Spec(boolean startDefined, int start, int size, Alignment alignment, float weight) {
             this(startDefined, new Interval(start, start + size), alignment, weight);
         }
 
@@ -2916,6 +2916,6 @@
         return (flexibility & CAN_STRETCH) != 0;
     }
 
-    private static final int INFLEXIBLE = 0;
-    private static final int CAN_STRETCH = 2;
+    static final int INFLEXIBLE = 0;
+    static final int CAN_STRETCH = 2;
 }
diff --git a/v7/gridlayout/tests/src/android/support/v7/widget/GridLayoutTest.java b/v7/gridlayout/tests/src/android/support/v7/widget/GridLayoutTest.java
index b343ca33c..b82fea0 100644
--- a/v7/gridlayout/tests/src/android/support/v7/widget/GridLayoutTest.java
+++ b/v7/gridlayout/tests/src/android/support/v7/widget/GridLayoutTest.java
@@ -40,9 +40,9 @@
 public class GridLayoutTest {
     @Rule public final ActivityTestRule<GridLayoutTestActivity> mActivityTestRule;
 
-    private View mLeftView;
-    private View mRightView;
-    private View mGridView;
+    View mLeftView;
+    View mRightView;
+    View mGridView;
 
     public GridLayoutTest() {
         mActivityTestRule = new ActivityTestRule<>(GridLayoutTestActivity.class);
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteActionProvider.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteActionProvider.java
index 79fad1f..ad8fc1b 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteActionProvider.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteActionProvider.java
@@ -279,7 +279,7 @@
                 MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE);
     }
 
-    private void refreshRoute() {
+    void refreshRoute() {
         refreshVisibility();
     }
 
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
index c45121e..20e83aa 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteButton.java
@@ -485,7 +485,7 @@
         }
     }
 
-    private void refreshRoute() {
+    void refreshRoute() {
         if (mAttachedToWindow) {
             final MediaRouter.RouteInfo route = mRouter.getSelectedRoute();
             final boolean isRemote = !route.isDefaultOrBluetooth()
@@ -529,6 +529,9 @@
     }
 
     private final class MediaRouterCallback extends MediaRouter.Callback {
+        MediaRouterCallback() {
+        }
+
         @Override
         public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
             refreshRoute();
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteChooserDialog.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteChooserDialog.java
index f492a9a..01cb1fd 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteChooserDialog.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteChooserDialog.java
@@ -61,11 +61,11 @@
  * @see MediaRouteActionProvider
  */
 public class MediaRouteChooserDialog extends Dialog {
-    private static final String TAG = "MediaRouteChooserDialog";
+    static final String TAG = "MediaRouteChooserDialog";
 
     // Do not update the route list immediately to avoid unnatural dialog change.
     private static final long UPDATE_ROUTES_DELAY_MS = 300L;
-    private static final int MSG_UPDATE_ROUTES = 1;
+    static final int MSG_UPDATE_ROUTES = 1;
 
     private final MediaRouter mRouter;
     private final MediaRouterCallback mCallback;
@@ -226,7 +226,7 @@
         }
     }
 
-    private void updateRoutes(List<MediaRouter.RouteInfo> routes) {
+    void updateRoutes(List<MediaRouter.RouteInfo> routes) {
         mLastUpdateTime = SystemClock.uptimeMillis();
         mRoutes.clear();
         mRoutes.addAll(routes);
@@ -344,6 +344,9 @@
     }
 
     private final class MediaRouterCallback extends MediaRouter.Callback {
+        MediaRouterCallback() {
+        }
+
         @Override
         public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
             refreshRoutes();
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
index 4699b25..ee3d26f 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteControllerDialog.java
@@ -92,24 +92,24 @@
  */
 public class MediaRouteControllerDialog extends AlertDialog {
     // Tags should be less than 24 characters long (see docs for android.util.Log.isLoggable())
-    private static final String TAG = "MediaRouteCtrlDialog";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final String TAG = "MediaRouteCtrlDialog";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     // Time to wait before updating the volume when the user lets go of the seek bar
     // to allow the route provider time to propagate the change and publish a new
     // route descriptor.
-    private static final int VOLUME_UPDATE_DELAY_MILLIS = 500;
-    private static final int CONNECTION_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(30L);
+    static final int VOLUME_UPDATE_DELAY_MILLIS = 500;
+    static final int CONNECTION_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(30L);
 
     private static final int BUTTON_NEUTRAL_RES_ID = android.R.id.button3;
-    private static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2;
-    private static final int BUTTON_STOP_RES_ID = android.R.id.button1;
+    static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2;
+    static final int BUTTON_STOP_RES_ID = android.R.id.button1;
 
-    private final MediaRouter mRouter;
+    final MediaRouter mRouter;
     private final MediaRouterCallback mCallback;
-    private final MediaRouter.RouteInfo mRoute;
+    final MediaRouter.RouteInfo mRoute;
 
-    private Context mContext;
+    Context mContext;
     private boolean mCreated;
     private boolean mAttachedToWindow;
 
@@ -125,7 +125,7 @@
 
     private FrameLayout mExpandableAreaLayout;
     private LinearLayout mDialogAreaLayout;
-    private FrameLayout mDefaultControlLayout;
+    FrameLayout mDefaultControlLayout;
     private FrameLayout mCustomControlLayout;
     private ImageView mArtView;
     private TextView mTitleView;
@@ -139,40 +139,40 @@
     private LinearLayout mVolumeControlLayout;
     private View mDividerView;
 
-    private OverlayListView mVolumeGroupList;
-    private VolumeGroupAdapter mVolumeGroupAdapter;
+    OverlayListView mVolumeGroupList;
+    VolumeGroupAdapter mVolumeGroupAdapter;
     private List<MediaRouter.RouteInfo> mGroupMemberRoutes;
-    private Set<MediaRouter.RouteInfo> mGroupMemberRoutesAdded;
+    Set<MediaRouter.RouteInfo> mGroupMemberRoutesAdded;
     private Set<MediaRouter.RouteInfo> mGroupMemberRoutesRemoved;
-    private Set<MediaRouter.RouteInfo> mGroupMemberRoutesAnimatingWithBitmap;
-    private SeekBar mVolumeSlider;
-    private VolumeChangeListener mVolumeChangeListener;
-    private MediaRouter.RouteInfo mRouteInVolumeSliderTouched;
+    Set<MediaRouter.RouteInfo> mGroupMemberRoutesAnimatingWithBitmap;
+    SeekBar mVolumeSlider;
+    VolumeChangeListener mVolumeChangeListener;
+    MediaRouter.RouteInfo mRouteInVolumeSliderTouched;
     private int mVolumeGroupListItemIconSize;
     private int mVolumeGroupListItemHeight;
     private int mVolumeGroupListMaxHeight;
     private final int mVolumeGroupListPaddingTop;
-    private Map<MediaRouter.RouteInfo, SeekBar> mVolumeSliderMap;
+    Map<MediaRouter.RouteInfo, SeekBar> mVolumeSliderMap;
 
-    private MediaControllerCompat mMediaController;
-    private MediaControllerCallback mControllerCallback;
-    private PlaybackStateCompat mState;
-    private MediaDescriptionCompat mDescription;
+    MediaControllerCompat mMediaController;
+    MediaControllerCallback mControllerCallback;
+    PlaybackStateCompat mState;
+    MediaDescriptionCompat mDescription;
 
-    private FetchArtTask mFetchArtTask;
-    private Bitmap mArtIconBitmap;
-    private Uri mArtIconUri;
-    private boolean mArtIconIsLoaded;
-    private Bitmap mArtIconLoadedBitmap;
-    private int mArtIconBackgroundColor;
+    FetchArtTask mFetchArtTask;
+    Bitmap mArtIconBitmap;
+    Uri mArtIconUri;
+    boolean mArtIconIsLoaded;
+    Bitmap mArtIconLoadedBitmap;
+    int mArtIconBackgroundColor;
 
-    private boolean mHasPendingUpdate;
-    private boolean mPendingUpdateAnimationNeeded;
+    boolean mHasPendingUpdate;
+    boolean mPendingUpdateAnimationNeeded;
 
-    private boolean mIsGroupExpanded;
-    private boolean mIsGroupListAnimating;
-    private boolean mIsGroupListAnimationPending;
-    private int mGroupListAnimationDurationMs;
+    boolean mIsGroupExpanded;
+    boolean mIsGroupListAnimating;
+    boolean mIsGroupListAnimationPending;
+    int mGroupListAnimationDurationMs;
     private int mGroupListFadeInDurationMs;
     private int mGroupListFadeOutDurationMs;
 
@@ -181,9 +181,9 @@
     private Interpolator mFastOutSlowInInterpolator;
     private Interpolator mAccelerateDecelerateInterpolator;
 
-    private final AccessibilityManager mAccessibilityManager;
+    final AccessibilityManager mAccessibilityManager;
 
-    private Runnable mGroupListFadeInAnimation = new Runnable() {
+    Runnable mGroupListFadeInAnimation = new Runnable() {
         @Override
         public void run() {
             startGroupListFadeInAnimation();
@@ -503,7 +503,7 @@
         return super.onKeyUp(keyCode, event);
     }
 
-    private void update(boolean animate) {
+    void update(boolean animate) {
         // Defer dialog updates if a user is adjusting a volume in the list
         if (mRouteInVolumeSliderTouched != null) {
             mHasPendingUpdate = true;
@@ -567,7 +567,7 @@
                 && !canShowPlaybackControlLayout) ? View.GONE : View.VISIBLE);
     }
 
-    private void updateLayoutHeight(final boolean animate) {
+    void updateLayoutHeight(final boolean animate) {
         // We need to defer the update until the first layout has occurred, as we don't yet know the
         // overall visible display size in which the window this view is attached to has been
         // positioned in.
@@ -589,7 +589,7 @@
     /**
      * Updates the height of views and hide artwork or metadata if space is limited.
      */
-    private void updateLayoutHeightInternal(boolean animate) {
+    void updateLayoutHeightInternal(boolean animate) {
         // Measure the size of widgets and get the height of main components.
         int oldHeight = getLayoutHeight(mMediaMainControlLayout);
         setLayoutHeight(mMediaMainControlLayout, ViewGroup.LayoutParams.MATCH_PARENT);
@@ -680,7 +680,7 @@
         rebuildVolumeGroupList(animate);
     }
 
-    private void updateVolumeGroupItemHeight(View item) {
+    void updateVolumeGroupItemHeight(View item) {
         LinearLayout container = (LinearLayout) item.findViewById(R.id.volume_item_container);
         setLayoutHeight(container, mVolumeGroupListItemHeight);
         View icon = item.findViewById(R.id.mr_volume_item_icon);
@@ -707,7 +707,7 @@
         view.startAnimation(anim);
     }
 
-    private void loadInterpolator() {
+    void loadInterpolator() {
         if (android.os.Build.VERSION.SDK_INT >= 21) {
             mInterpolator = mIsGroupExpanded ? mLinearOutSlowInInterpolator
                     : mFastOutSlowInInterpolator;
@@ -776,7 +776,7 @@
         });
     }
 
-    private void animateGroupListItemsInternal(
+    void animateGroupListItemsInternal(
             Map<MediaRouter.RouteInfo, Rect> previousRouteBoundMap,
             Map<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap) {
         if (mGroupMemberRoutesAdded == null || mGroupMemberRoutesRemoved == null) {
@@ -864,7 +864,7 @@
         }
     }
 
-    private void startGroupListFadeInAnimation() {
+    void startGroupListFadeInAnimation() {
         clearGroupListAnimation(true);
         mVolumeGroupList.requestLayout();
         ViewTreeObserver observer = mVolumeGroupList.getViewTreeObserver();
@@ -877,7 +877,7 @@
         });
     }
 
-    private void startGroupListFadeInAnimationInternal() {
+    void startGroupListFadeInAnimationInternal() {
         if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.size() != 0) {
             fadeInAddedRoutes();
         } else {
@@ -885,7 +885,7 @@
         }
     }
 
-    private void finishAnimation(boolean animate) {
+    void finishAnimation(boolean animate) {
         mGroupMemberRoutesAdded = null;
         mGroupMemberRoutesRemoved = null;
         mIsGroupListAnimating = false;
@@ -1020,7 +1020,7 @@
         }
     }
 
-    private boolean isVolumeControlAvailable(MediaRouter.RouteInfo route) {
+    boolean isVolumeControlAvailable(MediaRouter.RouteInfo route) {
         return mVolumeControlEnabled && route.getVolumeHandling()
                 == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
     }
@@ -1029,7 +1029,7 @@
         return view.getLayoutParams().height;
     }
 
-    private static void setLayoutHeight(View view, int height) {
+    static void setLayoutHeight(View view, int height) {
         ViewGroup.LayoutParams lp = view.getLayoutParams();
         lp.height = height;
         view.setLayoutParams(lp);
@@ -1047,7 +1047,7 @@
     /**
      * Returns desired art height to fit into controller dialog.
      */
-    private int getDesiredArtHeight(int originalWidth, int originalHeight) {
+    int getDesiredArtHeight(int originalWidth, int originalHeight) {
         if (originalWidth >= originalHeight) {
             // For landscape art, fit width to dialog width.
             return (int) ((float) mDialogContentWidth * originalHeight / originalWidth + 0.5f);
@@ -1056,7 +1056,7 @@
         return (int) ((float) mDialogContentWidth * 9 / 16 + 0.5f);
     }
 
-    private void updateArtIconIfNeeded() {
+    void updateArtIconIfNeeded() {
         if (mCustomControlView != null || !isIconChanged()) {
             return;
         }
@@ -1071,7 +1071,7 @@
      * Clear the bitmap loaded by FetchArtTask. Will be called after the loaded bitmaps are applied
      * to artwork, or no longer valid.
      */
-    private void clearLoadedBitmap() {
+    void clearLoadedBitmap() {
         mArtIconIsLoaded = false;
         mArtIconLoadedBitmap = null;
         mArtIconBackgroundColor = 0;
@@ -1096,6 +1096,9 @@
     }
 
     private final class MediaRouterCallback extends MediaRouter.Callback {
+        MediaRouterCallback() {
+        }
+
         @Override
         public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) {
             update(false);
@@ -1120,6 +1123,9 @@
     }
 
     private final class MediaControllerCallback extends MediaControllerCompat.Callback {
+        MediaControllerCallback() {
+        }
+
         @Override
         public void onSessionDestroyed() {
             if (mMediaController != null) {
@@ -1143,6 +1149,9 @@
     }
 
     private final class ClickListener implements View.OnClickListener {
+        ClickListener() {
+        }
+
         @Override
         public void onClick(View v) {
             int id = v.getId();
@@ -1192,6 +1201,9 @@
             }
         };
 
+        VolumeChangeListener() {
+        }
+
         @Override
         public void onStartTrackingTouch(SeekBar seekBar) {
             if (mRouteInVolumeSliderTouched != null) {
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouteExpandCollapseButton.java b/v7/mediarouter/src/android/support/v7/app/MediaRouteExpandCollapseButton.java
index 4c81a43..df0c944 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouteExpandCollapseButton.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouteExpandCollapseButton.java
@@ -31,12 +31,12 @@
  * Chevron/Caret button to expand/collapse group volume list with animation.
  */
 class MediaRouteExpandCollapseButton extends ImageButton {
-    private final AnimationDrawable mExpandAnimationDrawable;
-    private final AnimationDrawable mCollapseAnimationDrawable;
-    private final String mExpandGroupDescription;
-    private final String mCollapseGroupDescription;
-    private boolean mIsGroupExpanded;
-    private OnClickListener mListener;
+    final AnimationDrawable mExpandAnimationDrawable;
+    final AnimationDrawable mCollapseAnimationDrawable;
+    final String mExpandGroupDescription;
+    final String mCollapseGroupDescription;
+    boolean mIsGroupExpanded;
+    OnClickListener mListener;
 
     public MediaRouteExpandCollapseButton(Context context) {
         this(context, null);
diff --git a/v7/mediarouter/src/android/support/v7/app/MediaRouterThemeHelper.java b/v7/mediarouter/src/android/support/v7/app/MediaRouterThemeHelper.java
index e129dd7..60c878f 100644
--- a/v7/mediarouter/src/android/support/v7/app/MediaRouterThemeHelper.java
+++ b/v7/mediarouter/src/android/support/v7/app/MediaRouterThemeHelper.java
@@ -36,8 +36,8 @@
     @Retention(RetentionPolicy.SOURCE)
     private @interface ControllerColorType {}
 
-    private static final int COLOR_DARK_ON_LIGHT_BACKGROUND = 0xDE000000; /* Opacity of 87% */
-    private static final int COLOR_WHITE_ON_DARK_BACKGROUND = Color.WHITE;
+    static final int COLOR_DARK_ON_LIGHT_BACKGROUND = 0xDE000000; /* Opacity of 87% */
+    static final int COLOR_WHITE_ON_DARK_BACKGROUND = Color.WHITE;
 
     private MediaRouterThemeHelper() {
     }
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaItemStatus.java b/v7/mediarouter/src/android/support/v7/media/MediaItemStatus.java
index dd9ab85..c3d1c5e 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaItemStatus.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaItemStatus.java
@@ -58,13 +58,13 @@
  * </p>
  */
 public final class MediaItemStatus {
-    private static final String KEY_TIMESTAMP = "timestamp";
-    private static final String KEY_PLAYBACK_STATE = "playbackState";
-    private static final String KEY_CONTENT_POSITION = "contentPosition";
-    private static final String KEY_CONTENT_DURATION = "contentDuration";
-    private static final String KEY_EXTRAS = "extras";
+    static final String KEY_TIMESTAMP = "timestamp";
+    static final String KEY_PLAYBACK_STATE = "playbackState";
+    static final String KEY_CONTENT_POSITION = "contentPosition";
+    static final String KEY_CONTENT_DURATION = "contentDuration";
+    static final String KEY_EXTRAS = "extras";
 
-    private final Bundle mBundle;
+    final Bundle mBundle;
 
     /**
      * Playback state: Pending.
@@ -195,7 +195,7 @@
     public static final String EXTRA_HTTP_RESPONSE_HEADERS =
             "android.media.status.extra.HTTP_RESPONSE_HEADERS";
 
-    private MediaItemStatus(Bundle bundle) {
+    MediaItemStatus(Bundle bundle) {
         mBundle = bundle;
     }
 
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteDescriptor.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteDescriptor.java
index 93034e6..068db47 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteDescriptor.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteDescriptor.java
@@ -19,6 +19,7 @@
 import android.content.IntentSender;
 import android.net.Uri;
 import android.os.Bundle;
+import android.support.annotation.RestrictTo;
 import android.text.TextUtils;
 
 import java.util.ArrayList;
@@ -27,6 +28,8 @@
 import java.util.Collections;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Describes the properties of a route.
  * <p>
@@ -37,32 +40,32 @@
  * </p>
  */
 public final class MediaRouteDescriptor {
-    private static final String KEY_ID = "id";
-    private static final String KEY_GROUP_MEMBER_IDS = "groupMemberIds";
-    private static final String KEY_NAME = "name";
-    private static final String KEY_DESCRIPTION = "status";
-    private static final String KEY_ICON_URI = "iconUri";
-    private static final String KEY_ENABLED = "enabled";
-    private static final String KEY_CONNECTING = "connecting";
-    private static final String KEY_CONNECTION_STATE = "connectionState";
-    private static final String KEY_CONTROL_FILTERS = "controlFilters";
-    private static final String KEY_PLAYBACK_TYPE = "playbackType";
-    private static final String KEY_PLAYBACK_STREAM = "playbackStream";
-    private static final String KEY_DEVICE_TYPE = "deviceType";
-    private static final String KEY_VOLUME = "volume";
-    private static final String KEY_VOLUME_MAX = "volumeMax";
-    private static final String KEY_VOLUME_HANDLING = "volumeHandling";
-    private static final String KEY_PRESENTATION_DISPLAY_ID = "presentationDisplayId";
-    private static final String KEY_EXTRAS = "extras";
-    private static final String KEY_CAN_DISCONNECT = "canDisconnect";
-    private static final String KEY_SETTINGS_INTENT = "settingsIntent";
-    private static final String KEY_MIN_CLIENT_VERSION = "minClientVersion";
-    private static final String KEY_MAX_CLIENT_VERSION = "maxClientVersion";
+    static final String KEY_ID = "id";
+    static final String KEY_GROUP_MEMBER_IDS = "groupMemberIds";
+    static final String KEY_NAME = "name";
+    static final String KEY_DESCRIPTION = "status";
+    static final String KEY_ICON_URI = "iconUri";
+    static final String KEY_ENABLED = "enabled";
+    static final String KEY_CONNECTING = "connecting";
+    static final String KEY_CONNECTION_STATE = "connectionState";
+    static final String KEY_CONTROL_FILTERS = "controlFilters";
+    static final String KEY_PLAYBACK_TYPE = "playbackType";
+    static final String KEY_PLAYBACK_STREAM = "playbackStream";
+    static final String KEY_DEVICE_TYPE = "deviceType";
+    static final String KEY_VOLUME = "volume";
+    static final String KEY_VOLUME_MAX = "volumeMax";
+    static final String KEY_VOLUME_HANDLING = "volumeHandling";
+    static final String KEY_PRESENTATION_DISPLAY_ID = "presentationDisplayId";
+    static final String KEY_EXTRAS = "extras";
+    static final String KEY_CAN_DISCONNECT = "canDisconnect";
+    static final String KEY_SETTINGS_INTENT = "settingsIntent";
+    static final String KEY_MIN_CLIENT_VERSION = "minClientVersion";
+    static final String KEY_MAX_CLIENT_VERSION = "maxClientVersion";
 
-    private final Bundle mBundle;
-    private List<IntentFilter> mControlFilters;
+    final Bundle mBundle;
+    List<IntentFilter> mControlFilters;
 
-    private MediaRouteDescriptor(Bundle bundle, List<IntentFilter> controlFilters) {
+    MediaRouteDescriptor(Bundle bundle, List<IntentFilter> controlFilters) {
         mBundle = bundle;
         mControlFilters = controlFilters;
     }
@@ -87,6 +90,7 @@
      * </p>
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public List<String> getGroupMemberIds() {
         return mBundle.getStringArrayList(KEY_GROUP_MEMBER_IDS);
     }
@@ -189,7 +193,7 @@
         return mControlFilters;
     }
 
-    private void ensureControlFilters() {
+    void ensureControlFilters() {
         if (mControlFilters == null) {
             mControlFilters = mBundle.<IntentFilter>getParcelableArrayList(KEY_CONTROL_FILTERS);
             if (mControlFilters == null) {
@@ -274,6 +278,7 @@
      * Gets the minimum client version required for this route.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public int getMinClientVersion() {
         return mBundle.getInt(KEY_MIN_CLIENT_VERSION,
                 MediaRouteProviderProtocol.CLIENT_VERSION_START);
@@ -283,6 +288,7 @@
      * Gets the maximum client version required for this route.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public int getMaxClientVersion() {
         return mBundle.getInt(KEY_MAX_CLIENT_VERSION, Integer.MAX_VALUE);
     }
@@ -405,6 +411,7 @@
          * </p>
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public Builder addGroupMemberId(String groupMemberId) {
             if (TextUtils.isEmpty(groupMemberId)) {
                 throw new IllegalArgumentException("groupMemberId must not be empty");
@@ -427,6 +434,7 @@
          * </p>
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public Builder addGroupMemberIds(Collection<String> groupMemberIds) {
             if (groupMemberIds == null) {
                 throw new IllegalArgumentException("groupMemberIds must not be null");
@@ -655,6 +663,7 @@
          * A router whose version is lower than this will not be able to connect to this route.
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public Builder setMinClientVersion(int minVersion) {
             mBundle.putInt(KEY_MIN_CLIENT_VERSION, minVersion);
             return this;
@@ -665,6 +674,7 @@
          * A router whose version is higher than this will not be able to connect to this route.
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public Builder setMaxClientVersion(int maxVersion) {
             mBundle.putInt(KEY_MAX_CLIENT_VERSION, maxVersion);
             return this;
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
index a9c3ed2..e514782 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
@@ -23,8 +23,11 @@
 import android.os.Message;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v7.media.MediaRouter.ControlRequestCallback;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Media route providers are used to publish additional media routes for
  * use within an application.  Media route providers may also be declared
@@ -55,8 +58,8 @@
  * </p>
  */
 public abstract class MediaRouteProvider {
-    private static final int MSG_DELIVER_DESCRIPTOR_CHANGED = 1;
-    private static final int MSG_DELIVER_DISCOVERY_REQUEST_CHANGED = 2;
+    static final int MSG_DELIVER_DESCRIPTOR_CHANGED = 1;
+    static final int MSG_DELIVER_DISCOVERY_REQUEST_CHANGED = 2;
 
     private final Context mContext;
     private final ProviderMetadata mMetadata;
@@ -159,7 +162,7 @@
         }
     }
 
-    private void deliverDiscoveryRequestChanged() {
+    void deliverDiscoveryRequestChanged() {
         mPendingDiscoveryRequestChange = false;
         onDiscoveryRequestChanged(mDiscoveryRequest);
     }
@@ -230,7 +233,7 @@
         }
     }
 
-    private void deliverDescriptorChanged() {
+    void deliverDescriptorChanged() {
         mPendingDescriptorChange = false;
 
         if (mCallback != null) {
@@ -271,6 +274,7 @@
      * cannot be controlled using the route controller interface.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Nullable
     public RouteController onCreateRouteController(@NonNull String routeId,
             @NonNull String routeGroupId) {
@@ -427,6 +431,9 @@
     }
 
     private final class ProviderHandler extends Handler {
+        ProviderHandler() {
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderDescriptor.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderDescriptor.java
index a8909cb..ec2f7ba 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderDescriptor.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderDescriptor.java
@@ -33,10 +33,10 @@
 public final class MediaRouteProviderDescriptor {
     static final String KEY_ROUTES = "routes";
 
-    private final Bundle mBundle;
-    private List<MediaRouteDescriptor> mRoutes;
+    final Bundle mBundle;
+    List<MediaRouteDescriptor> mRoutes;
 
-    private MediaRouteProviderDescriptor(Bundle bundle,
+    MediaRouteProviderDescriptor(Bundle bundle,
             List<MediaRouteDescriptor> routes) {
         mBundle = bundle;
         mRoutes = routes;
@@ -50,7 +50,7 @@
         return mRoutes;
     }
 
-    private void ensureRoutes() {
+    void ensureRoutes() {
         if (mRoutes == null) {
             ArrayList<Bundle> routeBundles = mBundle.<Bundle>getParcelableArrayList(KEY_ROUTES);
             if (routeBundles == null || routeBundles.isEmpty()) {
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderProtocol.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderProtocol.java
index b312179..4bc03a8 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderProtocol.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderProtocol.java
@@ -21,7 +21,6 @@
 
 /**
  * Defines the communication protocol for media route provider services.
- * @hide
  */
 abstract class MediaRouteProviderProtocol {
     /**
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderService.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderService.java
index ba40692..dc49e81 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderService.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderService.java
@@ -62,16 +62,16 @@
  * </pre>
  */
 public abstract class MediaRouteProviderService extends Service {
-    private static final String TAG = "MediaRouteProviderSrv"; // max. 23 chars
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final String TAG = "MediaRouteProviderSrv"; // max. 23 chars
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final ArrayList<ClientRecord> mClients = new ArrayList<ClientRecord>();
     private final ReceiveHandler mReceiveHandler;
     private final Messenger mReceiveMessenger;
-    private final PrivateHandler mPrivateHandler;
+    final PrivateHandler mPrivateHandler;
     private final ProviderCallback mProviderCallback;
 
-    private MediaRouteProvider mProvider;
+    MediaRouteProvider mProvider;
     private MediaRouteDiscoveryRequest mCompositeDiscoveryRequest;
 
     /**
@@ -84,7 +84,7 @@
      * Private messages used internally.  (Yes, you can renumber these.)
      */
 
-    private static final int PRIVATE_MSG_CLIENT_DIED = 1;
+    static final int PRIVATE_MSG_CLIENT_DIED = 1;
 
     /**
      * Creates a media route provider service.
@@ -150,7 +150,7 @@
         return super.onUnbind(intent);
     }
 
-    private boolean onRegisterClient(Messenger messenger, int requestId, int version) {
+    boolean onRegisterClient(Messenger messenger, int requestId, int version) {
         if (version >= CLIENT_VERSION_1) {
             int index = findClient(messenger);
             if (index < 0) {
@@ -173,7 +173,7 @@
         return false;
     }
 
-    private boolean onUnregisterClient(Messenger messenger, int requestId) {
+    boolean onUnregisterClient(Messenger messenger, int requestId) {
         int index = findClient(messenger);
         if (index >= 0) {
             ClientRecord client = mClients.remove(index);
@@ -187,7 +187,7 @@
         return false;
     }
 
-    private void onBinderDied(Messenger messenger) {
+    void onBinderDied(Messenger messenger) {
         int index = findClient(messenger);
         if (index >= 0) {
             ClientRecord client = mClients.remove(index);
@@ -198,7 +198,7 @@
         }
     }
 
-    private boolean onCreateRouteController(Messenger messenger, int requestId,
+    boolean onCreateRouteController(Messenger messenger, int requestId,
             int controllerId, String routeId, String routeGroupId) {
         ClientRecord client = getClient(messenger);
         if (client != null) {
@@ -214,7 +214,7 @@
         return false;
     }
 
-    private boolean onReleaseRouteController(Messenger messenger, int requestId,
+    boolean onReleaseRouteController(Messenger messenger, int requestId,
             int controllerId) {
         ClientRecord client = getClient(messenger);
         if (client != null) {
@@ -230,7 +230,7 @@
         return false;
     }
 
-    private boolean onSelectRoute(Messenger messenger, int requestId,
+    boolean onSelectRoute(Messenger messenger, int requestId,
             int controllerId) {
         ClientRecord client = getClient(messenger);
         if (client != null) {
@@ -249,7 +249,7 @@
         return false;
     }
 
-    private boolean onUnselectRoute(Messenger messenger, int requestId,
+    boolean onUnselectRoute(Messenger messenger, int requestId,
             int controllerId, int reason) {
         ClientRecord client = getClient(messenger);
         if (client != null) {
@@ -268,7 +268,7 @@
         return false;
     }
 
-    private boolean onSetRouteVolume(Messenger messenger, int requestId,
+    boolean onSetRouteVolume(Messenger messenger, int requestId,
             int controllerId, int volume) {
         ClientRecord client = getClient(messenger);
         if (client != null) {
@@ -287,7 +287,7 @@
         return false;
     }
 
-    private boolean onUpdateRouteVolume(Messenger messenger, int requestId,
+    boolean onUpdateRouteVolume(Messenger messenger, int requestId,
             int controllerId, int delta) {
         ClientRecord client = getClient(messenger);
         if (client != null) {
@@ -306,7 +306,7 @@
         return false;
     }
 
-    private boolean onRouteControlRequest(final Messenger messenger, final int requestId,
+    boolean onRouteControlRequest(final Messenger messenger, final int requestId,
             final int controllerId, final Intent intent) {
         final ClientRecord client = getClient(messenger);
         if (client != null) {
@@ -364,7 +364,7 @@
         return false;
     }
 
-    private boolean onSetDiscoveryRequest(Messenger messenger, int requestId,
+    boolean onSetDiscoveryRequest(Messenger messenger, int requestId,
             MediaRouteDiscoveryRequest request) {
         ClientRecord client = getClient(messenger);
         if (client != null) {
@@ -380,7 +380,7 @@
         return false;
     }
 
-    private void sendDescriptorChanged(MediaRouteProviderDescriptor descriptor) {
+    void sendDescriptorChanged(MediaRouteProviderDescriptor descriptor) {
         final int count = mClients.size();
         for (int i = 0; i < count; i++) {
             ClientRecord client = mClients.get(i);
@@ -413,7 +413,7 @@
                 .addRoutes(routes).build().asBundle();
     }
 
-    private boolean updateCompositeDiscoveryRequest() {
+    boolean updateCompositeDiscoveryRequest() {
         MediaRouteDiscoveryRequest composite = null;
         MediaRouteSelector.Builder selectorBuilder = null;
         boolean activeScan = false;
@@ -451,7 +451,7 @@
         return index >= 0 ? mClients.get(index) : null;
     }
 
-    private int findClient(Messenger messenger) {
+    int findClient(Messenger messenger) {
         final int count = mClients.size();
         for (int i = 0; i < count; i++) {
             ClientRecord client = mClients.get(i);
@@ -462,7 +462,7 @@
         return -1;
     }
 
-    private static void sendGenericFailure(Messenger messenger, int requestId) {
+    static void sendGenericFailure(Messenger messenger, int requestId) {
         if (requestId != 0) {
             sendReply(messenger, SERVICE_MSG_GENERIC_FAILURE, requestId, 0, null, null);
         }
@@ -474,7 +474,7 @@
         }
     }
 
-    private static void sendReply(Messenger messenger, int what,
+    static void sendReply(Messenger messenger, int what,
             int requestId, int arg, Object obj, Bundle data) {
         Message msg = Message.obtain();
         msg.what = what;
@@ -491,11 +491,14 @@
         }
     }
 
-    private static String getClientId(Messenger messenger) {
+    static String getClientId(Messenger messenger) {
         return "Client connection " + messenger.getBinder().toString();
     }
 
     private final class PrivateHandler extends Handler {
+        PrivateHandler() {
+        }
+
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -507,6 +510,9 @@
     }
 
     private final class ProviderCallback extends MediaRouteProvider.Callback {
+        ProviderCallback() {
+        }
+
         @Override
         public void onDescriptorChanged(MediaRouteProvider provider,
                 MediaRouteProviderDescriptor descriptor) {
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteSelector.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteSelector.java
index 4323d69..65406da 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteSelector.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteSelector.java
@@ -44,17 +44,17 @@
  * </pre>
  */
 public final class MediaRouteSelector {
-    private static final String KEY_CONTROL_CATEGORIES = "controlCategories";
+    static final String KEY_CONTROL_CATEGORIES = "controlCategories";
 
     private final Bundle mBundle;
-    private List<String> mControlCategories;
+    List<String> mControlCategories;
 
     /**
      * An empty media route selector that will not match any routes.
      */
     public static final MediaRouteSelector EMPTY = new MediaRouteSelector(new Bundle(), null);
 
-    private MediaRouteSelector(Bundle bundle, List<String> controlCategories) {
+    MediaRouteSelector(Bundle bundle, List<String> controlCategories) {
         mBundle = bundle;
         mControlCategories = controlCategories;
     }
@@ -69,7 +69,7 @@
         return mControlCategories;
     }
 
-    private void ensureControlCategories() {
+    void ensureControlCategories() {
         if (mControlCategories == null) {
             mControlCategories = mBundle.getStringArrayList(KEY_CONTROL_CATEGORIES);
             if (mControlCategories == null || mControlCategories.isEmpty()) {
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
index b8d86ad..95c6ac2 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
@@ -33,6 +33,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.ActivityManagerCompat;
 import android.support.v4.hardware.display.DisplayManagerCompat;
 import android.support.v4.media.VolumeProviderCompat;
@@ -57,6 +58,8 @@
 import java.util.Map;
 import java.util.Set;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * MediaRouter allows applications to control the routing of media channels
  * and streams from the current device to external speakers and destination devices.
@@ -76,8 +79,8 @@
  * </p>
  */
 public final class MediaRouter {
-    private static final String TAG = "MediaRouter";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final String TAG = "MediaRouter";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     /**
      * Passed to {@link android.support.v7.media.MediaRouteProvider.RouteController#onUnselect(int)}
@@ -117,7 +120,6 @@
     final Context mContext;
     final ArrayList<CallbackRecord> mCallbackRecords = new ArrayList<CallbackRecord>();
 
-    /** @hide */
     @IntDef(flag = true,
             value = {
                     CALLBACK_FLAG_PERFORM_ACTIVE_SCAN,
@@ -805,7 +807,6 @@
         private IntentSender mSettingsIntent;
         MediaRouteDescriptor mDescriptor;
 
-        /** @hide */
         @IntDef({CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING,
                 CONNECTION_STATE_CONNECTED})
         @Retention(RetentionPolicy.SOURCE)
@@ -833,7 +834,6 @@
          */
         public static final int CONNECTION_STATE_CONNECTED = 2;
 
-        /** @hide */
         @IntDef({PLAYBACK_TYPE_LOCAL,PLAYBACK_TYPE_REMOTE})
         @Retention(RetentionPolicy.SOURCE)
         private @interface PlaybackType {}
@@ -855,7 +855,6 @@
          */
         public static final int PLAYBACK_TYPE_REMOTE = 1;
 
-        /** @hide */
         @IntDef({DEVICE_TYPE_UNKNOWN, DEVICE_TYPE_TV, DEVICE_TYPE_SPEAKER, DEVICE_TYPE_BLUETOOTH})
         @Retention(RetentionPolicy.SOURCE)
         private @interface DeviceType {}
@@ -866,6 +865,7 @@
          * @see #getDeviceType
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public static final int DEVICE_TYPE_UNKNOWN = 0;
 
         /**
@@ -891,9 +891,9 @@
          * @see #getDeviceType
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public static final int DEVICE_TYPE_BLUETOOTH = 3;
 
-        /** @hide */
         @IntDef({PLAYBACK_VOLUME_FIXED,PLAYBACK_VOLUME_VARIABLE})
         @Retention(RetentionPolicy.SOURCE)
         private @interface PlaybackVolume {}
@@ -921,6 +921,7 @@
          * with the route.
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public static final int PRESENTATION_DISPLAY_ID_NONE = -1;
 
         static final int CHANGE_GENERAL = 1 << 0;
@@ -1247,6 +1248,7 @@
         /**
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public boolean isDefaultOrBluetooth() {
             if (isDefault() || mDeviceType == DEVICE_TYPE_BLUETOOTH) {
                 return true;
@@ -1377,6 +1379,7 @@
          * Gets the route's presentation display id, or -1 if none.
          * @hide
          */
+        @RestrictTo(GROUP_ID)
         public int getPresentationDisplayId() {
             return mPresentationDisplayId;
         }
@@ -1521,6 +1524,7 @@
         }
 
         /** @hide */
+        @RestrictTo(GROUP_ID)
         public MediaRouteProvider getProviderInstance() {
             return mProvider.getProviderInstance();
         }
@@ -1530,6 +1534,7 @@
      * Information about a route that consists of multiple other routes in a group.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class RouteGroup extends RouteInfo {
         private List<RouteInfo> mRoutes = new ArrayList<>();
 
@@ -1882,31 +1887,31 @@
     private static final class GlobalMediaRouter
             implements SystemMediaRouteProvider.SyncCallback,
             RegisteredMediaRouteProviderWatcher.Callback {
-        private final Context mApplicationContext;
-        private final ArrayList<WeakReference<MediaRouter>> mRouters = new ArrayList<>();
+        final Context mApplicationContext;
+        final ArrayList<WeakReference<MediaRouter>> mRouters = new ArrayList<>();
         private final ArrayList<RouteInfo> mRoutes = new ArrayList<>();
         private final Map<Pair<String, String>, String> mUniqueIdMap = new HashMap<>();
         private final ArrayList<ProviderInfo> mProviders = new ArrayList<>();
         private final ArrayList<RemoteControlClientRecord> mRemoteControlClients =
                 new ArrayList<>();
-        private final RemoteControlClientCompat.PlaybackInfo mPlaybackInfo =
+        final RemoteControlClientCompat.PlaybackInfo mPlaybackInfo =
                 new RemoteControlClientCompat.PlaybackInfo();
         private final ProviderCallback mProviderCallback = new ProviderCallback();
-        private final CallbackHandler mCallbackHandler = new CallbackHandler();
+        final CallbackHandler mCallbackHandler = new CallbackHandler();
         private final DisplayManagerCompat mDisplayManager;
-        private final SystemMediaRouteProvider mSystemProvider;
+        final SystemMediaRouteProvider mSystemProvider;
         private final boolean mLowRam;
 
         private RegisteredMediaRouteProviderWatcher mRegisteredProviderWatcher;
         private RouteInfo mDefaultRoute;
-        private RouteInfo mSelectedRoute;
+        RouteInfo mSelectedRoute;
         private RouteController mSelectedRouteController;
         // A map from route descriptor ID to RouteController for the member routes in the currently
         // selected route group.
         private final Map<String, RouteController> mRouteControllerMap = new HashMap<>();
         private MediaRouteDiscoveryRequest mDiscoveryRequest;
         private MediaSessionRecord mMediaSession;
-        private MediaSessionCompat mRccMediaSession;
+        MediaSessionCompat mRccMediaSession;
         private MediaSessionCompat mCompatSession;
         private MediaSessionCompat.OnActiveChangeListener mSessionActiveListener =
                 new MediaSessionCompat.OnActiveChangeListener() {
@@ -2195,7 +2200,7 @@
             }
         }
 
-        private void updateProviderDescriptor(MediaRouteProvider providerInstance,
+        void updateProviderDescriptor(MediaRouteProvider providerInstance,
                 MediaRouteProviderDescriptor descriptor) {
             int index = findProviderInfo(providerInstance);
             if (index >= 0) {
@@ -2669,6 +2674,9 @@
         }
 
         private final class ProviderCallback extends MediaRouteProvider.Callback {
+            ProviderCallback() {
+            }
+
             @Override
             public void onDescriptorChanged(MediaRouteProvider provider,
                     MediaRouteProviderDescriptor descriptor) {
@@ -2794,6 +2802,9 @@
             public static final int MSG_PROVIDER_REMOVED = MSG_TYPE_PROVIDER | 2;
             public static final int MSG_PROVIDER_CHANGED = MSG_TYPE_PROVIDER | 3;
 
+            CallbackHandler() {
+            }
+
             public void post(int msg, Object obj) {
                 obtainMessage(msg, obj).sendToTarget();
             }
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaSessionStatus.java b/v7/mediarouter/src/android/support/v7/media/MediaSessionStatus.java
index 5c6deb5..511fc55 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaSessionStatus.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaSessionStatus.java
@@ -43,12 +43,12 @@
  * </p>
  */
 public final class MediaSessionStatus {
-    private static final String KEY_TIMESTAMP = "timestamp";
-    private static final String KEY_SESSION_STATE = "sessionState";
-    private static final String KEY_QUEUE_PAUSED = "queuePaused";
-    private static final String KEY_EXTRAS = "extras";
+    static final String KEY_TIMESTAMP = "timestamp";
+    static final String KEY_SESSION_STATE = "sessionState";
+    static final String KEY_QUEUE_PAUSED = "queuePaused";
+    static final String KEY_EXTRAS = "extras";
 
-    private final Bundle mBundle;
+    final Bundle mBundle;
 
     /**
      * Session state: Active.
@@ -82,7 +82,7 @@
      */
     public static final int SESSION_STATE_INVALIDATED = 2;
 
-    private MediaSessionStatus(Bundle bundle) {
+    MediaSessionStatus(Bundle bundle) {
         mBundle = bundle;
     }
 
diff --git a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
index 547ff79..7942eed 100644
--- a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
@@ -44,11 +44,11 @@
  */
 final class RegisteredMediaRouteProvider extends MediaRouteProvider
         implements ServiceConnection {
-    private static final String TAG = "MediaRouteProviderProxy";  // max. 23 chars
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final String TAG = "MediaRouteProviderProxy";  // max. 23 chars
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final ComponentName mComponentName;
-    private final PrivateHandler mPrivateHandler;
+    final PrivateHandler mPrivateHandler;
     private final ArrayList<Controller> mControllers = new ArrayList<Controller>();
 
     private boolean mStarted;
@@ -241,7 +241,7 @@
         return null;
     }
 
-    private void onConnectionReady(Connection connection) {
+    void onConnectionReady(Connection connection) {
         if (mActiveConnection == connection) {
             mConnectionReady = true;
             attachControllersToConnection();
@@ -253,7 +253,7 @@
         }
     }
 
-    private void onConnectionDied(Connection connection) {
+    void onConnectionDied(Connection connection) {
         if (mActiveConnection == connection) {
             if (DEBUG) {
                 Log.d(TAG, this + ": Service connection died");
@@ -262,7 +262,7 @@
         }
     }
 
-    private void onConnectionError(Connection connection, String error) {
+    void onConnectionError(Connection connection, String error) {
         if (mActiveConnection == connection) {
             if (DEBUG) {
                 Log.d(TAG, this + ": Service connection error - " + error);
@@ -271,7 +271,7 @@
         }
     }
 
-    private void onConnectionDescriptorChanged(Connection connection,
+    void onConnectionDescriptorChanged(Connection connection,
             MediaRouteProviderDescriptor descriptor) {
         if (mActiveConnection == connection) {
             if (DEBUG) {
@@ -291,7 +291,7 @@
         }
     }
 
-    private void onControllerReleased(Controller controller) {
+    void onControllerReleased(Controller controller) {
         mControllers.remove(controller);
         controller.detachConnection();
         updateBinding();
@@ -454,7 +454,7 @@
             });
         }
 
-        private void failPendingCallbacks() {
+        void failPendingCallbacks() {
             int count = 0;
             for (int i = 0; i < mPendingCallbacks.size(); i++) {
                 mPendingCallbacks.valueAt(i).onError(null, null);
@@ -615,6 +615,8 @@
     }
 
     private final class PrivateHandler extends Handler {
+        PrivateHandler() {
+        }
     }
 
     /**
diff --git a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProviderWatcher.java b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProviderWatcher.java
index 2fb01d2..e763597 100644
--- a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProviderWatcher.java
+++ b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProviderWatcher.java
@@ -85,7 +85,7 @@
         }
     }
 
-    private void scanPackages() {
+    void scanPackages() {
         if (!mRunning) {
             return;
         }
diff --git a/v7/mediarouter/src/android/support/v7/media/RemotePlaybackClient.java b/v7/mediarouter/src/android/support/v7/media/RemotePlaybackClient.java
index 1716af3..1dc556b 100644
--- a/v7/mediarouter/src/android/support/v7/media/RemotePlaybackClient.java
+++ b/v7/mediarouter/src/android/support/v7/media/RemotePlaybackClient.java
@@ -35,8 +35,8 @@
  * </p>
  */
 public class RemotePlaybackClient {
-    private static final String TAG = "RemotePlaybackClient";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    static final String TAG = "RemotePlaybackClient";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     private final Context mContext;
     private final MediaRouter.RouteInfo mRoute;
@@ -50,9 +50,9 @@
     private boolean mRouteSupportsSessionManagement;
     private boolean mRouteSupportsMessaging;
 
-    private String mSessionId;
-    private StatusCallback mStatusCallback;
-    private OnMessageReceivedListener mOnMessageReceivedListener;
+    String mSessionId;
+    StatusCallback mStatusCallback;
+    OnMessageReceivedListener mOnMessageReceivedListener;
 
     /**
      * Creates a remote playback client for a route.
@@ -748,20 +748,20 @@
         });
     }
 
-    private void adoptSession(String sessionId) {
+    void adoptSession(String sessionId) {
         if (sessionId != null) {
             setSessionId(sessionId);
         }
     }
 
-    private void handleInvalidResult(Intent intent, ActionCallback callback,
+    void handleInvalidResult(Intent intent, ActionCallback callback,
             Bundle data) {
         Log.w(TAG, "Received invalid result data from " + intent.getAction()
                 + ": data=" + bundleToString(data));
         callback.onError(null, MediaControlIntent.ERROR_UNKNOWN, data);
     }
 
-    private void handleError(Intent intent, ActionCallback callback,
+    void handleError(Intent intent, ActionCallback callback,
             String error, Bundle data) {
         final int code;
         if (data != null) {
@@ -840,7 +840,7 @@
         }
     }
 
-    private static String inferMissingResult(String request, String result) {
+    static String inferMissingResult(String request, String result) {
         if (result == null) {
             // Result is missing.
             return request;
@@ -859,7 +859,7 @@
         }
     }
 
-    private static String bundleToString(Bundle bundle) {
+    static String bundleToString(Bundle bundle) {
         if (bundle != null) {
             bundle.size(); // force bundle to be unparcelled
             return bundle.toString();
@@ -875,6 +875,9 @@
         public static final String ACTION_MESSAGE_RECEIVED =
                 "android.support.v7.media.actions.ACTION_MESSAGE_RECEIVED";
 
+        ActionReceiver() {
+        }
+
         @Override
         public void onReceive(Context context, Intent intent) {
             String sessionId = intent.getStringExtra(MediaControlIntent.EXTRA_SESSION_ID);
diff --git a/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
index 21ff5b4..6a2451b 100644
--- a/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/SystemMediaRouteProvider.java
@@ -103,7 +103,7 @@
      * Legacy implementation for platform versions prior to Jellybean.
      */
     static class LegacyImpl extends SystemMediaRouteProvider {
-        private static final int PLAYBACK_STREAM = AudioManager.STREAM_MUSIC;
+        static final int PLAYBACK_STREAM = AudioManager.STREAM_MUSIC;
 
         private static final ArrayList<IntentFilter> CONTROL_FILTERS;
         static {
@@ -115,9 +115,9 @@
             CONTROL_FILTERS.add(f);
         }
 
-        private final AudioManager mAudioManager;
+        final AudioManager mAudioManager;
         private final VolumeChangeReceiver mVolumeChangeReceiver;
-        private int mLastReportedVolume = -1;
+        int mLastReportedVolume = -1;
 
         public LegacyImpl(Context context) {
             super(context);
@@ -129,7 +129,7 @@
             publishRoutes();
         }
 
-        private void publishRoutes() {
+        void publishRoutes() {
             Resources r = getContext().getResources();
             int maxVolume = mAudioManager.getStreamMaxVolume(PLAYBACK_STREAM);
             mLastReportedVolume = mAudioManager.getStreamVolume(PLAYBACK_STREAM);
diff --git a/v7/palette/src/main/java/android/support/v7/graphics/ColorCutQuantizer.java b/v7/palette/src/main/java/android/support/v7/graphics/ColorCutQuantizer.java
index 1516261..9c7747c 100644
--- a/v7/palette/src/main/java/android/support/v7/graphics/ColorCutQuantizer.java
+++ b/v7/palette/src/main/java/android/support/v7/graphics/ColorCutQuantizer.java
@@ -46,9 +46,9 @@
     private static final String LOG_TAG = "ColorCutQuantizer";
     private static final boolean LOG_TIMINGS = false;
 
-    private static final int COMPONENT_RED = -3;
-    private static final int COMPONENT_GREEN = -2;
-    private static final int COMPONENT_BLUE = -1;
+    static final int COMPONENT_RED = -3;
+    static final int COMPONENT_GREEN = -2;
+    static final int COMPONENT_BLUE = -1;
 
     private static final int QUANTIZE_WORD_WIDTH = 5;
     private static final int QUANTIZE_WORD_MASK = (1 << QUANTIZE_WORD_WIDTH) - 1;
@@ -398,7 +398,7 @@
      *
      * @see Vbox#findSplitPoint()
      */
-    private static void modifySignificantOctet(final int[] a, final int dimension,
+    static void modifySignificantOctet(final int[] a, final int dimension,
             final int lower, final int upper) {
         switch (dimension) {
             case COMPONENT_RED:
@@ -469,7 +469,7 @@
     /**
      * Quantized RGB888 values to have a word width of {@value #QUANTIZE_WORD_WIDTH}.
      */
-    private static int approximateToRgb888(int r, int g, int b) {
+    static int approximateToRgb888(int r, int g, int b) {
         return Color.rgb(modifyWordWidth(r, QUANTIZE_WORD_WIDTH, 8),
                 modifyWordWidth(g, QUANTIZE_WORD_WIDTH, 8),
                 modifyWordWidth(b, QUANTIZE_WORD_WIDTH, 8));
@@ -482,21 +482,21 @@
     /**
      * @return red component of the quantized color
      */
-    private static int quantizedRed(int color) {
+    static int quantizedRed(int color) {
         return (color >> (QUANTIZE_WORD_WIDTH + QUANTIZE_WORD_WIDTH)) & QUANTIZE_WORD_MASK;
     }
 
     /**
      * @return green component of a quantized color
      */
-    private static int quantizedGreen(int color) {
+    static int quantizedGreen(int color) {
         return (color >> QUANTIZE_WORD_WIDTH) & QUANTIZE_WORD_MASK;
     }
 
     /**
      * @return blue component of a quantized color
      */
-    private static int quantizedBlue(int color) {
+    static int quantizedBlue(int color) {
         return color & QUANTIZE_WORD_MASK;
     }
 
diff --git a/v7/palette/src/main/java/android/support/v7/graphics/Palette.java b/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
index 6d0368d..93570de 100644
--- a/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
+++ b/v7/palette/src/main/java/android/support/v7/graphics/Palette.java
@@ -84,14 +84,14 @@
         void onGenerated(Palette palette);
     }
 
-    private static final int DEFAULT_RESIZE_BITMAP_AREA = 160 * 160;
-    private static final int DEFAULT_CALCULATE_NUMBER_COLORS = 16;
+    static final int DEFAULT_RESIZE_BITMAP_AREA = 160 * 160;
+    static final int DEFAULT_CALCULATE_NUMBER_COLORS = 16;
 
-    private static final float MIN_CONTRAST_TITLE_TEXT = 3.0f;
-    private static final float MIN_CONTRAST_BODY_TEXT = 4.5f;
+    static final float MIN_CONTRAST_TITLE_TEXT = 3.0f;
+    static final float MIN_CONTRAST_BODY_TEXT = 4.5f;
 
-    private static final String LOG_TAG = "Palette";
-    private static final boolean LOG_TIMINGS = false;
+    static final String LOG_TAG = "Palette";
+    static final boolean LOG_TIMINGS = false;
 
     /**
      * Start generating a {@link Palette} with the returned {@link Builder} instance.
@@ -151,7 +151,7 @@
 
     private final Swatch mDominantSwatch;
 
-    private Palette(List<Swatch> swatches, List<Target> targets) {
+    Palette(List<Swatch> swatches, List<Target> targets) {
         mSwatches = swatches;
         mTargets = targets;
 
@@ -345,7 +345,7 @@
         return mDominantSwatch != null ? mDominantSwatch.getRgb() : defaultColor;
     }
 
-    private void generate() {
+    void generate() {
         // We need to make sure that the scored targets are generated first. This is so that
         // inherited targets have something to inherit from
         for (int i = 0, count = mTargets.size(); i < count; i++) {
@@ -951,7 +951,7 @@
     /**
      * The default filter.
      */
-    private static final Filter DEFAULT_FILTER = new Filter() {
+    static final Filter DEFAULT_FILTER = new Filter() {
         private static final float BLACK_MAX_LIGHTNESS = 0.05f;
         private static final float WHITE_MIN_LIGHTNESS = 0.95f;
 
diff --git a/v7/palette/src/main/java/android/support/v7/graphics/Target.java b/v7/palette/src/main/java/android/support/v7/graphics/Target.java
index d1e0742..640970b 100644
--- a/v7/palette/src/main/java/android/support/v7/graphics/Target.java
+++ b/v7/palette/src/main/java/android/support/v7/graphics/Target.java
@@ -47,13 +47,13 @@
     private static final float WEIGHT_LUMA = 0.52f;
     private static final float WEIGHT_POPULATION = 0.24f;
 
-    private static final int INDEX_MIN = 0;
-    private static final int INDEX_TARGET = 1;
-    private static final int INDEX_MAX = 2;
+    static final int INDEX_MIN = 0;
+    static final int INDEX_TARGET = 1;
+    static final int INDEX_MAX = 2;
 
-    private static final int INDEX_WEIGHT_SAT = 0;
-    private static final int INDEX_WEIGHT_LUMA = 1;
-    private static final int INDEX_WEIGHT_POP = 2;
+    static final int INDEX_WEIGHT_SAT = 0;
+    static final int INDEX_WEIGHT_LUMA = 1;
+    static final int INDEX_WEIGHT_POP = 2;
 
     /**
      * A target which has the characteristics of a vibrant color which is light in luminance.
@@ -111,18 +111,18 @@
         setDefaultMutedSaturationValues(DARK_MUTED);
     }
 
-    private final float[] mSaturationTargets = new float[3];
-    private final float[] mLightnessTargets = new float[3];
-    private final float[] mWeights = new float[3];
-    private boolean mIsExclusive = true; // default to true
+    final float[] mSaturationTargets = new float[3];
+    final float[] mLightnessTargets = new float[3];
+    final float[] mWeights = new float[3];
+    boolean mIsExclusive = true; // default to true
 
-    private Target() {
+    Target() {
         setTargetDefaultValues(mSaturationTargets);
         setTargetDefaultValues(mLightnessTargets);
         setDefaultWeights();
     }
 
-    private Target(Target from) {
+    Target(Target from) {
         System.arraycopy(from.mSaturationTargets, 0, mSaturationTargets, 0,
                 mSaturationTargets.length);
         System.arraycopy(from.mLightnessTargets, 0, mLightnessTargets, 0,
diff --git a/v7/preference/Android.mk b/v7/preference/Android.mk
index 6bfd7e8..ca4fe02 100644
--- a/v7/preference/Android.mk
+++ b/v7/preference/Android.mk
@@ -24,7 +24,9 @@
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 LOCAL_SHARED_ANDROID_LIBRARIES := \
     android-support-v7-appcompat \
-    android-support-v7-recyclerview
+    android-support-v7-recyclerview \
+    android-support-v4 \
+    android-support-annotations
 LOCAL_JAR_EXCLUDE_FILES := none
 LOCAL_JAVA_LANGUAGE_VERSION := 1.7
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/v7/preference/constants/android/support/v7/preference/AndroidResources.java b/v7/preference/constants/android/support/v7/preference/AndroidResources.java
index 611e7c8..aeddb15 100644
--- a/v7/preference/constants/android/support/v7/preference/AndroidResources.java
+++ b/v7/preference/constants/android/support/v7/preference/AndroidResources.java
@@ -16,9 +16,14 @@
 
 package android.support.v7.preference;
 
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class AndroidResources {
 
     public static final int ANDROID_R_ICON_FRAME = android.R.id.icon_frame;
diff --git a/v7/preference/src/android/support/v7/internal/package-info.java b/v7/preference/src/android/support/v7/internal/package-info.java
new file mode 100644
index 0000000..c146ca5
--- /dev/null
+++ b/v7/preference/src/android/support/v7/internal/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * @hide
+ */
+@RestrictTo(GROUP_ID)
+package android.support.v7.internal;
+
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
\ No newline at end of file
diff --git a/v7/preference/src/android/support/v7/internal/widget/PreferenceImageView.java b/v7/preference/src/android/support/v7/internal/widget/PreferenceImageView.java
index e3d430d..a02872f 100644
--- a/v7/preference/src/android/support/v7/internal/widget/PreferenceImageView.java
+++ b/v7/preference/src/android/support/v7/internal/widget/PreferenceImageView.java
@@ -18,14 +18,18 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.support.annotation.RestrictTo;
 import android.support.v7.preference.R;
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Extension of ImageView that correctly applies maxWidth and maxHeight.
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class PreferenceImageView extends ImageView {
 
     private int mMaxWidth = Integer.MAX_VALUE;
diff --git a/v7/preference/src/android/support/v7/preference/CheckBoxPreference.java b/v7/preference/src/android/support/v7/preference/CheckBoxPreference.java
index fa4463b..72143a4 100644
--- a/v7/preference/src/android/support/v7/preference/CheckBoxPreference.java
+++ b/v7/preference/src/android/support/v7/preference/CheckBoxPreference.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.TypedArrayUtils;
 import android.util.AttributeSet;
 import android.view.View;
@@ -25,6 +26,8 @@
 import android.widget.Checkable;
 import android.widget.CompoundButton;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A {@link Preference} that provides checkbox widget
  * functionality.
@@ -96,6 +99,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     protected void performClick(View view) {
         super.performClick(view);
diff --git a/v7/preference/src/android/support/v7/preference/DropDownPreference.java b/v7/preference/src/android/support/v7/preference/DropDownPreference.java
index 3d6ac38..ec6339e 100644
--- a/v7/preference/src/android/support/v7/preference/DropDownPreference.java
+++ b/v7/preference/src/android/support/v7/preference/DropDownPreference.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.AdapterView;
@@ -25,6 +26,8 @@
 import android.widget.ArrayAdapter;
 import android.widget.Spinner;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A version of {@link ListPreference} that presents the options in a
  * drop down menu rather than a dialog.
@@ -99,6 +102,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public int findSpinnerIndexOfValue(String value) {
         CharSequence[] entryValues = getEntryValues();
         if (value != null && entryValues != null) {
diff --git a/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java
index 2abafe7..cb18ba9 100644
--- a/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java
+++ b/v7/preference/src/android/support/v7/preference/EditTextPreferenceDialogFragmentCompat.java
@@ -18,9 +18,12 @@
 
 import android.os.Bundle;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.view.View;
 import android.widget.EditText;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 public class EditTextPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
 
     private static final String SAVE_STATE_TEXT = "EditTextPreferenceDialogFragment.text";
@@ -73,6 +76,7 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     @Override
     protected boolean needInputMethod() {
         // We want the input method to show, if possible, when dialog is displayed
diff --git a/v7/preference/src/android/support/v7/preference/Preference.java b/v7/preference/src/android/support/v7/preference/Preference.java
index 2534b44..f12fcbd 100644
--- a/v7/preference/src/android/support/v7/preference/Preference.java
+++ b/v7/preference/src/android/support/v7/preference/Preference.java
@@ -26,6 +26,7 @@
 import android.os.Parcelable;
 import android.support.annotation.CallSuper;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.content.SharedPreferencesCompat;
 import android.support.v4.content.res.TypedArrayUtils;
@@ -41,6 +42,8 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Represents the basic Preference UI building
  * block displayed by a {@link PreferenceFragmentCompat} in the form of a
@@ -953,6 +956,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void performClick(View view) {
         performClick();
     }
@@ -962,6 +966,7 @@
      *
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public void performClick() {
 
         if (!isEnabled()) {
@@ -1102,6 +1107,7 @@
      * Called from {@link PreferenceGroup} to pass in an ID for reuse
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void onAttachedToHierarchy(PreferenceManager preferenceManager, long id) {
         mId = id;
         mHasId = true;
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java b/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java
index 9b6fd5a..3989385 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceDialogFragmentCompat.java
@@ -26,6 +26,7 @@
 import android.os.Bundle;
 import android.support.annotation.LayoutRes;
 import android.support.annotation.NonNull;
+import android.support.annotation.RestrictTo;
 import android.support.v4.app.DialogFragment;
 import android.support.v4.app.Fragment;
 import android.support.v7.app.AlertDialog;
@@ -36,6 +37,8 @@
 import android.view.WindowManager;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Abstract base class which presents a dialog associated with a
  * {@link android.support.v7.preference.DialogPreference}. Since the preference object may
@@ -191,6 +194,7 @@
      * the soft input method brought up automatically.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected boolean needInputMethod() {
         return false;
     }
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java b/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
index 527138b..751d9f7 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceFragmentCompat.java
@@ -25,6 +25,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.XmlRes;
 import android.support.v4.app.DialogFragment;
 import android.support.v4.app.Fragment;
@@ -38,6 +39,8 @@
 import android.view.View;
 import android.view.ViewGroup;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Shows a hierarchy of {@link Preference} objects as
  * lists. These preferences will
@@ -542,10 +545,12 @@
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     protected void onBindPreferences() {
     }
 
     /** @hide */
+    @RestrictTo(GROUP_ID)
     protected void onUnbindPreferences() {
     }
 
@@ -647,6 +652,7 @@
      * @return Fragment to possibly use as a callback
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public Fragment getCallbackFragment() {
         return null;
     }
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceGroup.java b/v7/preference/src/android/support/v7/preference/PreferenceGroup.java
index 4768e01..0fc77ce 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceGroup.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceGroup.java
@@ -20,6 +20,7 @@
 import android.content.res.TypedArray;
 import android.os.Bundle;
 import android.os.Handler;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.TypedArrayUtils;
 import android.support.v4.util.SimpleArrayMap;
 import android.text.TextUtils;
@@ -29,6 +30,8 @@
 import java.util.Collections;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * A container for multiple
  * {@link Preference} objects. It is a base class for  Preference objects that are
@@ -319,6 +322,7 @@
      * Returns true if we're between {@link #onAttached()} and {@link #onPrepareForRemoval()}
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public boolean isAttached() {
         return mAttachedToHierarchy;
     }
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceGroupAdapter.java b/v7/preference/src/android/support/v7/preference/PreferenceGroupAdapter.java
index 4762548..27d2a13 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceGroupAdapter.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceGroupAdapter.java
@@ -19,6 +19,7 @@
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.support.v7.widget.RecyclerView;
 import android.text.TextUtils;
@@ -29,12 +30,15 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * An adapter that connects a RecyclerView to the {@link Preference} objects contained in the
  * associated {@link PreferenceGroup}.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class PreferenceGroupAdapter extends RecyclerView.Adapter<PreferenceViewHolder>
         implements Preference.OnPreferenceChangeInternalListener,
         PreferenceGroup.PreferencePositionCallback {
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceManager.java b/v7/preference/src/android/support/v7/preference/PreferenceManager.java
index c99dde2..34adf6d 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceManager.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceManager.java
@@ -18,10 +18,13 @@
 
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.ContextCompat;
 import android.support.v4.content.SharedPreferencesCompat;
 import android.support.v4.os.BuildCompat;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Used to help create {@link Preference} hierarchies
  * from activities or XML.
@@ -95,6 +98,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public PreferenceManager(Context context) {
         mContext = context;
 
@@ -113,6 +117,7 @@
      *         root).
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public PreferenceScreen inflateFromResource(Context context, int resId,
             PreferenceScreen rootPreferences) {
         // Block commits
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceRecyclerViewAccessibilityDelegate.java b/v7/preference/src/android/support/v7/preference/PreferenceRecyclerViewAccessibilityDelegate.java
index 032fbf9..d2a2454 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceRecyclerViewAccessibilityDelegate.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceRecyclerViewAccessibilityDelegate.java
@@ -17,6 +17,7 @@
 package android.support.v7.preference;
 
 import android.os.Bundle;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.AccessibilityDelegateCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v7.widget.RecyclerView;
@@ -24,11 +25,14 @@
 import android.view.View;
 import android.view.accessibility.AccessibilityEvent;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * The AccessibilityDelegate used by the RecyclerView that displays Views for Preferences.
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public class PreferenceRecyclerViewAccessibilityDelegate
         extends RecyclerViewAccessibilityDelegate {
     final RecyclerView mRecyclerView;
diff --git a/v7/preference/src/android/support/v7/preference/PreferenceScreen.java b/v7/preference/src/android/support/v7/preference/PreferenceScreen.java
index cbabf21..8434354 100644
--- a/v7/preference/src/android/support/v7/preference/PreferenceScreen.java
+++ b/v7/preference/src/android/support/v7/preference/PreferenceScreen.java
@@ -17,9 +17,12 @@
 package android.support.v7.preference;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.TypedArrayUtils;
 import android.util.AttributeSet;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Represents a top-level {@link Preference} that
  * is the root of a Preference hierarchy. A {@link PreferenceFragmentCompat}
@@ -79,8 +82,9 @@
 
     /**
      * Do NOT use this constructor, use {@link PreferenceManager#createPreferenceScreen(Context)}.
-     * @hide-
+     * @hide
      */
+    @RestrictTo(GROUP_ID)
     public PreferenceScreen(Context context, AttributeSet attrs) {
         super(context, attrs, TypedArrayUtils.getAttr(context, R.attr.preferenceScreenStyle,
                 android.R.attr.preferenceScreenStyle));
diff --git a/v7/preference/src/android/support/v7/preference/SwitchPreferenceCompat.java b/v7/preference/src/android/support/v7/preference/SwitchPreferenceCompat.java
index ce41a25..1784f9f 100644
--- a/v7/preference/src/android/support/v7/preference/SwitchPreferenceCompat.java
+++ b/v7/preference/src/android/support/v7/preference/SwitchPreferenceCompat.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.support.annotation.RestrictTo;
 import android.support.v4.content.res.TypedArrayUtils;
 import android.support.v7.widget.SwitchCompat;
 import android.util.AttributeSet;
@@ -26,6 +27,8 @@
 import android.widget.Checkable;
 import android.widget.CompoundButton;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
 * A {@link Preference} that provides a two-state toggleable option.
 * <p>
@@ -198,6 +201,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     @Override
     protected void performClick(View view) {
         super.performClick(view);
diff --git a/v7/preference/src/android/support/v7/preference/TwoStatePreference.java b/v7/preference/src/android/support/v7/preference/TwoStatePreference.java
index 53965f1..19071f5 100644
--- a/v7/preference/src/android/support/v7/preference/TwoStatePreference.java
+++ b/v7/preference/src/android/support/v7/preference/TwoStatePreference.java
@@ -20,11 +20,14 @@
 import android.content.res.TypedArray;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.TextView;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Common base class for preferences that have two selectable states, persist a
  * boolean value in SharedPreferences, and may have dependent preferences that are
@@ -200,6 +203,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     protected void syncSummaryView(View view) {
         if (!(view instanceof TextView)) {
             return;
diff --git a/v7/preference/src/android/support/v7/preference/internal/AbstractMultiSelectListPreference.java b/v7/preference/src/android/support/v7/preference/internal/AbstractMultiSelectListPreference.java
index 737c209..6fcd77c 100644
--- a/v7/preference/src/android/support/v7/preference/internal/AbstractMultiSelectListPreference.java
+++ b/v7/preference/src/android/support/v7/preference/internal/AbstractMultiSelectListPreference.java
@@ -17,11 +17,14 @@
 package android.support.v7.preference.internal;
 
 import android.content.Context;
+import android.support.annotation.RestrictTo;
 import android.support.v7.preference.DialogPreference;
 import android.util.AttributeSet;
 
 import java.util.Set;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
+
 /**
  * Stub superclass for {@link android.support.v14.preference.MultiSelectListPreference} so that we
  * can reference it from
@@ -29,6 +32,7 @@
  *
  * @hide
  */
+@RestrictTo(GROUP_ID)
 public abstract class AbstractMultiSelectListPreference extends DialogPreference {
     public AbstractMultiSelectListPreference(Context context, AttributeSet attrs, int defStyleAttr,
             int defStyleRes) {
diff --git a/v7/preference/src/android/support/v7/preference/internal/package-info.java b/v7/preference/src/android/support/v7/preference/internal/package-info.java
new file mode 100644
index 0000000..6561bf1
--- /dev/null
+++ b/v7/preference/src/android/support/v7/preference/internal/package-info.java
@@ -0,0 +1,9 @@
+/**
+ * @hide
+ */
+@RestrictTo(GROUP_ID)
+package android.support.v7.preference.internal;
+
+import android.support.annotation.RestrictTo;
+
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
\ No newline at end of file
diff --git a/v7/recyclerview/src/android/support/v7/util/AsyncListUtil.java b/v7/recyclerview/src/android/support/v7/util/AsyncListUtil.java
index c2a66b4..bb31eab 100644
--- a/v7/recyclerview/src/android/support/v7/util/AsyncListUtil.java
+++ b/v7/recyclerview/src/android/support/v7/util/AsyncListUtil.java
@@ -44,9 +44,9 @@
  *
  */
 public class AsyncListUtil<T> {
-    private static final String TAG = "AsyncListUtil";
+    static final String TAG = "AsyncListUtil";
 
-    private static final boolean DEBUG = false;
+    static final boolean DEBUG = false;
 
     final Class<T> mTClass;
     final int mTileSize;
@@ -62,17 +62,17 @@
     final int[] mPrevRange = new int[2];
     final int[] mTmpRangeExtended = new int[2];
 
-    private boolean mAllowScrollHints;
+    boolean mAllowScrollHints;
     private int mScrollHint = ViewCallback.HINT_SCROLL_NONE;
 
-    private int mItemCount = 0;
+    int mItemCount = 0;
 
     int mDisplayedGeneration = 0;
     int mRequestedGeneration = mDisplayedGeneration;
 
-    final private SparseIntArray mMissingPositions = new SparseIntArray();
+    final SparseIntArray mMissingPositions = new SparseIntArray();
 
-    private void log(String s, Object... args) {
+    void log(String s, Object... args) {
         Log.d(TAG, "[MAIN] " + String.format(s, args));
     }
 
@@ -171,7 +171,7 @@
         return mItemCount;
     }
 
-    private void updateRange() {
+    void updateRange() {
         mViewCallback.getItemRangeInto(mTmpRange);
         if (mTmpRange[0] > mTmpRange[1] || mTmpRange[0] < 0) {
             return;
diff --git a/v7/recyclerview/src/android/support/v7/util/MessageThreadUtil.java b/v7/recyclerview/src/android/support/v7/util/MessageThreadUtil.java
index 8aa9eda..523801a 100644
--- a/v7/recyclerview/src/android/support/v7/util/MessageThreadUtil.java
+++ b/v7/recyclerview/src/android/support/v7/util/MessageThreadUtil.java
@@ -29,12 +29,12 @@
     @Override
     public MainThreadCallback<T> getMainThreadProxy(final MainThreadCallback<T> callback) {
         return new MainThreadCallback<T>() {
-            final private MessageQueue mQueue = new MessageQueue();
+            final MessageQueue mQueue = new MessageQueue();
             final private Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
 
-            private static final int UPDATE_ITEM_COUNT = 1;
-            private static final int ADD_TILE = 2;
-            private static final int REMOVE_TILE = 3;
+            static final int UPDATE_ITEM_COUNT = 1;
+            static final int ADD_TILE = 2;
+            static final int REMOVE_TILE = 3;
 
             @Override
             public void updateItemCount(int generation, int itemCount) {
@@ -85,14 +85,14 @@
     @Override
     public BackgroundCallback<T> getBackgroundProxy(final BackgroundCallback<T> callback) {
         return new BackgroundCallback<T>() {
-            final private MessageQueue mQueue = new MessageQueue();
+            final MessageQueue mQueue = new MessageQueue();
             final private Executor mExecutor = ParallelExecutorCompat.getParallelExecutor();
             AtomicBoolean mBackgroundRunning = new AtomicBoolean(false);
 
-            private static final int REFRESH = 1;
-            private static final int UPDATE_RANGE = 2;
-            private static final int LOAD_TILE = 3;
-            private static final int RECYCLE_TILE = 4;
+            static final int REFRESH = 1;
+            static final int UPDATE_RANGE = 2;
+            static final int LOAD_TILE = 3;
+            static final int RECYCLE_TILE = 4;
 
             @Override
             public void refresh(int generation) {
diff --git a/v7/recyclerview/src/android/support/v7/util/SortedList.java b/v7/recyclerview/src/android/support/v7/util/SortedList.java
index fd78348..74cf1fe 100644
--- a/v7/recyclerview/src/android/support/v7/util/SortedList.java
+++ b/v7/recyclerview/src/android/support/v7/util/SortedList.java
@@ -761,7 +761,7 @@
      */
     public static class BatchedCallback<T2> extends Callback<T2> {
 
-        private final Callback<T2> mWrappedCallback;
+        final Callback<T2> mWrappedCallback;
         private final BatchingListUpdateCallback mBatchingListUpdateCallback;
         /**
          * Creates a new BatchedCallback that wraps the provided Callback.
diff --git a/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java b/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java
index d64621a..f388c3f 100644
--- a/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java
+++ b/v7/recyclerview/src/android/support/v7/widget/DefaultItemAnimator.java
@@ -41,20 +41,20 @@
     private ArrayList<MoveInfo> mPendingMoves = new ArrayList<>();
     private ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>();
 
-    private ArrayList<ArrayList<ViewHolder>> mAdditionsList = new ArrayList<>();
-    private ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>();
-    private ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>();
+    ArrayList<ArrayList<ViewHolder>> mAdditionsList = new ArrayList<>();
+    ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>();
+    ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>();
 
-    private ArrayList<ViewHolder> mAddAnimations = new ArrayList<>();
-    private ArrayList<ViewHolder> mMoveAnimations = new ArrayList<>();
-    private ArrayList<ViewHolder> mRemoveAnimations = new ArrayList<>();
-    private ArrayList<ViewHolder> mChangeAnimations = new ArrayList<>();
+    ArrayList<ViewHolder> mAddAnimations = new ArrayList<>();
+    ArrayList<ViewHolder> mMoveAnimations = new ArrayList<>();
+    ArrayList<ViewHolder> mRemoveAnimations = new ArrayList<>();
+    ArrayList<ViewHolder> mChangeAnimations = new ArrayList<>();
 
     private static class MoveInfo {
         public ViewHolder holder;
         public int fromX, fromY, toX, toY;
 
-        private MoveInfo(ViewHolder holder, int fromX, int fromY, int toX, int toY) {
+        MoveInfo(ViewHolder holder, int fromX, int fromY, int toX, int toY) {
             this.holder = holder;
             this.fromX = fromX;
             this.fromY = fromY;
@@ -71,7 +71,7 @@
             this.newHolder = newHolder;
         }
 
-        private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder,
+        ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder,
                 int fromX, int fromY, int toX, int toY) {
             this(oldHolder, newHolder);
             this.fromX = fromX;
@@ -221,7 +221,7 @@
         return true;
     }
 
-    private void animateAddImpl(final ViewHolder holder) {
+    void animateAddImpl(final ViewHolder holder) {
         final View view = holder.itemView;
         final ViewPropertyAnimatorCompat animation = ViewCompat.animate(view);
         mAddAnimations.add(holder);
@@ -269,7 +269,7 @@
         return true;
     }
 
-    private void animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) {
+    void animateMoveImpl(final ViewHolder holder, int fromX, int fromY, int toX, int toY) {
         final View view = holder.itemView;
         final int deltaX = toX - fromX;
         final int deltaY = toY - fromY;
@@ -337,7 +337,7 @@
         return true;
     }
 
-    private void animateChangeImpl(final ChangeInfo changeInfo) {
+    void animateChangeImpl(final ChangeInfo changeInfo) {
         final ViewHolder holder = changeInfo.oldHolder;
         final View view = holder == null ? null : holder.itemView;
         final ViewHolder newHolder = changeInfo.newHolder;
@@ -536,7 +536,7 @@
      * pending/running, call {@link #dispatchAnimationsFinished()} to notify any
      * listeners.
      */
-    private void dispatchFinishedWhenDone() {
+    void dispatchFinishedWhenDone() {
         if (!isRunning()) {
             dispatchAnimationsFinished();
         }
@@ -657,6 +657,9 @@
     }
 
     private static class VpaListenerAdapter implements ViewPropertyAnimatorListener {
+        VpaListenerAdapter() {
+        }
+
         @Override
         public void onAnimationStart(View view) {}
 
diff --git a/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
index 4d19163..6365017 100644
--- a/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/GridLayoutManager.java
@@ -505,6 +505,27 @@
     }
 
     @Override
+    int getItemPrefetchCount() {
+        return mSpanCount;
+    }
+
+    @Override
+    int gatherPrefetchIndicesForLayoutState(RecyclerView.State state, LayoutState layoutState,
+                int[] outIndices) {
+        int remainingSpan = mSpanCount;
+        int count = 0;
+        while (count < mSpanCount && layoutState.hasMore(state) && remainingSpan > 0) {
+            final int pos = layoutState.mCurrentPosition;
+            outIndices[count] = pos;
+            final int spanSize = mSpanSizeLookup.getSpanSize(pos);
+            remainingSpan -= spanSize;
+            layoutState.mCurrentPosition += layoutState.mItemDirection;
+            count++;
+        }
+        return count;
+    }
+
+    @Override
     void layoutChunk(RecyclerView.Recycler recycler, RecyclerView.State state,
             LayoutState layoutState, LayoutChunkResult result) {
         final int otherDirSpecMode = mOrientationHelper.getModeInOther();
@@ -1080,9 +1101,9 @@
          */
         public static final int INVALID_SPAN_ID = -1;
 
-        private int mSpanIndex = INVALID_SPAN_ID;
+        int mSpanIndex = INVALID_SPAN_ID;
 
-        private int mSpanSize = 0;
+        int mSpanSize = 0;
 
         public LayoutParams(Context c, AttributeSet attrs) {
             super(c, attrs);
diff --git a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
index 5ee2537..d21406c 100644
--- a/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/LinearLayoutManager.java
@@ -16,12 +16,14 @@
 
 package android.support.v7.widget;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v7.widget.RecyclerView.NO_POSITION;
 
 import android.content.Context;
 import android.graphics.PointF;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.support.v4.view.accessibility.AccessibilityRecordCompat;
@@ -44,7 +46,7 @@
 
     private static final String TAG = "LinearLayoutManager";
 
-    private static final boolean DEBUG = false;
+    static final boolean DEBUG = false;
 
     public static final int HORIZONTAL = OrientationHelper.HORIZONTAL;
 
@@ -1180,6 +1182,36 @@
                 && mOrientationHelper.getEnd() == 0;
     }
 
+    @Override
+    int getItemPrefetchCount() {
+        return 1;
+    }
+
+    int gatherPrefetchIndicesForLayoutState(RecyclerView.State state, LayoutState layoutState,
+            int[] outIndices) {
+        final int pos = layoutState.mCurrentPosition;
+        if (pos >= 0 && pos < state.getItemCount()) {
+            outIndices[0] = pos;
+            return 1;
+        }
+        return 0;
+    }
+
+    @Override
+    int gatherPrefetchIndices(int dx, int dy, RecyclerView.State state, int[] outIndices) {
+        int delta = (mOrientation == HORIZONTAL) ? dx : dy;
+        if (getChildCount() == 0 || delta == 0) {
+            // can't support this scroll, so don't bother prefetching
+            return 0;
+        }
+
+
+        final int layoutDirection = delta > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START;
+        final int absDy = Math.abs(delta);
+        updateLayoutState(layoutDirection, absDy, true, state);
+        return gatherPrefetchIndicesForLayoutState(state, mLayoutState, outIndices);
+    }
+
     int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
         if (getChildCount() == 0 || dy == 0) {
             return 0;
@@ -1323,7 +1355,6 @@
                 }
             }
         }
-
     }
 
     /**
@@ -1888,6 +1919,7 @@
     /**
      * @hide This method should be called by ItemTouchHelper only.
      */
+    @RestrictTo(GROUP_ID)
     @Override
     public void prepareForDrop(View view, View target, int x, int y) {
         assertNotInLayoutOrScroll("Cannot drop a view during a scroll or layout calculation");
@@ -2106,6 +2138,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class SavedState implements Parcelable {
 
         int mAnchorPosition;
@@ -2204,7 +2237,7 @@
                     '}';
         }
 
-        private boolean isViewValidAsAnchor(View child, RecyclerView.State state) {
+        boolean isViewValidAsAnchor(View child, RecyclerView.State state) {
             LayoutParams lp = (LayoutParams) child.getLayoutParams();
             return !lp.isItemRemoved() && lp.getViewLayoutPosition() >= 0
                     && lp.getViewLayoutPosition() < state.getItemCount();
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
index 7bd0417..88e0c41 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerView.java
@@ -34,6 +34,7 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.annotation.VisibleForTesting;
 import android.support.v4.os.ParcelableCompat;
 import android.support.v4.os.ParcelableCompatCreatorCallbacks;
@@ -58,6 +59,7 @@
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 import android.util.TypedValue;
+import android.view.Display;
 import android.view.FocusFinder;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -74,9 +76,12 @@
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v7.widget.AdapterHelper.Callback;
 import static android.support.v7.widget.AdapterHelper.UpdateOp;
 
@@ -149,9 +154,9 @@
  */
 public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild {
 
-    private static final String TAG = "RecyclerView";
+    static final String TAG = "RecyclerView";
 
-    private static final boolean DEBUG = false;
+    static final boolean DEBUG = false;
 
     private static final int[]  NESTED_SCROLLING_ATTRS
             = {16843830 /* android.R.attr.nestedScrollingEnabled */};
@@ -165,7 +170,7 @@
      * recursively traverses itemView and invalidates display list for each ViewGroup that matches
      * this criteria.
      */
-    private static final boolean FORCE_INVALIDATE_DISPLAY_LIST = Build.VERSION.SDK_INT == 18
+    static final boolean FORCE_INVALIDATE_DISPLAY_LIST = Build.VERSION.SDK_INT == 18
             || Build.VERSION.SDK_INT == 19 || Build.VERSION.SDK_INT == 20;
     /**
      * On M+, an unspecified measure spec may include a hint which we can use. On older platforms,
@@ -176,6 +181,12 @@
 
     static final boolean POST_UPDATES_ON_ANIMATION = Build.VERSION.SDK_INT >= 16;
 
+    /**
+     * On L+, with RenderThread, the UI thread has idle time after it has passed a frame off to
+     * RenderThread but before the next frame begins. We schedule prefetch work in this window.
+     */
+    private static final boolean ALLOW_PREFETCHING = Build.VERSION.SDK_INT >= 21;
+
     static final boolean DISPATCH_TEMP_DETACH = false;
     public static final int HORIZONTAL = 0;
     public static final int VERTICAL = 1;
@@ -198,14 +209,14 @@
      */
     public static final int TOUCH_SLOP_PAGING = 1;
 
-    private static final int MAX_SCROLL_DURATION = 2000;
+    static final int MAX_SCROLL_DURATION = 2000;
 
     /**
      * RecyclerView is calculating a scroll.
      * If there are too many of these in Systrace, some Views inside RecyclerView might be causing
      * it. Try to avoid using EditText, focusable views or handle them with care.
      */
-    private static final String TRACE_SCROLL_TAG = "RV Scroll";
+    static final String TRACE_SCROLL_TAG = "RV Scroll";
 
     /**
      * OnLayout has been called by the View system.
@@ -236,7 +247,12 @@
      * If this is taking a lot of time, consider optimizing your layout or make sure you are not
      * doing extra operations in onBindViewHolder call.
      */
-    private static final String TRACE_BIND_VIEW_TAG = "RV OnBindView";
+    static final String TRACE_BIND_VIEW_TAG = "RV OnBindView";
+
+    /**
+     * RecyclerView is attempting to pre-populate off screen views.
+     */
+    private static final String TRACE_PREFETCH_TAG = "RV Prefetch";
 
     /**
      * RecyclerView is creating a new View.
@@ -251,7 +267,7 @@
      * - There might be too many itemChange animations and not enough space in RecyclerPool.
      * >Try increasing your pool size and item cache size.
      */
-    private static final String TRACE_CREATE_VIEW_TAG = "RV CreateView";
+    static final String TRACE_CREATE_VIEW_TAG = "RV CreateView";
     private static final Class<?>[] LAYOUT_MANAGER_CONSTRUCTOR_SIGNATURE =
             new Class[]{Context.class, AttributeSet.class, int.class, int.class};
 
@@ -280,7 +296,7 @@
      * Prior to L, there is no way to query this variable which is why we override the setter and
      * track it here.
      */
-    private boolean mClipToPadding;
+    boolean mClipToPadding;
 
     /**
      * Note: this Runnable is only ever posted if:
@@ -288,7 +304,7 @@
      * 2) We know we have a fixed size (mHasFixedSize)
      * 3) We're attached
      */
-    private final Runnable mUpdateChildViewsRunnable = new Runnable() {
+    final Runnable mUpdateChildViewsRunnable = new Runnable() {
         @Override
         public void run() {
             if (!mFirstLayoutComplete || isLayoutRequested()) {
@@ -308,30 +324,30 @@
         }
     };
 
-    private final Rect mTempRect = new Rect();
+    final Rect mTempRect = new Rect();
     private final Rect mTempRect2 = new Rect();
-    private final RectF mTempRectF = new RectF();
-    private Adapter mAdapter;
+    final RectF mTempRectF = new RectF();
+    Adapter mAdapter;
     @VisibleForTesting LayoutManager mLayout;
-    private RecyclerListener mRecyclerListener;
-    private final ArrayList<ItemDecoration> mItemDecorations = new ArrayList<>();
+    RecyclerListener mRecyclerListener;
+    final ArrayList<ItemDecoration> mItemDecorations = new ArrayList<>();
     private final ArrayList<OnItemTouchListener> mOnItemTouchListeners =
             new ArrayList<>();
     private OnItemTouchListener mActiveOnItemTouchListener;
-    private boolean mIsAttached;
-    private boolean mHasFixedSize;
+    boolean mIsAttached;
+    boolean mHasFixedSize;
     @VisibleForTesting boolean mFirstLayoutComplete;
 
     // Counting lock to control whether we should ignore requestLayout calls from children or not.
     private int mEatRequestLayout = 0;
 
-    private boolean mLayoutRequestEaten;
-    private boolean mLayoutFrozen;
+    boolean mLayoutRequestEaten;
+    boolean mLayoutFrozen;
     private boolean mIgnoreMotionEventTillDown;
 
     // binary OR of change events that were eaten during a layout or scroll.
     private int mEatenAccessibilityChangeFlags;
-    private boolean mAdapterUpdateDuringMeasure;
+    boolean mAdapterUpdateDuringMeasure;
 
     private final AccessibilityManager mAccessibilityManager;
     private List<OnChildAttachStateChangeListener> mOnChildAttachStateListeners;
@@ -340,7 +356,7 @@
      * Set to true when an adapter data set changed notification is received.
      * In that case, we cannot run any animations since we don't know what happened.
      */
-    private boolean mDataSetHasChangedAfterLayout = false;
+    boolean mDataSetHasChangedAfterLayout = false;
 
     /**
      * This variable is incremented during a dispatchLayout and/or scroll.
@@ -403,7 +419,10 @@
     private float mScrollFactor = Float.MIN_VALUE;
     private boolean mPreserveFocusAfterLayout = true;
 
-    private final ViewFlinger mViewFlinger = new ViewFlinger();
+    final ViewFlinger mViewFlinger = new ViewFlinger();
+
+    private static final long MIN_PREFETCH_TIME_NANOS = TimeUnit.MILLISECONDS.toNanos(4);
+    ViewPrefetcher mViewPrefetcher = ALLOW_PREFETCHING ? new ViewPrefetcher() : null;
 
     final State mState = new State();
 
@@ -415,8 +434,8 @@
     boolean mItemsChanged = false;
     private ItemAnimator.ItemAnimatorListener mItemAnimatorListener =
             new ItemAnimatorRestoreListener();
-    private boolean mPostedAnimatorRunner = false;
-    private RecyclerViewAccessibilityDelegate mAccessibilityDelegate;
+    boolean mPostedAnimatorRunner = false;
+    RecyclerViewAccessibilityDelegate mAccessibilityDelegate;
     private ChildDrawingOrderCallback mChildDrawingOrderCallback;
 
     // simple array to keep min and max child position during a layout calculation
@@ -438,7 +457,7 @@
         }
     };
 
-    private static final Interpolator sQuinticInterpolator = new Interpolator() {
+    static final Interpolator sQuinticInterpolator = new Interpolator() {
         @Override
         public float getInterpolation(float t) {
             t -= 1.0f;
@@ -1108,6 +1127,7 @@
                 mLayout.dispatchAttachedToWindow(this);
             }
         }
+        mRecycler.updateViewCacheSize();
         requestLayout();
     }
 
@@ -1205,7 +1225,7 @@
      * @see #addAnimatingView(RecyclerView.ViewHolder)
      * @return true if an animating view is removed
      */
-    private boolean removeAnimatingView(View view) {
+    boolean removeAnimatingView(View view) {
         eatRequestLayout();
         final boolean removed = mChildHelper.removeViewIfHidden(view);
         if (removed) {
@@ -1291,7 +1311,7 @@
         return mScrollState;
     }
 
-    private void setScrollState(int state) {
+    void setScrollState(int state) {
         if (state == mScrollState) {
             return;
         }
@@ -1466,7 +1486,7 @@
         awakenScrollBars();
     }
 
-    private void jumpToPositionForSmoothScroller(int position) {
+    void jumpToPositionForSmoothScroller(int position) {
         if (mLayout == null) {
             return;
         }
@@ -1532,7 +1552,7 @@
      * <p>
      * This method consumes all deferred changes to avoid that case.
      */
-    private void consumePendingUpdateOperations() {
+    void consumePendingUpdateOperations() {
         if (!mFirstLayoutComplete || mDataSetHasChangedAfterLayout) {
             TraceCompat.beginSection(TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG);
             dispatchLayout();
@@ -2048,7 +2068,7 @@
         }
     }
 
-    private void considerReleasingGlowsOnScroll(int dx, int dy) {
+    void considerReleasingGlowsOnScroll(int dx, int dy) {
         boolean needsInvalidate = false;
         if (mLeftGlow != null && !mLeftGlow.isFinished() && dx > 0) {
             needsInvalidate = mLeftGlow.onRelease();
@@ -2357,6 +2377,13 @@
             mLayout.dispatchAttachedToWindow(this);
         }
         mPostedAnimatorRunner = false;
+        Display display = ViewCompat.getDisplay(this);
+        if (ALLOW_PREFETCHING
+                && display != null
+                && display.getRefreshRate() >= 30.0f) {
+            // break 60 fps assumption if data appears good
+            mViewPrefetcher.mFrameIntervalNanos = (long) (1000000000 / display.getRefreshRate());
+        }
     }
 
     @Override
@@ -2723,6 +2750,9 @@
                             vtev)) {
                         getParent().requestDisallowInterceptTouchEvent(true);
                     }
+                    if (ALLOW_PREFETCHING) {
+                        mViewPrefetcher.postFromTraversal(dx, dy);
+                    }
                 }
             } break;
 
@@ -2952,11 +2982,11 @@
         }
     }
 
-    private void onEnterLayoutOrScroll() {
+    void onEnterLayoutOrScroll() {
         mLayoutOrScrollCounter ++;
     }
 
-    private void onExitLayoutOrScroll() {
+    void onExitLayoutOrScroll() {
         mLayoutOrScrollCounter --;
         if (mLayoutOrScrollCounter < 1) {
             if (DEBUG && mLayoutOrScrollCounter < 0) {
@@ -3054,7 +3084,7 @@
      * Post a runnable to the next frame to run pending item animations. Only the first such
      * request will be posted, governed by the mPostedAnimatorRunner flag.
      */
-    private void postAnimationRunner() {
+    void postAnimationRunner() {
         if (!mPostedAnimatorRunner && mIsAttached) {
             ViewCompat.postOnAnimation(this, mItemAnimatorRunner);
             mPostedAnimatorRunner = true;
@@ -3471,7 +3501,7 @@
      * Records the animation information for a view holder that was bounced from hidden list. It
      * also clears the bounce back flag.
      */
-    private void recordAnimationInfoIfBouncedHiddenView(ViewHolder viewHolder,
+    void recordAnimationInfoIfBouncedHiddenView(ViewHolder viewHolder,
             ItemHolderInfo animationInfo) {
         // looks like this view bounced back from hidden list!
         viewHolder.setFlags(0, ViewHolder.FLAG_BOUNCED_FROM_HIDDEN_LIST);
@@ -3538,7 +3568,7 @@
         return mAdapter.hasStableIds() ? holder.getItemId() : holder.mPosition;
     }
 
-    private void animateAppearance(@NonNull ViewHolder itemHolder,
+    void animateAppearance(@NonNull ViewHolder itemHolder,
             @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
         itemHolder.setIsRecyclable(false);
         if (mItemAnimator.animateAppearance(itemHolder, preLayoutInfo, postLayoutInfo)) {
@@ -3546,7 +3576,7 @@
         }
     }
 
-    private void animateDisappearance(@NonNull ViewHolder holder,
+    void animateDisappearance(@NonNull ViewHolder holder,
             @NonNull ItemHolderInfo preLayoutInfo, @Nullable ItemHolderInfo postLayoutInfo) {
         addAnimatingView(holder);
         holder.setIsRecyclable(false);
@@ -3850,12 +3880,12 @@
         mRecycler.viewRangeUpdate(positionStart, itemCount);
     }
 
-    private boolean canReuseUpdatedViewHolder(ViewHolder viewHolder) {
+    boolean canReuseUpdatedViewHolder(ViewHolder viewHolder) {
         return mItemAnimator == null || mItemAnimator.canReuseUpdatedViewHolder(viewHolder,
                 viewHolder.getUnmodifiedPayloads());
     }
 
-    private void setDataSetChangedAfterLayout() {
+    void setDataSetChangedAfterLayout() {
         if (mDataSetHasChangedAfterLayout) {
             return;
         }
@@ -4398,6 +4428,76 @@
                 || mAdapterHelper.hasPendingUpdates();
     }
 
+    /**
+     * Runs prefetch work immediately after a traversal, in the downtime while the UI thread is
+     * waiting for VSYNC.
+     */
+    class ViewPrefetcher implements Runnable {
+        long mFrameIntervalNanos = TimeUnit.MILLISECONDS.toNanos(16);
+
+        long mPostTimeNanos;
+        private int mDx;
+        private int mDy;
+
+        private int[] mItemPrefetchArray;
+
+        /**
+         * Schedule a prefetch immediately after the current traversal.
+         */
+        public void postFromTraversal(int dx, int dy) {
+            if (ALLOW_PREFETCHING
+                    && mAdapter != null
+                    && mLayout != null
+                    && mLayout.getItemPrefetchCount() > 0) {
+                mDx = dx;
+                mDy = dy;
+                mPostTimeNanos = System.nanoTime();
+                RecyclerView.this.post(this);
+            }
+        }
+
+        @Override
+        public void run() {
+            try {
+                TraceCompat.beginSection(TRACE_PREFETCH_TAG);
+                final int prefetchCount = mLayout.getItemPrefetchCount();
+                if (mAdapter == null
+                        || mLayout == null
+                        || !mLayout.isItemPrefetchEnabled()
+                        || prefetchCount < 1
+                        || hasPendingAdapterUpdates()) {
+                    // abort - no work
+                    return;
+                }
+
+                // Query last vsync so we can predict next one. Note that drawing time not yet
+                // valid in animation/input callbacks, so query it here to be safe.
+                long lastFrameVsyncNanos = TimeUnit.MILLISECONDS.toNanos(getDrawingTime());
+                if (lastFrameVsyncNanos == 0) {
+                    // abort - couldn't get last vsync for estimating next
+                    return;
+                }
+
+                long nowNanos = System.nanoTime();
+                long nextFrameNanos = lastFrameVsyncNanos + mFrameIntervalNanos;
+                if (nowNanos - mPostTimeNanos > mFrameIntervalNanos
+                        || nextFrameNanos - nowNanos < MIN_PREFETCH_TIME_NANOS) {
+                    // abort - Executing either too far after post, or too near next scheduled vsync
+                    return;
+                }
+
+                if (mItemPrefetchArray == null || mItemPrefetchArray.length < prefetchCount) {
+                    mItemPrefetchArray = new int[prefetchCount];
+                }
+                Arrays.fill(mItemPrefetchArray, -1);
+                int viewCount = mLayout.gatherPrefetchIndices(mDx, mDy, mState, mItemPrefetchArray);
+                mRecycler.prefetch(mItemPrefetchArray, viewCount);
+            } finally {
+                TraceCompat.endSection();
+            }
+        }
+    }
+
     private class ViewFlinger implements Runnable {
         private int mLastFlingX;
         private int mLastFlingY;
@@ -4514,6 +4614,9 @@
                     setScrollState(SCROLL_STATE_IDLE); // setting state to idle will stop this.
                 } else {
                     postOnAnimation();
+                    if (ALLOW_PREFETCHING) {
+                        mViewPrefetcher.postFromTraversal(dx, dy);
+                    }
                 }
             }
             // call this after the onAnimation is complete not to have inconsistent callbacks etc.
@@ -4615,7 +4718,7 @@
 
     }
 
-    private void repositionShadowingViews() {
+    void repositionShadowingViews() {
         // Fix up shadow views used by change animations
         int count = mChildHelper.getChildCount();
         for (int i = 0; i < count; i++) {
@@ -4636,6 +4739,9 @@
     }
 
     private class RecyclerViewDataObserver extends AdapterDataObserver {
+        RecyclerViewDataObserver() {
+        }
+
         @Override
         public void onChanged() {
             assertNotInLayoutOrScroll(null);
@@ -4823,20 +4929,21 @@
      */
     public final class Recycler {
         final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>();
-        private ArrayList<ViewHolder> mChangedScrap = null;
+        ArrayList<ViewHolder> mChangedScrap = null;
 
         final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();
 
         private final List<ViewHolder>
                 mUnmodifiableAttachedScrap = Collections.unmodifiableList(mAttachedScrap);
 
-        private int mViewCacheMax = DEFAULT_CACHE_SIZE;
+        private int mRequestedCacheMax = DEFAULT_CACHE_SIZE;
+        int mViewCacheMax = DEFAULT_CACHE_SIZE;
 
         private RecycledViewPool mRecyclerPool;
 
         private ViewCacheExtension mViewCacheExtension;
 
-        private static final int DEFAULT_CACHE_SIZE = 2;
+        static final int DEFAULT_CACHE_SIZE = 2;
 
         /**
          * Clear scrap views out of this recycler. Detached views contained within a
@@ -4853,9 +4960,19 @@
          * @param viewCount Number of views to keep before sending views to the shared pool
          */
         public void setViewCacheSize(int viewCount) {
-            mViewCacheMax = viewCount;
+            mRequestedCacheMax = viewCount;
+            updateViewCacheSize();
+        }
+
+        void updateViewCacheSize() {
+            int extraCache = 0;
+            if (mLayout != null && ALLOW_PREFETCHING) {
+                extraCache = mLayout.isItemPrefetchEnabled() ? mLayout.getItemPrefetchCount() : 0;
+            }
+            mViewCacheMax = mRequestedCacheMax + extraCache;
             // first, try the views that can be recycled
-            for (int i = mCachedViews.size() - 1; i >= 0 && mCachedViews.size() > viewCount; i--) {
+            for (int i = mCachedViews.size() - 1;
+                    i >= 0 && mCachedViews.size() > mViewCacheMax; i--) {
                 recycleCachedViewAt(i);
             }
         }
@@ -5734,6 +5851,21 @@
                 }
             }
         }
+
+        void prefetch(int[] itemPrefetchArray, int viewCount) {
+            if (viewCount == 0) return;
+
+            int childPosition = itemPrefetchArray[viewCount - 1];
+            if (childPosition < 0) {
+                throw new IllegalArgumentException("Recycler requested to prefetch invalid view "
+                        + childPosition);
+            }
+            View prefetchView = getViewForPosition(childPosition);
+            if (viewCount > 1) {
+                prefetch(itemPrefetchArray, viewCount - 1);
+            }
+            recycleView(prefetchView);
+        }
     }
 
     /**
@@ -6316,7 +6448,7 @@
         }
     }
 
-    private void dispatchChildDetached(View child) {
+    void dispatchChildDetached(View child) {
         final ViewHolder viewHolder = getChildViewHolderInt(child);
         onChildDetachedFromWindow(child);
         if (mAdapter != null && viewHolder != null) {
@@ -6330,7 +6462,7 @@
         }
     }
 
-    private void dispatchChildAttached(View child) {
+    void dispatchChildAttached(View child) {
         final ViewHolder viewHolder = getChildViewHolderInt(child);
         onChildAttachedToWindow(child);
         if (mAdapter != null && viewHolder != null) {
@@ -6367,11 +6499,11 @@
         @Nullable
         SmoothScroller mSmoothScroller;
 
-        private boolean mRequestedSimpleAnimations = false;
+        boolean mRequestedSimpleAnimations = false;
 
         boolean mIsAttachedToWindow = false;
 
-        private boolean mAutoMeasure = false;
+        boolean mAutoMeasure = false;
 
         /**
          * LayoutManager has its own more strict measurement cache to avoid re-measuring a child
@@ -6379,6 +6511,7 @@
          */
         private boolean mMeasurementCacheEnabled = true;
 
+        private boolean mItemPrefetchEnabled = true;
 
         /**
          * These measure specs might be the measure specs that were passed into RecyclerView's
@@ -6660,6 +6793,52 @@
             return false;
         }
 
+        /**
+         * Sets whether the LayoutManager should be queried for views outside of
+         * its viewport while the UI thread is idle between frames.
+         *
+         * <p>If enabled, the LayoutManager will be queried for items to inflate/bind in between
+         * view system traversals on devices running API 21 or greater. Default value is true.</p>
+         *
+         * <p>On platforms API level 21 and higher, the UI thread is idle between passing a frame
+         * to RenderThread and the starting up its next frame at the next VSync pulse. By
+         * prefetching out of window views in this time period, delays from inflation and view
+         * binding are much less likely to cause jank and stuttering during scrolls and flings.</p>
+         *
+         * <p>While prefetch is enabled, it will have the side effect of expanding the effective
+         * size of the View cache to hold prefetched views.</p>
+         *
+         * @param enabled <code>True</code> if items should be prefetched in between traversals.
+         *
+         * @see #isItemPrefetchEnabled()
+         */
+        public final void setItemPrefetchEnabled(boolean enabled) {
+            if (enabled != mItemPrefetchEnabled) {
+                mItemPrefetchEnabled = enabled;
+                if (mRecyclerView != null) {
+                    mRecyclerView.mRecycler.updateViewCacheSize();
+                }
+            }
+        }
+
+        /**
+         * Sets whether the LayoutManager should be queried for views outside of
+         * its viewport while the UI thread is idle between frames.
+         *
+         * @see #setItemPrefetchEnabled(boolean)
+         *
+         * @return true if item prefetch is enabled, false otherwise
+         */
+        public final boolean isItemPrefetchEnabled() {
+            return mItemPrefetchEnabled;
+        }
+
+        int getItemPrefetchCount() { return 0; }
+
+        int gatherPrefetchIndices(int dx, int dy, State state, int[] outIndices) {
+            return 0;
+        }
+
         void dispatchAttachedToWindow(RecyclerView view) {
             mIsAttachedToWindow = true;
             onAttachedToWindow(view);
@@ -9826,7 +10005,7 @@
         }
     }
 
-    private int getAdapterPositionFor(ViewHolder viewHolder) {
+    int getAdapterPositionFor(ViewHolder viewHolder) {
         if (viewHolder.hasAnyOfTheFlags( ViewHolder.FLAG_INVALID |
                 ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)
                 || !viewHolder.isBound()) {
@@ -10337,7 +10516,7 @@
                 return mJumpToPosition >= 0;
             }
 
-            private void runIfNecessary(RecyclerView recyclerView) {
+            void runIfNecessary(RecyclerView recyclerView) {
                 if (mJumpToPosition >= 0) {
                     final int position = mJumpToPosition;
                     mJumpToPosition = NO_POSITION;
@@ -10522,6 +10701,7 @@
      * This is public so that the CREATOR can be access on cold launch.
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class SavedState extends AbsSavedState {
 
         Parcelable mLayoutState;
@@ -10548,7 +10728,7 @@
             dest.writeParcelable(mLayoutState, 0);
         }
 
-        private void copyFrom(SavedState other) {
+        void copyFrom(SavedState other) {
             mLayoutState = other.mLayoutState;
         }
 
@@ -10597,7 +10777,7 @@
         private int mTargetPosition = RecyclerView.NO_POSITION;
 
         @LayoutState
-        private int mLayoutStep = STEP_START;
+        int mLayoutStep = STEP_START;
 
         private SparseArray<Object> mData;
 
@@ -10609,25 +10789,25 @@
         /**
          * Number of items adapter had in the previous layout.
          */
-        private int mPreviousLayoutItemCount = 0;
+        int mPreviousLayoutItemCount = 0;
 
         /**
          * Number of items that were NOT laid out but has been deleted from the adapter after the
          * previous layout.
          */
-        private int mDeletedInvisibleItemCountSincePreviousLayout = 0;
+        int mDeletedInvisibleItemCountSincePreviousLayout = 0;
 
-        private boolean mStructureChanged = false;
+        boolean mStructureChanged = false;
 
-        private boolean mInPreLayout = false;
+        boolean mInPreLayout = false;
 
-        private boolean mRunSimpleAnimations = false;
+        boolean mRunSimpleAnimations = false;
 
-        private boolean mRunPredictiveAnimations = false;
+        boolean mRunPredictiveAnimations = false;
 
-        private boolean mTrackOldChangeHolders = false;
+        boolean mTrackOldChangeHolders = false;
 
-        private boolean mIsMeasuring = false;
+        boolean mIsMeasuring = false;
 
         /**
          * This data is saved before a layout calculation happens. After the layout is finished,
@@ -10846,6 +11026,9 @@
      */
     private class ItemAnimatorRestoreListener implements ItemAnimator.ItemAnimatorListener {
 
+        ItemAnimatorRestoreListener() {
+        }
+
         @Override
         public void onAnimationFinished(ViewHolder item) {
             item.setIsRecyclable(true);
diff --git a/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java b/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
index 1283f03..c44c802 100644
--- a/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
+++ b/v7/recyclerview/src/android/support/v7/widget/RecyclerViewAccessibilityDelegate.java
@@ -35,7 +35,7 @@
         mRecyclerView = recyclerView;
     }
 
-    private boolean shouldIgnore() {
+    boolean shouldIgnore() {
         return mRecyclerView.hasPendingAdapterUpdates();
     }
 
diff --git a/v7/recyclerview/src/android/support/v7/widget/SnapHelper.java b/v7/recyclerview/src/android/support/v7/widget/SnapHelper.java
index a2c557d..915556e 100644
--- a/v7/recyclerview/src/android/support/v7/widget/SnapHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/SnapHelper.java
@@ -34,21 +34,30 @@
  */
 public abstract class SnapHelper extends RecyclerView.OnFlingListener {
 
-    private static final float MILLISECONDS_PER_INCH = 100f;
+    static final float MILLISECONDS_PER_INCH = 100f;
 
-    private RecyclerView mRecyclerView;
+    RecyclerView mRecyclerView;
     private Scroller mGravityScroller;
 
     // Handles the snap on scroll case.
     private final RecyclerView.OnScrollListener mScrollListener =
             new RecyclerView.OnScrollListener() {
+                boolean mScrolled = false;
+
                 @Override
                 public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                     super.onScrollStateChanged(recyclerView, newState);
-                    if (newState == RecyclerView.SCROLL_STATE_IDLE) {
+                    if (newState == RecyclerView.SCROLL_STATE_IDLE && mScrolled) {
+                        mScrolled = false;
                         snapToTargetExistingView();
                     }
                 }
+
+                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+                    if (dx != 0 || dy != 0) {
+                        mScrolled = true;
+                    }
+                }
             };
 
     @Override
@@ -169,7 +178,7 @@
      * method is used to snap the view when the {@link RecyclerView} is first attached; when
      * snapping was triggered by a scroll and when the fling is at its final stages.
      */
-    private void snapToTargetExistingView() {
+    void snapToTargetExistingView() {
         if (mRecyclerView == null) {
             return;
         }
diff --git a/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java b/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java
index 12745fe..eba10ca 100644
--- a/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java
+++ b/v7/recyclerview/src/android/support/v7/widget/StaggeredGridLayoutManager.java
@@ -16,6 +16,7 @@
 
 package android.support.v7.widget;
 
+import static android.support.annotation.RestrictTo.Scope.GROUP_ID;
 import static android.support.v7.widget.LayoutState.ITEM_DIRECTION_HEAD;
 import static android.support.v7.widget.LayoutState.ITEM_DIRECTION_TAIL;
 import static android.support.v7.widget.LayoutState.LAYOUT_END;
@@ -29,6 +30,7 @@
 import android.os.Parcelable;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
+import android.support.annotation.RestrictTo;
 import android.support.v4.view.ViewCompat;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
@@ -57,7 +59,7 @@
 
     private static final String TAG = "StaggeredGridLayoutManager";
 
-    private static final boolean DEBUG = false;
+    static final boolean DEBUG = false;
 
     public static final int HORIZONTAL = OrientationHelper.HORIZONTAL;
 
@@ -96,7 +98,7 @@
      */
     public static final int GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS = 2;
 
-    private static final int INVALID_OFFSET = Integer.MIN_VALUE;
+    static final int INVALID_OFFSET = Integer.MIN_VALUE;
     /**
      * While trying to find next view to focus, LayoutManager will not try to scroll more
      * than this factor times the total space of the list. If layout is vertical, total space is the
@@ -109,7 +111,7 @@
      */
     private int mSpanCount = -1;
 
-    private Span[] mSpans;
+    Span[] mSpans;
 
     /**
      * Primary orientation is the layout's orientation, secondary orientation is the orientation
@@ -130,7 +132,7 @@
     @NonNull
     private final LayoutState mLayoutState;
 
-    private boolean mReverseLayout = false;
+    boolean mReverseLayout = false;
 
     /**
      * Aggregated reverse layout value that takes RTL into account.
@@ -260,7 +262,7 @@
      * When a full span item is laid out in reverse direction, it sets a flag which we check when
      * scroll is stopped (or re-layout happens) and re-layout after first valid item.
      */
-    private boolean checkForGaps() {
+    boolean checkForGaps() {
         if (getChildCount() == 0 || mGapStrategy == GAP_HANDLING_NONE || !isAttachedToWindow()) {
             return false;
         }
@@ -610,8 +612,9 @@
             }
         }
 
-        if (!anchorInfo.mValid || mPendingScrollPosition != NO_POSITION ||
-                mPendingSavedState != null) {
+        boolean recalculateAnchor = !anchorInfo.mValid || mPendingScrollPosition != NO_POSITION ||
+                mPendingSavedState != null;
+        if (recalculateAnchor) {
             anchorInfo.reset();
             if (mPendingSavedState != null) {
                 applyPendingSavedState(anchorInfo);
@@ -619,7 +622,6 @@
                 resolveShouldLayoutReverse();
                 anchorInfo.mLayoutFromEnd = mShouldReverseLayout;
             }
-
             updateAnchorInfoForLayout(state, anchorInfo);
             anchorInfo.mValid = true;
         }
@@ -642,8 +644,18 @@
                     }
                 }
             } else {
-                for (int i = 0; i < mSpanCount; i++) {
-                    mSpans[i].cacheReferenceLineAndClear(mShouldReverseLayout, anchorInfo.mOffset);
+                if (recalculateAnchor || mAnchorInfo.mSpanReferenceLines == null) {
+                    for (int i = 0; i < mSpanCount; i++) {
+                        mSpans[i].cacheReferenceLineAndClear(mShouldReverseLayout,
+                                anchorInfo.mOffset);
+                    }
+                    mAnchorInfo.saveSpanReferenceLines(mSpans);
+                } else {
+                    for (int i = 0; i < mSpanCount; i++) {
+                        final Span span = mSpans[i];
+                        span.clear();
+                        span.setLine(mAnchorInfo.mSpanReferenceLines[i]);
+                    }
                 }
             }
         }
@@ -1056,8 +1068,8 @@
             return 0;
         }
         return ScrollbarHelper.computeScrollOffset(state, mPrimaryOrientation,
-                findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled, true)
-                , findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled, true),
+                findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled),
+                findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled),
                 this, mSmoothScrollbarEnabled, mShouldReverseLayout);
     }
 
@@ -1076,8 +1088,8 @@
             return 0;
         }
         return ScrollbarHelper.computeScrollExtent(state, mPrimaryOrientation,
-                findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled, true)
-                , findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled, true),
+                findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled),
+                findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled),
                 this, mSmoothScrollbarEnabled);
     }
 
@@ -1096,8 +1108,8 @@
             return 0;
         }
         return ScrollbarHelper.computeScrollRange(state, mPrimaryOrientation,
-                findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled, true)
-                , findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled, true),
+                findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled),
+                findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled),
                 this, mSmoothScrollbarEnabled);
     }
 
@@ -1250,8 +1262,8 @@
         if (getChildCount() > 0) {
             final AccessibilityRecordCompat record = AccessibilityEventCompat
                     .asRecord(event);
-            final View start = findFirstVisibleItemClosestToStart(false, true);
-            final View end = findFirstVisibleItemClosestToEnd(false, true);
+            final View start = findFirstVisibleItemClosestToStart(false);
+            final View end = findFirstVisibleItemClosestToEnd(false);
             if (start == null || end == null) {
                 return;
             }
@@ -1273,8 +1285,8 @@
      * of returning null.
      */
     int findFirstVisibleItemPositionInt() {
-        final View first = mShouldReverseLayout ? findFirstVisibleItemClosestToEnd(true, true) :
-                findFirstVisibleItemClosestToStart(true, true);
+        final View first = mShouldReverseLayout ? findFirstVisibleItemClosestToEnd(true) :
+                findFirstVisibleItemClosestToStart(true);
         return first == null ? NO_POSITION : getPosition(first);
     }
 
@@ -1302,7 +1314,7 @@
      * This method does not do any sorting based on child's start coordinate, instead, it uses
      * children order.
      */
-    View findFirstVisibleItemClosestToStart(boolean fullyVisible, boolean acceptPartiallyVisible) {
+    View findFirstVisibleItemClosestToStart(boolean fullyVisible) {
         final int boundsStart = mPrimaryOrientation.getStartAfterPadding();
         final int boundsEnd = mPrimaryOrientation.getEndAfterPadding();
         final int limit = getChildCount();
@@ -1319,7 +1331,7 @@
                 // as long as fully visible is not requested.
                 return child;
             }
-            if (acceptPartiallyVisible && partiallyVisible == null) {
+            if (partiallyVisible == null) {
                 partiallyVisible = child;
             }
         }
@@ -1332,7 +1344,7 @@
      * This method does not do any sorting based on child's end coordinate, instead, it uses
      * children order.
      */
-    View findFirstVisibleItemClosestToEnd(boolean fullyVisible, boolean acceptPartiallyVisible) {
+    View findFirstVisibleItemClosestToEnd(boolean fullyVisible) {
         final int boundsStart = mPrimaryOrientation.getStartAfterPadding();
         final int boundsEnd = mPrimaryOrientation.getEndAfterPadding();
         View partiallyVisible = null;
@@ -1348,7 +1360,7 @@
                 // as long as fully visible is not requested.
                 return child;
             }
-            if (acceptPartiallyVisible && partiallyVisible == null) {
+            if (partiallyVisible == null) {
                 partiallyVisible = child;
             }
         }
@@ -2053,10 +2065,35 @@
         requestLayout();
     }
 
-    int scrollBy(int dt, RecyclerView.Recycler recycler, RecyclerView.State state) {
+    @Override
+    int getItemPrefetchCount() {
+        return mSpanCount;
+    }
+
+    @Override
+    int gatherPrefetchIndices(int dx, int dy, RecyclerView.State state, int[] outIndices) {
+        int delta = (mOrientation == HORIZONTAL) ? dx : dy;
+        if (getChildCount() == 0 || delta == 0) {
+            // can't support this scroll, so don't bother prefetching
+            return 0;
+        }
+        prepareLayoutStateForDelta(delta, state);
+        int remainingSpan = mSpanCount;
+        int count = 0;
+        while (count < mSpanCount && mLayoutState.hasMore(state) && remainingSpan > 0) {
+            final int pos = mLayoutState.mCurrentPosition;
+            outIndices[count] = pos;
+            remainingSpan--;
+            mLayoutState.mCurrentPosition += mLayoutState.mItemDirection;
+            count++;
+        }
+        return count;
+    }
+
+    void prepareLayoutStateForDelta(int delta, RecyclerView.State state) {
         final int referenceChildPosition;
         final int layoutDir;
-        if (dt > 0) { // layout towards end
+        if (delta > 0) { // layout towards end
             layoutDir = LAYOUT_END;
             referenceChildPosition = getLastChildPosition();
         } else {
@@ -2067,11 +2104,20 @@
         updateLayoutState(referenceChildPosition, state);
         setLayoutStateDirection(layoutDir);
         mLayoutState.mCurrentPosition = referenceChildPosition + mLayoutState.mItemDirection;
-        final int absDt = Math.abs(dt);
+        final int absDt = Math.abs(delta);
         mLayoutState.mAvailable = absDt;
+    }
+
+    int scrollBy(int dt, RecyclerView.Recycler recycler, RecyclerView.State state) {
+        if (getChildCount() == 0 || dt == 0) {
+            return 0;
+        }
+
+        prepareLayoutStateForDelta(dt, state);
         int consumed = fill(recycler, mLayoutState, state);
+        final int available = mLayoutState.mAvailable;
         final int totalScroll;
-        if (absDt < consumed) {
+        if (available < consumed) {
             totalScroll = dt;
         } else if (dt < 0) {
             totalScroll = -consumed;
@@ -2085,6 +2131,8 @@
         mPrimaryOrientation.offsetChildren(-totalScroll);
         // always reset this if we scroll for a proper save instance state
         mLastLayoutFromEnd = mShouldReverseLayout;
+        mLayoutState.mAvailable = 0;
+        recycle(recycler, mLayoutState);
         return totalScroll;
     }
 
@@ -2356,13 +2404,13 @@
     class Span {
 
         static final int INVALID_LINE = Integer.MIN_VALUE;
-        private ArrayList<View> mViews = new ArrayList<>();
+        ArrayList<View> mViews = new ArrayList<>();
         int mCachedStart = INVALID_LINE;
         int mCachedEnd = INVALID_LINE;
         int mDeletedSize = 0;
         final int mIndex;
 
-        private Span(int index) {
+        Span(int index) {
             mIndex = index;
         }
 
@@ -2928,6 +2976,7 @@
     /**
      * @hide
      */
+    @RestrictTo(GROUP_ID)
     public static class SavedState implements Parcelable {
 
         int mAnchorPosition;
@@ -3041,6 +3090,9 @@
         boolean mLayoutFromEnd;
         boolean mInvalidateOffsets;
         boolean mValid;
+        // this is where we save span reference lines in case we need to re-use them for multi-pass
+        // measure steps
+        int[] mSpanReferenceLines;
 
         public AnchorInfo() {
             reset();
@@ -3052,6 +3104,20 @@
             mLayoutFromEnd = false;
             mInvalidateOffsets = false;
             mValid = false;
+            if (mSpanReferenceLines != null) {
+                Arrays.fill(mSpanReferenceLines, -1);
+            }
+        }
+
+        void saveSpanReferenceLines(Span[] spans) {
+            int spanCount = spans.length;
+            if (mSpanReferenceLines == null || mSpanReferenceLines.length < spanCount) {
+                mSpanReferenceLines = new int[mSpans.length];
+            }
+            for (int i = 0; i < spanCount; i++) {
+                // does not matter start or end since this is only recorded when span is reset
+                mSpanReferenceLines[i] = spans[i].getStartLine(Span.INVALID_LINE);
+            }
         }
 
         void assignCoordinateFromPadding() {
diff --git a/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java b/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java
index f01a382..90f3a6f 100644
--- a/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java
+++ b/v7/recyclerview/src/android/support/v7/widget/ViewInfoStore.java
@@ -34,9 +34,7 @@
 import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_PRE;
 import static android.support.v7.widget.ViewInfoStore.InfoRecord.FLAG_POST;
 /**
- * This class abstracts all tracking for Views to run animations
- *
- * @hide
+ * This class abstracts all tracking for Views to run animations.
  */
 class ViewInfoStore {
 
diff --git a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java b/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java
index 5bbc458..cce7161 100644
--- a/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java
+++ b/v7/recyclerview/src/android/support/v7/widget/helper/ItemTouchHelper.java
@@ -142,19 +142,19 @@
      */
     public static final int ANIMATION_TYPE_DRAG = 1 << 3;
 
-    private static final String TAG = "ItemTouchHelper";
+    static final String TAG = "ItemTouchHelper";
 
-    private static final boolean DEBUG = false;
+    static final boolean DEBUG = false;
 
-    private static final int ACTIVE_POINTER_ID_NONE = -1;
+    static final int ACTIVE_POINTER_ID_NONE = -1;
 
-    private static final int DIRECTION_FLAG_COUNT = 8;
+    static final int DIRECTION_FLAG_COUNT = 8;
 
     private static final int ACTION_MODE_IDLE_MASK = (1 << DIRECTION_FLAG_COUNT) - 1;
 
-    private static final int ACTION_MODE_SWIPE_MASK = ACTION_MODE_IDLE_MASK << DIRECTION_FLAG_COUNT;
+    static final int ACTION_MODE_SWIPE_MASK = ACTION_MODE_IDLE_MASK << DIRECTION_FLAG_COUNT;
 
-    private static final int ACTION_MODE_DRAG_MASK = ACTION_MODE_SWIPE_MASK << DIRECTION_FLAG_COUNT;
+    static final int ACTION_MODE_DRAG_MASK = ACTION_MODE_SWIPE_MASK << DIRECTION_FLAG_COUNT;
 
     /**
      * The unit we are using to track velocity
@@ -245,13 +245,13 @@
 
     private int mSlop;
 
-    private RecyclerView mRecyclerView;
+    RecyclerView mRecyclerView;
 
     /**
      * When user drags a view to the edge, we start scrolling the LayoutManager as long as View
      * is partially out of bounds.
      */
-    private final Runnable mScrollRunnable = new Runnable() {
+    final Runnable mScrollRunnable = new Runnable() {
         @Override
         public void run() {
             if (mSelected != null && scrollIfNecessary()) {
@@ -267,7 +267,7 @@
     /**
      * Used for detecting fling swipe
      */
-    private VelocityTracker mVelocityTracker;
+    VelocityTracker mVelocityTracker;
 
     //re-used list for selecting a swap target
     private List<ViewHolder> mSwapTargets;
@@ -285,19 +285,19 @@
      * until view reaches its final position (end of recover animation), we keep a reference so
      * that it can be drawn above other children.
      */
-    private View mOverdrawChild = null;
+    View mOverdrawChild = null;
 
     /**
      * We cache the position of the overdraw child to avoid recalculating it each time child
      * position callback is called. This value is invalidated whenever a child is attached or
      * detached.
      */
-    private int mOverdrawChildPosition = -1;
+    int mOverdrawChildPosition = -1;
 
     /**
      * Used to detect long press.
      */
-    private GestureDetectorCompat mGestureDetector;
+    GestureDetectorCompat mGestureDetector;
 
     private final OnItemTouchListener mOnItemTouchListener
             = new OnItemTouchListener() {
@@ -549,7 +549,7 @@
      *                    current action
      * @param actionState The type of action
      */
-    private void select(ViewHolder selected, int actionState) {
+    void select(ViewHolder selected, int actionState) {
         if (selected == mSelected && actionState == mActionState) {
             return;
         }
@@ -669,7 +669,7 @@
         mRecyclerView.invalidate();
     }
 
-    private void postDispatchSwipe(final RecoverAnimation anim, final int swipeDir) {
+    void postDispatchSwipe(final RecoverAnimation anim, final int swipeDir) {
         // wait until animations are complete.
         mRecyclerView.post(new Runnable() {
             @Override
@@ -692,7 +692,7 @@
         });
     }
 
-    private boolean hasRunningRecoverAnim() {
+    boolean hasRunningRecoverAnim() {
         final int size = mRecoverAnimations.size();
         for (int i = 0; i < size; i++) {
             if (!mRecoverAnimations.get(i).mEnded) {
@@ -705,7 +705,7 @@
     /**
      * If user drags the view to the edge, trigger a scroll if necessary.
      */
-    private boolean scrollIfNecessary() {
+    boolean scrollIfNecessary() {
         if (mSelected == null) {
             mDragScrollStartTimeInMs = Long.MIN_VALUE;
             return false;
@@ -820,7 +820,7 @@
     /**
      * Checks if we should swap w/ another view holder.
      */
-    private void moveIfNecessary(ViewHolder viewHolder) {
+    void moveIfNecessary(ViewHolder viewHolder) {
         if (mRecyclerView.isLayoutRequested()) {
             return;
         }
@@ -880,7 +880,7 @@
     /**
      * Returns the animation type or 0 if cannot be found.
      */
-    private int endRecoverAnimation(ViewHolder viewHolder, boolean override) {
+    int endRecoverAnimation(ViewHolder viewHolder, boolean override) {
         final int recoverAnimSize = mRecoverAnimations.size();
         for (int i = recoverAnimSize - 1; i >= 0; i--) {
             final RecoverAnimation anim = mRecoverAnimations.get(i);
@@ -902,7 +902,7 @@
         outRect.setEmpty();
     }
 
-    private void obtainVelocityTracker() {
+    void obtainVelocityTracker() {
         if (mVelocityTracker != null) {
             mVelocityTracker.recycle();
         }
@@ -945,7 +945,7 @@
     /**
      * Checks whether we should select a View for swiping.
      */
-    private boolean checkSelectForSwipe(int action, MotionEvent motionEvent, int pointerIndex) {
+    boolean checkSelectForSwipe(int action, MotionEvent motionEvent, int pointerIndex) {
         if (mSelected != null || action != MotionEvent.ACTION_MOVE
                 || mActionState == ACTION_STATE_DRAG || !mCallback.isItemViewSwipeEnabled()) {
             return false;
@@ -1003,7 +1003,7 @@
         return true;
     }
 
-    private View findChildView(MotionEvent event) {
+    View findChildView(MotionEvent event) {
         // first check elevated views, if none, then call RV
         final float x = event.getX();
         final float y = event.getY();
@@ -1119,7 +1119,7 @@
         select(viewHolder, ACTION_STATE_SWIPE);
     }
 
-    private RecoverAnimation findAnimation(MotionEvent event) {
+    RecoverAnimation findAnimation(MotionEvent event) {
         if (mRecoverAnimations.isEmpty()) {
             return null;
         }
@@ -1133,7 +1133,7 @@
         return null;
     }
 
-    private void updateDxDy(MotionEvent ev, int directionFlags, int pointerIndex) {
+    void updateDxDy(MotionEvent ev, int directionFlags, int pointerIndex) {
         final float x = ev.getX(pointerIndex);
         final float y = ev.getY(pointerIndex);
 
@@ -1283,7 +1283,7 @@
         mRecyclerView.setChildDrawingOrderCallback(mChildDrawingOrderCallback);
     }
 
-    private void removeChildDrawingOrderCallbackIfNecessary(View view) {
+    void removeChildDrawingOrderCallbackIfNecessary(View view) {
         if (view == mOverdrawChild) {
             mOverdrawChild = null;
             // only remove if we've added
@@ -1569,12 +1569,12 @@
             return convertToAbsoluteDirection(flags, ViewCompat.getLayoutDirection(recyclerView));
         }
 
-        private boolean hasDragFlag(RecyclerView recyclerView, ViewHolder viewHolder) {
+        boolean hasDragFlag(RecyclerView recyclerView, ViewHolder viewHolder) {
             final int flags = getAbsoluteMovementFlags(recyclerView, viewHolder);
             return (flags & ACTION_MODE_DRAG_MASK) != 0;
         }
 
-        private boolean hasSwipeFlag(RecyclerView recyclerView,
+        boolean hasSwipeFlag(RecyclerView recyclerView,
                 ViewHolder viewHolder) {
             final int flags = getAbsoluteMovementFlags(recyclerView, viewHolder);
             return (flags & ACTION_MODE_SWIPE_MASK) != 0;
@@ -1940,7 +1940,7 @@
             }
         }
 
-        private void onDraw(Canvas c, RecyclerView parent, ViewHolder selected,
+        void onDraw(Canvas c, RecyclerView parent, ViewHolder selected,
                 List<ItemTouchHelper.RecoverAnimation> recoverAnimationList,
                 int actionState, float dX, float dY) {
             final int recoverAnimSize = recoverAnimationList.size();
@@ -1959,7 +1959,7 @@
             }
         }
 
-        private void onDrawOver(Canvas c, RecyclerView parent, ViewHolder selected,
+        void onDrawOver(Canvas c, RecyclerView parent, ViewHolder selected,
                 List<ItemTouchHelper.RecoverAnimation> recoverAnimationList,
                 int actionState, float dX, float dY) {
             final int recoverAnimSize = recoverAnimationList.size();
@@ -2256,6 +2256,9 @@
 
     private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
 
+        ItemTouchHelperGestureListener() {
+        }
+
         @Override
         public boolean onDown(MotionEvent e) {
             return true;
@@ -2310,7 +2313,7 @@
 
         private final ValueAnimatorCompat mValueAnimator;
 
-        private final int mAnimationType;
+        final int mAnimationType;
 
         public boolean mIsPendingCleanup;
 
@@ -2322,7 +2325,7 @@
         // instantly.
         boolean mOverridden = false;
 
-        private boolean mEnded = false;
+        boolean mEnded = false;
 
         private float mFraction;
 
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BaseGridLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BaseGridLayoutManagerTest.java
index 34b6621..3a72152 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseGridLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseGridLayoutManagerTest.java
@@ -17,6 +17,7 @@
 
 import android.content.Context;
 import android.view.View;
+import android.view.ViewGroup;
 
 import java.lang.reflect.Field;
 import java.util.ArrayList;
@@ -46,7 +47,7 @@
     }
 
     public RecyclerView setupBasic(Config config, GridTestAdapter testAdapter) throws Throwable {
-        RecyclerView recyclerView = new RecyclerView(getActivity());
+        RecyclerView recyclerView = new WrappedRecyclerView(getActivity());
         mAdapter = testAdapter;
         mGlm = new WrappedGridLayoutManager(getActivity(), config.mSpanCount, config.mOrientation,
                 config.mReverseLayout);
@@ -149,6 +150,8 @@
 
         CountDownLatch mLayoutLatch;
 
+        CountDownLatch prefetchLatch;
+
         List<GridLayoutManagerTest.Callback>
                 mCallbacks = new ArrayList<GridLayoutManagerTest.Callback>();
 
@@ -227,6 +230,23 @@
             });
         }
 
+        public void expectPrefetch(int count) {
+            prefetchLatch = new CountDownLatch(count);
+        }
+
+        public void waitForPrefetch(int seconds) throws Throwable {
+            prefetchLatch.await(seconds * (DEBUG ? 100 : 1), SECONDS);
+            checkForMainThreadException();
+            MatcherAssert.assertThat("all prefetches should complete on time",
+                    prefetchLatch.getCount(), CoreMatchers.is(0L));
+            // use a runnable to ensure RV layout is finished
+            getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                }
+            });
+        }
+
         public void expectIdleState(int count) {
             snapLatch = new CountDownLatch(count);
             mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@@ -255,6 +275,12 @@
                 }
             });
         }
+
+        @Override
+        int gatherPrefetchIndices(int dx, int dy, RecyclerView.State state, int[] outIndices) {
+            if (prefetchLatch != null) prefetchLatch.countDown();
+            return super.gatherPrefetchIndices(dx, dy, state, outIndices);
+        }
     }
 
     class GridTestAdapter extends TestAdapter {
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BaseLinearLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BaseLinearLayoutManagerTest.java
index 353e84e..50c9ba3 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseLinearLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseLinearLayoutManagerTest.java
@@ -345,6 +345,8 @@
 
         CountDownLatch snapLatch;
 
+        CountDownLatch prefetchLatch;
+
         OrientationHelper mSecondaryOrientation;
 
         OnLayoutListener mOnLayoutListener;
@@ -370,6 +372,23 @@
             });
         }
 
+        public void expectPrefetch(int count) {
+            prefetchLatch = new CountDownLatch(count);
+        }
+
+        public void waitForPrefetch(int seconds) throws Throwable {
+            prefetchLatch.await(seconds * (DEBUG ? 100 : 1), SECONDS);
+            checkForMainThreadException();
+            MatcherAssert.assertThat("all prefetches should complete on time",
+                    prefetchLatch.getCount(), CoreMatchers.is(0L));
+            // use a runnable to ensure RV layout is finished
+            getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                }
+            });
+        }
+
         public void expectIdleState(int count) {
             snapLatch = new CountDownLatch(count);
             mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@@ -576,5 +595,11 @@
             }
             layoutLatch.countDown();
         }
+
+        @Override
+        int gatherPrefetchIndices(int dx, int dy, RecyclerView.State state, int[] outIndices) {
+            if (prefetchLatch != null) prefetchLatch.countDown();
+            return super.gatherPrefetchIndices(dx, dy, state, outIndices);
+        }
     }
 }
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BaseStaggeredGridLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BaseStaggeredGridLayoutManagerTest.java
index 82f8cf0..d872eca 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseStaggeredGridLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseStaggeredGridLayoutManagerTest.java
@@ -81,11 +81,10 @@
 
     void setupByConfig(Config config, GridTestAdapter adapter) throws Throwable {
         mAdapter = adapter;
-        mRecyclerView = new RecyclerView(getActivity());
+        mRecyclerView = new WrappedRecyclerView(getActivity());
         mRecyclerView.setAdapter(mAdapter);
         mRecyclerView.setHasFixedSize(true);
-        mLayoutManager = new WrappedLayoutManager(config.mSpanCount,
-                config.mOrientation);
+        mLayoutManager = new WrappedLayoutManager(config.mSpanCount, config.mOrientation);
         mLayoutManager.setGapStrategy(config.mGapStrategy);
         mLayoutManager.setReverseLayout(config.mReverseLayout);
         mRecyclerView.setLayoutManager(mLayoutManager);
@@ -470,12 +469,13 @@
     class WrappedLayoutManager extends StaggeredGridLayoutManager {
 
         CountDownLatch layoutLatch;
+        CountDownLatch prefetchLatch;
         OnLayoutListener mOnLayoutListener;
         // gradle does not yet let us customize manifest for tests which is necessary to test RTL.
         // until bug is fixed, we'll fake it.
         // public issue id: 57819
         Boolean mFakeRTL;
-        CountDownLatch snapLatch;
+        CountDownLatch mSnapLatch;
 
         @Override
         boolean isLayoutRTL() {
@@ -499,15 +499,32 @@
             });
         }
 
+        public void expectPrefetch(int count) {
+            prefetchLatch = new CountDownLatch(count);
+        }
+
+        public void waitForPrefetch(int seconds) throws Throwable {
+            prefetchLatch.await(seconds * (DEBUG ? 100 : 1), SECONDS);
+            checkForMainThreadException();
+            MatcherAssert.assertThat("all prefetches should complete on time",
+                    prefetchLatch.getCount(), CoreMatchers.is(0L));
+            // use a runnable to ensure RV layout is finished
+            getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                }
+            });
+        }
+
         public void expectIdleState(int count) {
-            snapLatch = new CountDownLatch(count);
+            mSnapLatch = new CountDownLatch(count);
             mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                 @Override
                 public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                     super.onScrollStateChanged(recyclerView, newState);
                     if (newState == RecyclerView.SCROLL_STATE_IDLE) {
-                        snapLatch.countDown();
-                        if (snapLatch.getCount() == 0L) {
+                        mSnapLatch.countDown();
+                        if (mSnapLatch.getCount() == 0L) {
                             mRecyclerView.removeOnScrollListener(this);
                         }
                     }
@@ -516,10 +533,10 @@
         }
 
         public void waitForSnap(int seconds) throws Throwable {
-            snapLatch.await(seconds * (DEBUG ? 100 : 1), SECONDS);
+            mSnapLatch.await(seconds * (DEBUG ? 100 : 1), SECONDS);
             checkForMainThreadException();
             MatcherAssert.assertThat("all scrolling should complete on time",
-                    snapLatch.getCount(), CoreMatchers.is(0L));
+                    mSnapLatch.getCount(), CoreMatchers.is(0L));
             // use a runnable to ensure RV layout is finished
             getInstrumentation().runOnMainSync(new Runnable() {
                 @Override
@@ -786,6 +803,12 @@
                 }
             }
         }
+
+        @Override
+        int gatherPrefetchIndices(int dx, int dy, RecyclerView.State state, int[] outIndices) {
+            if (prefetchLatch != null) prefetchLatch.countDown();
+            return super.gatherPrefetchIndices(dx, dy, state, outIndices);
+        }
     }
 
     class GridTestAdapter extends TestAdapter {
@@ -854,6 +877,7 @@
                         / AVG_ITEM_PER_VIEW : mRecyclerViewHeight / AVG_ITEM_PER_VIEW;
             }
             super.onBindViewHolder(holder, position);
+
             Item item = mItems.get(position);
             RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) holder.itemView
                     .getLayoutParams();
@@ -862,8 +886,8 @@
                         .setFullSpan(mFullSpanItems.contains(item.mAdapterIndex));
             } else {
                 StaggeredGridLayoutManager.LayoutParams slp
-                        = (StaggeredGridLayoutManager.LayoutParams) mLayoutManager
-                        .generateDefaultLayoutParams();
+                    = (StaggeredGridLayoutManager.LayoutParams) mLayoutManager
+                    .generateDefaultLayoutParams();
                 holder.itemView.setLayoutParams(slp);
                 slp.setFullSpan(mFullSpanItems.contains(item.mAdapterIndex));
                 lp = slp;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BaseWrapContentTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BaseWrapContentTest.java
index 281745c..2dd16ef 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BaseWrapContentTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BaseWrapContentTest.java
@@ -501,43 +501,6 @@
         return true;
     }
 
-    static class WrappedRecyclerView extends RecyclerView {
-
-        public WrappedRecyclerView(Context context) {
-            super(context);
-        }
-
-        public void waitUntilLayout() {
-            while (isLayoutRequested()) {
-                try {
-                    Thread.sleep(100);
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
-                }
-            }
-        }
-
-        public void waitUntilAnimations() throws InterruptedException {
-            final CountDownLatch latch = new CountDownLatch(1);
-            if (mItemAnimator == null || !mItemAnimator.isRunning(
-                    new ItemAnimator.ItemAnimatorFinishedListener() {
-                        @Override
-                        public void onAnimationsFinished() {
-                            latch.countDown();
-                        }
-                    })) {
-                latch.countDown();
-            }
-            MatcherAssert.assertThat("waiting too long for animations",
-                    latch.await(60, TimeUnit.SECONDS), CoreMatchers.is(true));
-        }
-
-        @Override
-        protected void onLayout(boolean changed, int l, int t, int r, int b) {
-            super.onLayout(changed, l, t, r, b);
-        }
-    }
-
     static class WrapContentConfig {
 
         public boolean unlimitedWidth;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/BucketTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/BucketTest.java
index 0db69f1..3f90a1a 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/BucketTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/BucketTest.java
@@ -16,20 +16,21 @@
 
 package android.support.v7.widget;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
 
-import android.support.test.runner.AndroidJUnit4;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
-import static org.junit.Assert.*;
 
 @SmallTest
 @RunWith(JUnit4.class)
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/ChildHelperTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/ChildHelperTest.java
index 47a34db..4dcd6a7 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/ChildHelperTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/ChildHelperTest.java
@@ -16,31 +16,36 @@
 
 package android.support.v7.widget;
 
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
+import android.content.Context;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
-import android.test.AndroidTestCase;
-import android.test.mock.MockContext;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.View;
 import android.view.ViewGroup;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.ArrayList;
 import java.util.List;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class ChildHelperTest extends AndroidTestCase {
+public class ChildHelperTest {
     LoggingCallback  mLoggingCallback;
     ChildHelper mChildHelper;
+    Context mContext;
 
     @Before
-    public void prepare() throws Exception {
-        setUp();
-        setContext(InstrumentationRegistry.getContext());
+    public void setup() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
         mLoggingCallback = new LoggingCallback();
         mChildHelper = new ChildHelper(mLoggingCallback);
     }
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerCacheTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerCacheTest.java
new file mode 100644
index 0000000..6819a6a
--- /dev/null
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerCacheTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.widget;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
+import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(Parameterized.class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
+public class GridLayoutManagerCacheTest extends BaseGridLayoutManagerTest {
+
+    final Config mConfig;
+    final int mDx;
+    final int mDy;
+
+    public GridLayoutManagerCacheTest(Config config, int dx, int dy) {
+        mConfig = config;
+        mDx = dx;
+        mDy = dy;
+    }
+
+    @Parameterized.Parameters(name = "config:{0}, dx:{1}, dy:{2}")
+    public static List<Object[]> getParams() {
+        List<Object[]> result = new ArrayList<>();
+        List<Config> configs = createBaseVariations();
+        for (Config config : configs) {
+            for (int dx : new int[] {-1, 0, 1}) {
+                for (int dy : new int[] {-1, 0, 1}) {
+                    result.add(new Object[]{config, dx, dy});
+                }
+            }
+        }
+        return result;
+    }
+
+    private ArrayList<RecyclerView.ViewHolder> cachedViews() {
+        return mRecyclerView.mRecycler.mCachedViews;
+    }
+
+    private boolean cachedViewsContains(int position) {
+        // Note: can't make assumptions about order here, so just check all cached views
+        for (int i = 0; i < cachedViews().size(); i++) {
+            if (cachedViews().get(i).getAdapterPosition() == position) return true;
+        }
+        return false;
+    }
+
+    @MediumTest
+    @Test
+    public void cacheAndPrefetch() throws Throwable {
+        final Config config = (Config) mConfig.clone();
+        RecyclerView recyclerView = setupBasic(config);
+        waitForFirstLayout(recyclerView);
+
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // pretend to have an extra 5s before next frame so prefetch won't abort early
+                ((WrappedRecyclerView)mRecyclerView).setDrawingTimeOffset(5000);
+
+                // scroll to the middle, so we can move in either direction
+                mRecyclerView.scrollToPosition(mConfig.mItemCount / 2);
+            }
+        });
+
+        mRecyclerView.setItemViewCacheSize(0);
+        {
+            mGlm.expectPrefetch(1);
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mRecyclerView.mRecycler.recycleAndClearCachedViews();
+                    mRecyclerView.mViewPrefetcher.postFromTraversal(mDx, mDy);
+
+                    // Lie about post time, so prefetch executes even if it is delayed
+                    mRecyclerView.mViewPrefetcher.mPostTimeNanos += TimeUnit.SECONDS.toNanos(5);
+                }
+            });
+            mGlm.waitForPrefetch(1);
+        }
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // validate cache state on UI thread
+                if ((config.mOrientation == HORIZONTAL && mDx == 0)
+                        || (config.mOrientation == VERTICAL && mDy == 0)) {
+                    assertEquals(0, cachedViews().size());
+                } else {
+                    assertEquals(config.mSpanCount, cachedViews().size());
+
+                    boolean reverseScroll = config.mOrientation == HORIZONTAL ? mDx < 0 : mDy < 0;
+                    int lastVisibleItemPosition = mGlm.findLastVisibleItemPosition();
+                    int firstVisibleItemPosition = mGlm.findFirstVisibleItemPosition();
+
+                    for (int i = 0; i < config.mSpanCount; i++) {
+                        if (mConfig.mReverseLayout == reverseScroll) {
+                            // Pos scroll on pos layout, or reverse scroll on reverse layout
+                            // = toward last
+                            assertTrue(cachedViewsContains(lastVisibleItemPosition + 1 + i));
+                        } else {
+                            // Pos scroll on reverse layout, or reverse scroll on pos layout
+                            // = toward first
+                            assertTrue(cachedViewsContains(firstVisibleItemPosition - 1 - i));
+                        }
+                    }
+                }
+            }
+        });
+    }
+}
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerWrapContentWithAspectRatioTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerWrapContentWithAspectRatioTest.java
index d33611c..6c311e4 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerWrapContentWithAspectRatioTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/GridLayoutManagerWrapContentWithAspectRatioTest.java
@@ -78,7 +78,7 @@
 
     RecyclerView.LayoutManager mLayoutManager;
 
-    BaseWrapContentTest.WrappedRecyclerView mRecyclerView;
+    WrappedRecyclerView mRecyclerView;
 
     OrientationHelper mHelper;
 
@@ -102,7 +102,7 @@
         }
         mLayoutManager = createFromConfig();
 
-        mRecyclerView = new BaseWrapContentTest.WrappedRecyclerView(getActivity());
+        mRecyclerView = new WrappedRecyclerView(getActivity());
         mHelper = OrientationHelper.createOrientationHelper(
                 mLayoutManager, 1 - mConfig.mOrientation);
 
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerCacheTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerCacheTest.java
new file mode 100644
index 0000000..cacc9f4
--- /dev/null
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerCacheTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.v7.widget;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.FrameLayout;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
+import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
+import static org.junit.Assert.assertEquals;
+
+@RunWith(Parameterized.class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
+public class LinearLayoutManagerCacheTest extends BaseLinearLayoutManagerTest {
+
+    final Config mConfig;
+    final int mDx;
+    final int mDy;
+
+    public LinearLayoutManagerCacheTest(Config config, int dx, int dy) {
+        mConfig = config;
+        mDx = dx;
+        mDy = dy;
+    }
+
+    @Parameterized.Parameters(name = "config:{0}, dx:{1}, dy:{2}")
+    public static List<Object[]> getParams() {
+        List<Object[]> result = new ArrayList<>();
+        List<Config> configs = createBaseVariations();
+        for (Config config : configs) {
+            for (int dx : new int[] {-1, 0, 1}) {
+                for (int dy : new int[] {-1, 0, 1}) {
+                    result.add(new Object[]{config, dx, dy});
+                }
+            }
+        }
+        return result;
+    }
+
+    private ArrayList<RecyclerView.ViewHolder> cachedViews() {
+        return mRecyclerView.mRecycler.mCachedViews;
+    }
+
+    @MediumTest
+    @Test
+    public void cacheAndPrefetch() throws Throwable {
+        final Config config = (Config) mConfig.clone();
+
+        setupByConfig(config, true);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // pretend to have an extra 5s before next frame so prefetch won't abort early
+                ((WrappedRecyclerView)mRecyclerView).setDrawingTimeOffset(5000);
+
+                mRecyclerView.scrollToPosition(100);
+            }
+        });
+
+        mRecyclerView.setItemViewCacheSize(0);
+        {
+            mLayoutManager.expectPrefetch(1);
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mRecyclerView.mRecycler.recycleAndClearCachedViews();
+                    mRecyclerView.mViewPrefetcher.postFromTraversal(mDx, mDy);
+
+                    // Lie about post time, so prefetch executes even if it is delayed
+                    mRecyclerView.mViewPrefetcher.mPostTimeNanos += TimeUnit.SECONDS.toNanos(5);
+                }
+            });
+            mLayoutManager.waitForPrefetch(1);
+        }
+
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // validate cache state on UI thread
+                if ((config.mOrientation == HORIZONTAL && mDx == 0)
+                        || (config.mOrientation == VERTICAL && mDy == 0)) {
+                    assertEquals(0, cachedViews().size());
+                } else {
+                    boolean reverseScroll = config.mOrientation == HORIZONTAL ? mDx < 0 : mDy < 0;
+                    int lastVisibleItemPosition = mLayoutManager.findLastVisibleItemPosition();
+                    int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition();
+                    assertEquals(1, cachedViews().size());
+                    int prefetchedPosition = cachedViews().get(0).getAdapterPosition();
+                    if (mConfig.mReverseLayout == reverseScroll) {
+                        // Pos scroll on pos layout, or reverse scroll on reverse layout = toward last
+                        assertEquals(lastVisibleItemPosition + 1, prefetchedPosition);
+                    } else {
+                        // Pos scroll on reverse layout, or reverse scroll on pos layout = toward first
+                        assertEquals(firstVisibleItemPosition - 1, prefetchedPosition);
+                    }
+                }
+            }
+        });
+    }
+}
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerWrapContentWithAspectRatioTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerWrapContentWithAspectRatioTest.java
index 2bb0750..185aa4b 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerWrapContentWithAspectRatioTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerWrapContentWithAspectRatioTest.java
@@ -122,8 +122,8 @@
         }
 
         RecyclerView.LayoutManager layoutManager = createFromConfig();
-        BaseWrapContentTest.WrappedRecyclerView
-                recyclerView = new BaseWrapContentTest.WrappedRecyclerView(getActivity());
+        WrappedRecyclerView
+                recyclerView = new WrappedRecyclerView(getActivity());
         recyclerView.setBackgroundColor(Color.rgb(0, 0, 255));
         recyclerView.setLayoutManager(layoutManager);
         recyclerView.setLayoutParams(wrapContent);
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewBasicTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewBasicTest.java
index b232271..97f9b92 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewBasicTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewBasicTest.java
@@ -16,18 +16,22 @@
 
 package android.support.v7.widget;
 
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
 
-import android.app.Instrumentation;
 import android.content.Context;
+import android.os.Build;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SdkSuppress;
 import android.support.test.runner.AndroidJUnit4;
-import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.AttributeSet;
 import android.util.SparseArray;
@@ -36,10 +40,13 @@
 import android.view.ViewGroup;
 import android.widget.TextView;
 
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
-import static org.junit.Assert.*;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -309,7 +316,6 @@
         layout();
     }
 
-
     @Test
     public void dontSaveChildrenState() throws InterruptedException {
         MockLayoutManager mlm = new MockLayoutManager() {
@@ -343,6 +349,21 @@
                 loggingView.getOnSavedInstanceCnt());
     }
 
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
+    @Test
+    public void prefetchChangesCacheSize() {
+        MockLayoutManager mlm = new MockLayoutManager() {
+            @Override
+            int getItemPrefetchCount() {
+                return 3;
+            }
+        };
+        RecyclerView.Recycler recycler = mRecyclerView.mRecycler;
+        assertEquals(RecyclerView.Recycler.DEFAULT_CACHE_SIZE, recycler.mViewCacheMax);
+        mRecyclerView.setLayoutManager(mlm);
+        assertEquals(RecyclerView.Recycler.DEFAULT_CACHE_SIZE + 3, recycler.mViewCacheMax);
+    }
+
     static class MockLayoutManager extends RecyclerView.LayoutManager {
 
         int mLayoutCount = 0;
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewPrefetchTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewPrefetchTest.java
new file mode 100644
index 0000000..e397b6e
--- /dev/null
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/RecyclerViewPrefetchTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.v7.widget;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@SmallTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
+@RunWith(AndroidJUnit4.class)
+public class RecyclerViewPrefetchTest extends BaseRecyclerViewInstrumentationTest {
+    private class PrefetchLayoutManager extends TestLayoutManager {
+        CountDownLatch prefetchLatch = new CountDownLatch(1);
+
+        @Override
+        public boolean canScrollVertically() {
+            return true;
+        }
+
+        @Override
+        public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+            super.onLayoutChildren(recycler, state);
+            detachAndScrapAttachedViews(recycler);
+            layoutRange(recycler, 0, 5);
+        }
+
+        @Override
+        public void onLayoutCompleted(RecyclerView.State state) {
+            super.onLayoutCompleted(state);
+            layoutLatch.countDown();
+        }
+
+        @Override
+        int getItemPrefetchCount() {
+            return 1;
+        }
+
+        @Override
+        int gatherPrefetchIndices(int dx, int dy, RecyclerView.State state, int[] outIndices) {
+            prefetchLatch.countDown();
+            outIndices[0] = 6;
+            return 1;
+        }
+
+        void waitForPrefetch(int time) throws InterruptedException {
+            assertThat(prefetchLatch.await(time, TimeUnit.SECONDS),
+                    is(true));
+            getInstrumentation().runOnMainSync(new Runnable() {
+                @Override
+                public void run() {
+                }
+            });
+        }
+    }
+
+    private ArrayList<RecyclerView.ViewHolder> cachedViews() {
+        return mRecyclerView.mRecycler.mCachedViews;
+    }
+
+    @Test
+    public void prefetchTest() throws Throwable {
+        RecyclerView recyclerView = new RecyclerView(getActivity());
+        recyclerView.setAdapter(new TestAdapter(50));
+        PrefetchLayoutManager layout = new PrefetchLayoutManager();
+        recyclerView.setLayoutManager(layout);
+
+        {
+            layout.expectLayouts(1);
+            setRecyclerView(recyclerView);
+            layout.waitForLayout(10);
+        }
+
+        assertThat(layout.prefetchLatch.getCount(), is(1L)); // shouldn't have fired yet
+        assertThat(cachedViews().size(), is(0));
+        smoothScrollBy(50);
+
+        layout.waitForPrefetch(10);
+        assertThat(cachedViews().size(), is(1));
+        assertThat(cachedViews().get(0).getAdapterPosition(), is(6));
+    }
+}
\ No newline at end of file
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerBaseConfigSetTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerBaseConfigSetTest.java
index f8d11d8..71484dd 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerBaseConfigSetTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerBaseConfigSetTest.java
@@ -304,9 +304,9 @@
                 final String boundsLog = mLayoutManager.getBoundsLog();
                 VisibleChildren queryResult = new VisibleChildren(mLayoutManager.getSpanCount());
                 queryResult.findFirstPartialVisibleClosestToStart = mLayoutManager
-                        .findFirstVisibleItemClosestToStart(false, true);
+                        .findFirstVisibleItemClosestToStart(false);
                 queryResult.findFirstPartialVisibleClosestToEnd = mLayoutManager
-                        .findFirstVisibleItemClosestToEnd(false, true);
+                        .findFirstVisibleItemClosestToEnd(false);
                 queryResult.firstFullyVisiblePositions = mLayoutManager
                         .findFirstCompletelyVisibleItemPositions(
                                 provideArr ? new int[mLayoutManager.getSpanCount()] : null);
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerCacheTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerCacheTest.java
new file mode 100644
index 0000000..e11a576
--- /dev/null
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerCacheTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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.v7.widget;
+
+import android.os.Build;
+import android.support.test.filters.SdkSuppress;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import static android.support.v7.widget.LinearLayoutManager.HORIZONTAL;
+import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+@RunWith(Parameterized.class)
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.LOLLIPOP)
+public class StaggeredGridLayoutManagerCacheTest extends BaseStaggeredGridLayoutManagerTest {
+
+    final Config mConfig;
+    final int mDx;
+    final int mDy;
+
+    public StaggeredGridLayoutManagerCacheTest(Config config, int dx, int dy) {
+        mConfig = config;
+        mDx = dx;
+        mDy = dy;
+    }
+
+    @Parameterized.Parameters(name = "config:{0}, dx:{1}, dy: {2}")
+    public static List<Object[]> getParams() {
+        List<Object[]> result = new ArrayList<>();
+        List<Config> configs = createBaseVariations();
+        for (Config config : configs) {
+            for (int dx : new int[] {-1, 0, 1}) {
+                for (int dy : new int[] {-1, 0, 1}) {
+                    result.add(new Object[]{config, dx, dy});
+                }
+            }
+        }
+        return result;
+    }
+
+    private ArrayList<RecyclerView.ViewHolder> cachedViews() {
+        return mRecyclerView.mRecycler.mCachedViews;
+    }
+
+    private boolean cachedViewsContains(int position) {
+        // Note: can't make assumptions about order here, so just check all cached views
+        for (int i = 0; i < cachedViews().size(); i++) {
+            if (cachedViews().get(i).getAdapterPosition() == position) return true;
+        }
+        return false;
+    }
+
+    public int findFirstVisibleItemPosition() {
+        int[] positions = new int[mConfig.mSpanCount];
+        mLayoutManager.findFirstVisibleItemPositions(positions);
+        Arrays.sort(positions);
+        return positions[0];
+    }
+
+    public int findLastVisibleItemPosition() {
+        int[] positions = new int[mConfig.mSpanCount];
+        mLayoutManager.findLastVisibleItemPositions(positions);
+        Arrays.sort(positions);
+        return positions[mConfig.mSpanCount - 1];
+    }
+
+    @MediumTest
+    @Test
+    public void cacheAndPrefetch() throws Throwable {
+        final Config config = (Config) mConfig.clone();
+        setupByConfig(config);
+        waitFirstLayout();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // pretend to have an extra 5s before next frame so prefetch won't abort early
+                ((WrappedRecyclerView)mRecyclerView).setDrawingTimeOffset(5000);
+
+                // scroll to the middle, so we can move in either direction
+                mRecyclerView.scrollToPosition(mConfig.mItemCount / 2);
+            }
+        });
+
+        mRecyclerView.setItemViewCacheSize(0);
+        {
+            mLayoutManager.expectPrefetch(1);
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mRecyclerView.mRecycler.recycleAndClearCachedViews();
+                    mRecyclerView.mViewPrefetcher.postFromTraversal(mDx, mDy);
+
+                    // Lie about post time, so prefetch executes even if it is delayed
+                    mRecyclerView.mViewPrefetcher.mPostTimeNanos += TimeUnit.SECONDS.toNanos(5);
+                }
+            });
+            mLayoutManager.waitForPrefetch(1);
+        }
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // validate cache state on UI thread
+                if ((config.mOrientation == HORIZONTAL && mDx == 0)
+                        || (config.mOrientation == VERTICAL && mDy == 0)) {
+                    assertEquals(0, cachedViews().size());
+                } else {
+                    assertEquals(config.mSpanCount, cachedViews().size());
+
+                    boolean reverseScroll = config.mOrientation == HORIZONTAL ? mDx < 0 : mDy < 0;
+                    int lastVisibleItemPosition = findLastVisibleItemPosition();
+                    int firstVisibleItemPosition = findFirstVisibleItemPosition();
+
+                    for (int i = 0; i < config.mSpanCount; i++) {
+                        if (mConfig.mReverseLayout == reverseScroll) {
+                            // Pos scroll on pos layout, or reverse scroll on reverse layout
+                            // = toward last
+                            assertTrue(cachedViewsContains(lastVisibleItemPosition + 1 + i));
+                        } else {
+                            // Pos scroll on reverse layout, or reverse scroll on pos layout
+                            // = toward first
+                            assertTrue(cachedViewsContains(firstVisibleItemPosition - 1 - i));
+                        }
+                    }
+                }
+            }
+        });
+    }
+}
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerSnappingTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerSnappingTest.java
index d4955d5..51b469d 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerSnappingTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerSnappingTest.java
@@ -62,6 +62,46 @@
 
     @MediumTest
     @Test
+    public void snapOnScrollSameViewFixedSize() throws Throwable {
+        // This test is a special case for fixed sized children.
+        final Config config = ((Config) mConfig.clone()).itemCount(10);
+        setupByConfig(config);
+        RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(1000, 950);
+        mRecyclerView.setLayoutParams(lp);
+        mAdapter.mOnBindCallback = new OnBindCallback() {
+            @Override
+            void onBoundItem(TestViewHolder vh, int position) {
+                StaggeredGridLayoutManager.LayoutParams slp = getLayoutParamsForPosition(position);
+                vh.itemView.setLayoutParams(slp);
+            }
+
+            @Override
+            boolean assignRandomSize() {
+                return false;
+            }
+        };
+        waitFirstLayout();
+        setupSnapHelper();
+
+        // Record the current center view.
+        View view = findCenterView(mLayoutManager);
+        assertCenterAligned(view);
+        // This number comes from the sizes of the fixed views that are created for this config/
+        // See getLayoutParamsForPosition(int) below. Obtained manually.
+        int scrollDistance = mLayoutManager.canScrollHorizontally() ? 52 : 52;
+        int scrollDist = mReverseScroll ? -scrollDistance : scrollDistance;
+        mLayoutManager.expectIdleState(2);
+        smoothScrollBy(scrollDist);
+        mLayoutManager.waitForSnap(10);
+
+        // Views have not changed
+        View viewAfterScroll = findCenterView(mLayoutManager);
+        assertSame("The view should NOT have scrolled", view, viewAfterScroll);
+        assertCenterAligned(viewAfterScroll);
+    }
+
+    @MediumTest
+    @Test
     public void snapOnScrollSameView() throws Throwable {
         final Config config = (Config) mConfig.clone();
         setupByConfig(config);
@@ -71,18 +111,18 @@
         // Record the current center view.
         View view = findCenterView(mLayoutManager);
         assertCenterAligned(view);
-        // For a staggered grid layout manager we need to keep the distance
+        // For a staggered grid layout manager with unknown item size we need to keep the distance
         // small enough to ensure we do not scroll over to an offset view in a different span.
-        int scrollDistance = 5;
+        int scrollDistance = findMinSafeScrollDistance();
         int scrollDist = mReverseScroll ? -scrollDistance : scrollDistance;
         mLayoutManager.expectIdleState(2);
         smoothScrollBy(scrollDist);
         mLayoutManager.waitForSnap(10);
 
         // Views have not changed
-        View viewAfterFling = findCenterView(mLayoutManager);
-        assertSame("The view should have scrolled", view, viewAfterFling);
-        assertCenterAligned(viewAfterFling);
+        View viewAfterScroll = findCenterView(mLayoutManager);
+        assertSame("The view should NOT have scrolled", view, viewAfterScroll);
+        assertCenterAligned(viewAfterScroll);
     }
 
     @Test
@@ -163,6 +203,21 @@
         assertCenterAligned(viewAfterFling);
     }
 
+    private StaggeredGridLayoutManager.LayoutParams getLayoutParamsForPosition(int position) {
+        // Only enabled fixed sizes if the config says so.
+        if (mLayoutManager.canScrollHorizontally()) {
+            int width = 400 + position * 70;
+            return new StaggeredGridLayoutManager.LayoutParams(width, 300);
+        } else {
+            int height = 300 + position * 70;
+            return new StaggeredGridLayoutManager.LayoutParams(300, height);
+        }
+    }
+
+    @Nullable View findCenterView(RecyclerView.LayoutManager layoutManager) {
+        return mLayoutManager.findFirstVisibleItemClosestToCenter();
+    }
+
     private void setupSnapHelper() throws Throwable {
         SnapHelper snapHelper = new LinearSnapHelper();
         mLayoutManager.expectIdleState(1);
@@ -174,7 +229,11 @@
         mLayoutManager.waitForLayout(2);
 
         View view = findCenterView(mLayoutManager);
-        int scrollDistance = (getViewDimension(view) / 2) + 10;
+        int scrollDistance = distFromCenter(view) / 2;
+        if (scrollDistance == 0) {
+            return;
+        }
+
         int scrollDist = mReverseScroll ? -scrollDistance : scrollDistance;
 
         mLayoutManager.expectIdleState(2);
@@ -182,10 +241,6 @@
         mLayoutManager.waitForSnap(10);
     }
 
-    @Nullable View findCenterView(RecyclerView.LayoutManager layoutManager) {
-        return mLayoutManager.findFirstVisibleItemClosestToCenter();
-    }
-
     private int getViewDimension(View view) {
         OrientationHelper helper;
         if (mLayoutManager.canScrollHorizontally()) {
@@ -206,6 +261,28 @@
         }
     }
 
+    private int findMinSafeScrollDistance() {
+        int minDist = Integer.MAX_VALUE;
+        for (int i = mLayoutManager.getChildCount() - 1; i >= 0; i--) {
+            final View child = mLayoutManager.getChildAt(i);
+            int dist = distFromCenter(child);
+            if (dist < minDist) {
+                minDist = dist;
+            }
+        }
+        return minDist / 2 - 1;
+    }
+
+    private int distFromCenter(View view) {
+        if (mLayoutManager.canScrollHorizontally()) {
+            return Math.abs(mRecyclerView.getWidth() / 2 -
+                    mLayoutManager.getViewBounds(view).centerX());
+        } else {
+            return Math.abs(mRecyclerView.getHeight() / 2 -
+                    mLayoutManager.getViewBounds(view).centerY());
+        }
+    }
+
     private boolean fling(final int velocityX, final int velocityY)
             throws Throwable {
         final AtomicBoolean didStart = new AtomicBoolean(false);
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
index 60149fb..18cae23 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/StaggeredGridLayoutManagerTest.java
@@ -135,17 +135,17 @@
         assertEquals("last completely visible item from span 1 should be 1", 1, into[1]);
         assertEquals("first fully visible child should be at position",
                 0, mRecyclerView.getChildViewHolder(mLayoutManager.
-                        findFirstVisibleItemClosestToStart(true, true)).getPosition());
+                        findFirstVisibleItemClosestToStart(true)).getPosition());
         assertEquals("last fully visible child should be at position",
                 4, mRecyclerView.getChildViewHolder(mLayoutManager.
-                        findFirstVisibleItemClosestToEnd(true, true)).getPosition());
+                        findFirstVisibleItemClosestToEnd(true)).getPosition());
 
         assertEquals("first visible child should be at position",
                 0, mRecyclerView.getChildViewHolder(mLayoutManager.
-                        findFirstVisibleItemClosestToStart(false, true)).getPosition());
+                        findFirstVisibleItemClosestToStart(false)).getPosition());
         assertEquals("last visible child should be at position",
                 4, mRecyclerView.getChildViewHolder(mLayoutManager.
-                        findFirstVisibleItemClosestToEnd(false, true)).getPosition());
+                        findFirstVisibleItemClosestToEnd(false)).getPosition());
 
     }
 
@@ -807,10 +807,10 @@
                 .asRecord(event);
         final int start = mRecyclerView
                 .getChildLayoutPosition(
-                        mLayoutManager.findFirstVisibleItemClosestToStart(false, true));
+                        mLayoutManager.findFirstVisibleItemClosestToStart(false));
         final int end = mRecyclerView
                 .getChildLayoutPosition(
-                        mLayoutManager.findFirstVisibleItemClosestToEnd(false, true));
+                        mLayoutManager.findFirstVisibleItemClosestToEnd(false));
         assertEquals("first item position should match",
                 Math.min(start, end), record.getFromIndex());
         assertEquals("last item position should match",
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/TestResizingRelayoutWithAutoMeasure.java b/v7/recyclerview/tests/src/android/support/v7/widget/TestResizingRelayoutWithAutoMeasure.java
index 1f0f3ef..b0f90d6 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/TestResizingRelayoutWithAutoMeasure.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/TestResizingRelayoutWithAutoMeasure.java
@@ -25,8 +25,12 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 
 import android.graphics.Rect;
+import android.support.annotation.NonNull;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.Toast;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -44,33 +48,44 @@
 @MediumTest
 @RunWith(Parameterized.class)
 public class TestResizingRelayoutWithAutoMeasure extends BaseRecyclerViewInstrumentationTest {
+    private final int mRvWidth;
+    private final int mRvHeight;
     private final RecyclerView.LayoutManager mLayoutManager;
     private final float mWidthMultiplier;
     private final float mHeightMultiplier;
 
     public TestResizingRelayoutWithAutoMeasure(@SuppressWarnings("UnusedParameters") String name,
+            int rvWidth, int rvHeight,
             RecyclerView.LayoutManager layoutManager, float widthMultiplier,
             float heightMultiplier) {
+        mRvWidth = rvWidth;
+        mRvHeight = rvHeight;
         mLayoutManager = layoutManager;
         mWidthMultiplier = widthMultiplier;
         mHeightMultiplier = heightMultiplier;
     }
 
-    @Parameterized.Parameters(name = "{0} w:{2} h:{3}")
+    @Parameterized.Parameters(name = "{0} rv w/h:{1}/{2} changed w/h:{4}/{5}")
     public static List<Object[]> getParams() {
         List<Object[]> params = new ArrayList<>();
-        for (float w : new float[]{.5f, 1f, 2f}) {
-            for (float h : new float[]{.5f, 1f, 2f}) {
-                params.add(
-                        new Object[]{"linear layout", new LinearLayoutManager(null), w, h}
-                );
-                params.add(
-                        new Object[]{"grid layout", new GridLayoutManager(null, 3), w, h}
-                );
-                params.add(
-                        new Object[]{"staggered", new StaggeredGridLayoutManager(3,
-                                StaggeredGridLayoutManager.VERTICAL), w, h}
-                );
+        for(int[] rvSize : new int[][]{new int[]{200, 200}, new int[]{200, 100},
+                new int[]{100, 200}}) {
+            for (float w : new float[]{.5f, 1f, 2f}) {
+                for (float h : new float[]{.5f, 1f, 2f}) {
+                    params.add(
+                            new Object[]{"linear layout", rvSize[0], rvSize[1],
+                                    new LinearLayoutManager(null), w, h}
+                    );
+                    params.add(
+                            new Object[]{"grid layout", rvSize[0], rvSize[1],
+                                    new GridLayoutManager(null, 3), w, h}
+                    );
+                    params.add(
+                            new Object[]{"staggered", rvSize[0], rvSize[1],
+                                    new StaggeredGridLayoutManager(3,
+                                    StaggeredGridLayoutManager.VERTICAL), w, h}
+                    );
+                }
             }
         }
         return params;
@@ -78,9 +93,12 @@
 
     @Test
     public void testResizeDuringMeasurements() throws Throwable {
-        final RecyclerView recyclerView = new RecyclerView(getActivity());
+        final WrappedRecyclerView recyclerView = new WrappedRecyclerView(getActivity());
         recyclerView.setLayoutManager(mLayoutManager);
-        recyclerView.setAdapter(new TestAdapter(500));
+        StaticAdapter adapter = new StaticAdapter(50, ViewGroup.LayoutParams.MATCH_PARENT,
+                mRvHeight / 5);
+        recyclerView.setLayoutParams(new FrameLayout.LayoutParams(mRvWidth, mRvHeight));
+        recyclerView.setAdapter(adapter);
         setRecyclerView(recyclerView);
         getInstrumentation().waitForIdleSync();
         assertThat("Test sanity", recyclerView.getChildCount() > 0, is(true));
@@ -88,38 +106,57 @@
         smoothScrollToPosition(lastPosition);
         assertThat("test sanity", recyclerView.findViewHolderForAdapterPosition(lastPosition),
                 notNullValue());
+        assertThat("test sanity", mRvWidth, is(recyclerView.getWidth()));
+        assertThat("test sanity", mRvHeight, is(recyclerView.getHeight()));
+        recyclerView.waitUntilLayout();
+        recyclerView.waitUntilAnimations();
+        final Map<Integer, Rect> startPositions = capturePositions(recyclerView);
         runTestOnUiThread(new Runnable() {
             @Override
             public void run() {
-                int startHeight = recyclerView.getMeasuredHeight();
-                int startWidth = recyclerView.getMeasuredWidth();
-                Map<Integer, Rect> startPositions = capturePositions(recyclerView);
                 recyclerView.measure(
-                        makeMeasureSpec((int) (startWidth * mWidthMultiplier),
+                        makeMeasureSpec((int) (mRvWidth * mWidthMultiplier),
                                 mWidthMultiplier == 1f ? EXACTLY : AT_MOST),
-                        makeMeasureSpec((int) (startHeight * mHeightMultiplier),
+                        makeMeasureSpec((int) (mRvHeight * mHeightMultiplier),
                                 mHeightMultiplier == 1f ? EXACTLY : AT_MOST));
 
                 recyclerView.measure(
-                        makeMeasureSpec(startWidth, EXACTLY),
-                        makeMeasureSpec(startHeight, EXACTLY));
+                        makeMeasureSpec(mRvWidth, EXACTLY),
+                        makeMeasureSpec(mRvHeight, EXACTLY));
                 recyclerView.dispatchLayout();
                 Map<Integer, Rect> endPositions = capturePositions(recyclerView);
                 assertStartItemPositions(startPositions, endPositions);
             }
         });
+        recyclerView.waitUntilLayout();
+        recyclerView.waitUntilAnimations();
+        checkForMainThreadException();
     }
 
     private void assertStartItemPositions(Map<Integer, Rect> startPositions,
             Map<Integer, Rect> endPositions) {
+        String log = log(startPositions, endPositions);
         for (Map.Entry<Integer, Rect> entry : startPositions.entrySet()) {
             Rect rect = endPositions.get(entry.getKey());
-            assertThat("view for position " + entry.getKey() + " at" + entry.getValue(), rect,
+            assertThat(log + "view for position " + entry.getKey() + " at" + entry.getValue(), rect,
                     notNullValue());
-            assertThat("rect for position " + entry.getKey(), entry.getValue(), is(rect));
+            assertThat(log + "rect for position " + entry.getKey(), entry.getValue(), is(rect));
         }
     }
 
+    @NonNull
+    private String log(Map<Integer, Rect> startPositions, Map<Integer, Rect> endPositions) {
+        StringBuilder logBuilder = new StringBuilder();
+        for (Map.Entry<Integer, Rect> entry : startPositions.entrySet()) {
+            logBuilder.append(entry.getKey()).append(":").append(entry.getValue()).append("\n");
+        }
+        logBuilder.append("------\n");
+        for (Map.Entry<Integer, Rect> entry : endPositions.entrySet()) {
+            logBuilder.append(entry.getKey()).append(":").append(entry.getValue()).append("\n");
+        }
+        return logBuilder.toString();
+    }
+
     private Map<Integer, Rect> capturePositions(RecyclerView recyclerView) {
         Map<Integer, Rect> positions = new HashMap<>();
         for (int i = 0; i < mLayoutManager.getChildCount(); i++) {
@@ -138,4 +175,52 @@
         }
         return positions;
     }
+
+    private class StaticAdapter extends RecyclerView.Adapter<TestViewHolder> {
+        final int mSize;
+        // is passed to the layout params of the item
+        final int mMinItemWidth;
+        final int mMinItemHeight;
+
+        public StaticAdapter(int size, int minItemWidth, int minItemHeight) {
+            mSize = size;
+            mMinItemWidth = minItemWidth;
+            mMinItemHeight = minItemHeight;
+        }
+
+        @Override
+        public TestViewHolder onCreateViewHolder(ViewGroup parent,
+                int viewType) {
+            return new TestViewHolder(new View(parent.getContext()));
+        }
+
+        @Override
+        public void onBindViewHolder(TestViewHolder holder, int position) {
+            holder.mBoundItem = new Item(position, "none");
+            if (mMinItemHeight < 1 && mMinItemWidth < 1) {
+                return;
+            }
+            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
+            if (lp == null) {
+                lp = new ViewGroup.LayoutParams(0, 0);
+            }
+            if (mMinItemWidth > 0) {
+                lp.width = (int) (mMinItemWidth + (position % 10) * mMinItemWidth / 7f);
+            } else {
+                lp.width = mMinItemWidth;
+            }
+
+            if (mMinItemHeight > 0) {
+                lp.height = (int) (mMinItemHeight + (position % 10) * mMinItemHeight / 7f);
+            } else {
+                lp.height = mMinItemHeight;
+            }
+            holder.itemView.setLayoutParams(lp);
+        }
+
+        @Override
+        public int getItemCount() {
+            return mSize;
+        }
+    }
 }
\ No newline at end of file
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/WrapContentBasicTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/WrapContentBasicTest.java
index 56cd024..73362dc 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/WrapContentBasicTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/WrapContentBasicTest.java
@@ -16,35 +16,29 @@
 
 package android.support.v7.widget;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import android.content.Context;
-import android.support.annotation.Nullable;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.Display;
-import android.view.View;
-import android.view.ViewGroup;
-
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 @MediumTest
 @RunWith(AndroidJUnit4.class)
-public class WrapContentBasicTest extends AndroidTestCase {
-
+public class WrapContentBasicTest {
+    private Context mContext;
     private WrapContentLayoutManager mLayoutManager;
     private RecyclerView mRecyclerView;
     private WrapAdapter mAdapter;
@@ -54,26 +48,16 @@
             .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
 
     @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        setContext(InstrumentationRegistry.getContext());
-        RecyclerView rv = new RecyclerView(getContext());
-        mRecyclerView = spy(rv);
+    public void setup() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mRecyclerView = new RecyclerView(mContext);
         mLayoutManager = spy(new WrapContentLayoutManager());
         // working around a mockito issue
-        rv.mLayout = mLayoutManager;
-        mAdapter = spy(new WrapAdapter());
         mRecyclerView.setLayoutManager(mLayoutManager);
+        mAdapter = spy(new WrapAdapter());
         mRecyclerView.setAdapter(mAdapter);
     }
 
-    @After
-    @Override
-    public void tearDown() throws Exception {
-        super.tearDown();
-    }
-
     @Test
     public void testLayoutInOnMeasureWithoutPredictive() {
         mLayoutManager.setAutoMeasureEnabled(true);
@@ -153,11 +137,11 @@
         children[0].layout(0, 0, 100, 100);
         children[1].layout(-5, 0, 100, 100);
         children[2].layout(-5, -10, 100, 100);
-        when(mRecyclerView.getMinimumWidth()).thenReturn(250);
+        mRecyclerView.setMinimumWidth(250);
         mLayoutManager.setMeasuredDimensionFromChildren(UNSPECIFIED, UNSPECIFIED);
         verify(mLayoutManager).setMeasuredDimension(250, 110);
 
-        when(mRecyclerView.getMinimumWidth()).thenReturn(5);
+        mRecyclerView.setMinimumWidth(5);
         mLayoutManager.setMeasuredDimensionFromChildren(UNSPECIFIED, UNSPECIFIED);
         verify(mLayoutManager).setMeasuredDimension(105, 110);
     }
@@ -169,11 +153,11 @@
         children[0].layout(0, 0, 100, 100);
         children[1].layout(-5, 0, 100, 100);
         children[2].layout(-5, -10, 100, 100);
-        when(mRecyclerView.getMinimumHeight()).thenReturn(250);
+        mRecyclerView.setMinimumHeight(250);
         mLayoutManager.setMeasuredDimensionFromChildren(UNSPECIFIED, UNSPECIFIED);
         verify(mLayoutManager).setMeasuredDimension(105, 250);
 
-        when(mRecyclerView.getMinimumHeight()).thenReturn(50);
+        mRecyclerView.setMinimumHeight(50);
         mLayoutManager.setMeasuredDimensionFromChildren(UNSPECIFIED, UNSPECIFIED);
         verify(mLayoutManager).setMeasuredDimension(105, 110);
     }
@@ -181,7 +165,7 @@
     private View[] createMockChildren(int count) {
         View[] views = new View[count];
         for (int i = 0; i < count; i++) {
-            View v = new View(getContext());
+            View v = new View(mContext);
             v.setLayoutParams(new RecyclerView.LayoutParams(1, 1));
             views[i] = v;
             when(mLayoutManager.getChildAt(i)).thenReturn(v);
@@ -202,6 +186,68 @@
             return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                     ViewGroup.LayoutParams.WRAP_CONTENT);
         }
+
+        // START MOCKITO OVERRIDES
+        // We override package protected methods to make them public. This is necessary to run
+        // mockito on Kitkat
+        @Override
+        public void setRecyclerView(RecyclerView recyclerView) {
+            super.setRecyclerView(recyclerView);
+        }
+
+        @Override
+        public void dispatchAttachedToWindow(RecyclerView view) {
+            super.dispatchAttachedToWindow(view);
+        }
+
+        @Override
+        public void dispatchDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
+            super.dispatchDetachedFromWindow(view, recycler);
+        }
+
+        @Override
+        public void setExactMeasureSpecsFrom(RecyclerView recyclerView) {
+            super.setExactMeasureSpecsFrom(recyclerView);
+        }
+
+        @Override
+        public void setMeasureSpecs(int wSpec, int hSpec) {
+            super.setMeasureSpecs(wSpec, hSpec);
+        }
+
+        @Override
+        public void setMeasuredDimensionFromChildren(int widthSpec, int heightSpec) {
+            super.setMeasuredDimensionFromChildren(widthSpec, heightSpec);
+        }
+
+        @Override
+        public boolean shouldReMeasureChild(View child, int widthSpec, int heightSpec,
+                RecyclerView.LayoutParams lp) {
+            return super.shouldReMeasureChild(child, widthSpec, heightSpec, lp);
+        }
+
+        @Override
+        public boolean shouldMeasureChild(View child, int widthSpec, int heightSpec,
+                RecyclerView.LayoutParams lp) {
+            return super.shouldMeasureChild(child, widthSpec, heightSpec, lp);
+        }
+
+        @Override
+        public void removeAndRecycleScrapInt(RecyclerView.Recycler recycler) {
+            super.removeAndRecycleScrapInt(recycler);
+        }
+
+        @Override
+        public void stopSmoothScroller() {
+            super.stopSmoothScroller();
+        }
+
+        @Override
+        public boolean shouldMeasureTwice() {
+            return super.shouldMeasureTwice();
+        }
+
+        // END MOCKITO OVERRIDES
     }
 
     public class WrapAdapter extends RecyclerView.Adapter {
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/WrappedRecyclerView.java b/v7/recyclerview/tests/src/android/support/v7/widget/WrappedRecyclerView.java
index 1da3ba5..58a0841 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/WrappedRecyclerView.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/WrappedRecyclerView.java
@@ -16,10 +16,18 @@
 
 package android.support.v7.widget;
 
+import android.app.Instrumentation;
 import android.content.Context;
+import android.support.test.InstrumentationRegistry;
 import android.support.v4.view.ViewCompat;
 import android.util.AttributeSet;
 
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.MatcherAssert;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 /**
  * RecyclerView wrapper used in tests. This class can fake behavior like layout direction w/o
  * playing with framework support.
@@ -27,11 +35,21 @@
 public class WrappedRecyclerView extends RecyclerView {
 
     Boolean mFakeRTL;
+    private long mDrawingTimeOffsetMs;
 
     public void setFakeRTL(Boolean fakeRTL) {
         mFakeRTL = fakeRTL;
     }
 
+    public void setDrawingTimeOffset(long offsetMs) {
+        mDrawingTimeOffsetMs = offsetMs;
+    }
+
+    @Override
+    public long getDrawingTime() {
+        return super.getDrawingTime() + mDrawingTimeOffsetMs;
+    }
+
     public WrappedRecyclerView(Context context) {
         super(context);
         init(context);
@@ -51,6 +69,34 @@
         //initializeScrollbars(null);
     }
 
+    public void waitUntilLayout() {
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        while (isLayoutRequested()) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public void waitUntilAnimations() throws InterruptedException {
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+        final CountDownLatch latch = new CountDownLatch(1);
+        if (mItemAnimator == null || !mItemAnimator.isRunning(
+                new ItemAnimator.ItemAnimatorFinishedListener() {
+                    @Override
+                    public void onAnimationsFinished() {
+                        latch.countDown();
+                    }
+                })) {
+            latch.countDown();
+        }
+        MatcherAssert.assertThat("waiting too long for animations",
+                latch.await(60, TimeUnit.SECONDS), CoreMatchers.is(true));
+    }
+
+
     @Override
     public int getLayoutDirection() {
         if (mFakeRTL == null) {