diff --git a/Android.mk b/Android.mk
index 21bd76b..2539c3d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -346,6 +346,7 @@
 	core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
 	core/java/com/android/internal/backup/IBackupTransport.aidl \
 	core/java/com/android/internal/backup/IObbBackupService.aidl \
+	core/java/com/android/internal/font/IFontManager.aidl \
 	core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl \
 	core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \
 	core/java/com/android/internal/policy/IKeyguardDismissCallback.aidl \
diff --git a/api/current.txt b/api/current.txt
index ca6f470..bca65ee 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8476,6 +8476,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
+    field public static final java.lang.String FONT_SERVICE = "font";
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
@@ -37726,7 +37727,7 @@
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
     field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
-    field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
+    field public static final deprecated java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
@@ -39485,6 +39486,65 @@
     method public android.text.Editable newEditable(java.lang.CharSequence);
   }
 
+  public final class FontConfig implements android.os.Parcelable {
+    ctor public FontConfig();
+    ctor public FontConfig(android.text.FontConfig);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Alias> getAliases();
+    method public java.util.List<android.text.FontConfig.Family> getFamilies();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR;
+  }
+
+  public static final class FontConfig.Alias implements android.os.Parcelable {
+    ctor public FontConfig.Alias(java.lang.String, java.lang.String, int);
+    method public int describeContents();
+    method public java.lang.String getName();
+    method public java.lang.String getToName();
+    method public int getWeight();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Alias> CREATOR;
+  }
+
+  public static final class FontConfig.Axis implements android.os.Parcelable {
+    ctor public FontConfig.Axis(int, float);
+    method public int describeContents();
+    method public float getStyleValue();
+    method public int getTag();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Axis> CREATOR;
+  }
+
+  public static final class FontConfig.Family implements android.os.Parcelable {
+    ctor public FontConfig.Family(java.lang.String, java.util.List<android.text.FontConfig.Font>, java.lang.String, java.lang.String);
+    ctor public FontConfig.Family(android.text.FontConfig.Family);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Font> getFonts();
+    method public java.lang.String getLanguage();
+    method public java.lang.String getName();
+    method public java.lang.String getVariant();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Family> CREATOR;
+  }
+
+  public static final class FontConfig.Font implements android.os.Parcelable {
+    ctor public FontConfig.Font(java.lang.String, int, java.util.List<android.text.FontConfig.Axis>, int, boolean);
+    ctor public FontConfig.Font(android.text.FontConfig.Font);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Axis> getAxes();
+    method public android.os.ParcelFileDescriptor getFd();
+    method public java.lang.String getFontName();
+    method public int getTtcIndex();
+    method public int getWeight();
+    method public boolean isItalic();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Font> CREATOR;
+  }
+
+  public final class FontManager {
+    method public android.text.FontConfig getSystemFonts();
+  }
+
   public abstract interface GetChars implements java.lang.CharSequence {
     method public abstract void getChars(int, int, char[], int);
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 8e0a3e2..53552fc 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8852,6 +8852,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
+    field public static final java.lang.String FONT_SERVICE = "font";
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
@@ -40929,7 +40930,7 @@
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
     field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
-    field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
+    field public static final deprecated java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_PHONE_ACCOUNT_REGISTERED = "android.telecom.action.PHONE_ACCOUNT_REGISTERED";
     field public static final java.lang.String ACTION_PHONE_ACCOUNT_UNREGISTERED = "android.telecom.action.PHONE_ACCOUNT_UNREGISTERED";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
@@ -42786,6 +42787,65 @@
     method public android.text.Editable newEditable(java.lang.CharSequence);
   }
 
+  public final class FontConfig implements android.os.Parcelable {
+    ctor public FontConfig();
+    ctor public FontConfig(android.text.FontConfig);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Alias> getAliases();
+    method public java.util.List<android.text.FontConfig.Family> getFamilies();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR;
+  }
+
+  public static final class FontConfig.Alias implements android.os.Parcelable {
+    ctor public FontConfig.Alias(java.lang.String, java.lang.String, int);
+    method public int describeContents();
+    method public java.lang.String getName();
+    method public java.lang.String getToName();
+    method public int getWeight();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Alias> CREATOR;
+  }
+
+  public static final class FontConfig.Axis implements android.os.Parcelable {
+    ctor public FontConfig.Axis(int, float);
+    method public int describeContents();
+    method public float getStyleValue();
+    method public int getTag();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Axis> CREATOR;
+  }
+
+  public static final class FontConfig.Family implements android.os.Parcelable {
+    ctor public FontConfig.Family(java.lang.String, java.util.List<android.text.FontConfig.Font>, java.lang.String, java.lang.String);
+    ctor public FontConfig.Family(android.text.FontConfig.Family);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Font> getFonts();
+    method public java.lang.String getLanguage();
+    method public java.lang.String getName();
+    method public java.lang.String getVariant();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Family> CREATOR;
+  }
+
+  public static final class FontConfig.Font implements android.os.Parcelable {
+    ctor public FontConfig.Font(java.lang.String, int, java.util.List<android.text.FontConfig.Axis>, int, boolean);
+    ctor public FontConfig.Font(android.text.FontConfig.Font);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Axis> getAxes();
+    method public android.os.ParcelFileDescriptor getFd();
+    method public java.lang.String getFontName();
+    method public int getTtcIndex();
+    method public int getWeight();
+    method public boolean isItalic();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Font> CREATOR;
+  }
+
+  public final class FontManager {
+    method public android.text.FontConfig getSystemFonts();
+  }
+
   public abstract interface GetChars implements java.lang.CharSequence {
     method public abstract void getChars(int, int, char[], int);
   }
@@ -50654,6 +50714,7 @@
     method public java.lang.String getErrorString(android.content.Context, int);
     method public int getPackageId(android.content.res.Resources, java.lang.String);
     method public void invokeDrawGlFunctor(android.view.View, long, boolean);
+    method public boolean isMultiProcessEnabled();
     method public boolean isTraceTagEnabled();
     method public void setOnTraceEnabledChangeListener(android.webkit.WebViewDelegate.OnTraceEnabledChangeListener);
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index d579624..d18af4c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -8500,6 +8500,7 @@
     field public static final java.lang.String DOWNLOAD_SERVICE = "download";
     field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
     field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint";
+    field public static final java.lang.String FONT_SERVICE = "font";
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
@@ -37847,7 +37848,7 @@
     field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS";
     field public static final java.lang.String ACTION_CONFIGURE_PHONE_ACCOUNT = "android.telecom.action.CONFIGURE_PHONE_ACCOUNT";
     field public static final java.lang.String ACTION_DEFAULT_DIALER_CHANGED = "android.telecom.action.DEFAULT_DIALER_CHANGED";
-    field public static final java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
+    field public static final deprecated java.lang.String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
     field public static final java.lang.String ACTION_SHOW_CALL_ACCESSIBILITY_SETTINGS = "android.telecom.action.SHOW_CALL_ACCESSIBILITY_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS";
     field public static final java.lang.String ACTION_SHOW_MISSED_CALLS_NOTIFICATION = "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION";
@@ -39609,6 +39610,65 @@
     method public android.text.Editable newEditable(java.lang.CharSequence);
   }
 
+  public final class FontConfig implements android.os.Parcelable {
+    ctor public FontConfig();
+    ctor public FontConfig(android.text.FontConfig);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Alias> getAliases();
+    method public java.util.List<android.text.FontConfig.Family> getFamilies();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig> CREATOR;
+  }
+
+  public static final class FontConfig.Alias implements android.os.Parcelable {
+    ctor public FontConfig.Alias(java.lang.String, java.lang.String, int);
+    method public int describeContents();
+    method public java.lang.String getName();
+    method public java.lang.String getToName();
+    method public int getWeight();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Alias> CREATOR;
+  }
+
+  public static final class FontConfig.Axis implements android.os.Parcelable {
+    ctor public FontConfig.Axis(int, float);
+    method public int describeContents();
+    method public float getStyleValue();
+    method public int getTag();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Axis> CREATOR;
+  }
+
+  public static final class FontConfig.Family implements android.os.Parcelable {
+    ctor public FontConfig.Family(java.lang.String, java.util.List<android.text.FontConfig.Font>, java.lang.String, java.lang.String);
+    ctor public FontConfig.Family(android.text.FontConfig.Family);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Font> getFonts();
+    method public java.lang.String getLanguage();
+    method public java.lang.String getName();
+    method public java.lang.String getVariant();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Family> CREATOR;
+  }
+
+  public static final class FontConfig.Font implements android.os.Parcelable {
+    ctor public FontConfig.Font(java.lang.String, int, java.util.List<android.text.FontConfig.Axis>, int, boolean);
+    ctor public FontConfig.Font(android.text.FontConfig.Font);
+    method public int describeContents();
+    method public java.util.List<android.text.FontConfig.Axis> getAxes();
+    method public android.os.ParcelFileDescriptor getFd();
+    method public java.lang.String getFontName();
+    method public int getTtcIndex();
+    method public int getWeight();
+    method public boolean isItalic();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.text.FontConfig.Font> CREATOR;
+  }
+
+  public final class FontManager {
+    method public android.text.FontConfig getSystemFonts();
+  }
+
   public abstract interface GetChars implements java.lang.CharSequence {
     method public abstract void getChars(int, int, char[], int);
   }
diff --git a/compiled-classes-phone b/compiled-classes-phone
index ebc54f2..ed0a4a6 100644
--- a/compiled-classes-phone
+++ b/compiled-classes-phone
@@ -1195,13 +1195,13 @@
 android.graphics.DiscretePathEffect
 android.graphics.DrawFilter
 android.graphics.EmbossMaskFilter
+android.graphics.FontConfig
+android.graphics.FontConfig$Alias
+android.graphics.FontConfig$Axis
+android.graphics.FontConfig$Family
+android.graphics.FontConfig$Font
 android.graphics.FontFamily
 android.graphics.FontListParser
-android.graphics.FontListParser$Alias
-android.graphics.FontListParser$Axis
-android.graphics.FontListParser$Config
-android.graphics.FontListParser$Family
-android.graphics.FontListParser$Font
 android.graphics.ImageFormat
 android.graphics.Insets
 android.graphics.Interpolator
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 1658e82..b2c97f6 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1591,12 +1591,15 @@
         }
 
         final IActivityManager am = ActivityManager.getService();
-        if (am == null && UserHandle.getAppId(Binder.getCallingUid()) == Process.SYSTEM_UID) {
+        if (am == null) {
             // Well this is super awkward; we somehow don't have an active
-            // ActivityManager instance. If this is the system UID, then we
-            // totally have whatever permission this is.
-            Slog.w(TAG, "Missing ActivityManager; assuming system UID holds " + permission);
-            return PackageManager.PERMISSION_GRANTED;
+            // ActivityManager instance. If we're testing a root or system
+            // UID, then they totally have whatever permission this is.
+            final int appId = UserHandle.getAppId(uid);
+            if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) {
+                Slog.w(TAG, "Missing ActivityManager; assuming " + uid + " holds " + permission);
+                return PackageManager.PERMISSION_GRANTED;
+            }
         }
 
         try {
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 036b47c..6793c90 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -322,7 +322,7 @@
      * password.
      */
     public boolean isDeviceLocked() {
-        return isDeviceLocked(UserHandle.getCallingUserId());
+        return isDeviceLocked(UserHandle.myUserId());
     }
 
     /**
@@ -347,7 +347,7 @@
      * @return true if a PIN, pattern or password was set.
      */
     public boolean isDeviceSecure() {
-        return isDeviceSecure(UserHandle.getCallingUserId());
+        return isDeviceSecure(UserHandle.myUserId());
     }
 
     /**
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 9387019..a37f22b 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -118,6 +118,7 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.text.FontManager;
 import android.text.TextClassificationManager;
 import android.util.Log;
 import android.view.ContextThemeWrapper;
@@ -133,6 +134,7 @@
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.app.ISoundTriggerService;
 import com.android.internal.appwidget.IAppWidgetService;
+import com.android.internal.font.IFontManager;
 import com.android.internal.os.IDropBoxManagerService;
 import com.android.internal.policy.PhoneLayoutInflater;
 
@@ -793,6 +795,15 @@
             public IncidentManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                 return new IncidentManager(ctx);
             }});
+
+        registerService(Context.FONT_SERVICE, FontManager.class,
+                new CachedServiceFetcher<FontManager>() {
+                    @Override
+                    public FontManager createService(ContextImpl ctx)
+                            throws ServiceNotFoundException {
+                        IBinder b = ServiceManager.getServiceOrThrow(Context.FONT_SERVICE);
+                        return new FontManager(IFontManager.Stub.asInterface(b));
+                    }});
     }
 
     /**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 596a9fd..f41d7f2 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3744,6 +3744,11 @@
     public static final String DEVICE_IDENTIFIERS_SERVICE = "device_identifiers";
 
     /**
+     * Service that provides System font data.
+     */
+    public static final String FONT_SERVICE = "font";
+
+    /**
      * Service to report a system health "incident"
      * @hide
      */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5dcc96a..71b9482 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7601,6 +7601,14 @@
                "hdmi_control_auto_device_off_enabled";
 
        /**
+        * The interval in milliseconds at which location requests will be throttled when they are
+        * coming from the background.
+        * @hide
+        */
+       public static final String LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS =
+                "location_background_throttle_interval_ms";
+
+       /**
         * Whether TV will switch to MHL port when a mobile device is plugged in.
         * (0 = false, 1 = true)
         * @hide
diff --git a/core/java/android/text/FontConfig.aidl b/core/java/android/text/FontConfig.aidl
new file mode 100644
index 0000000..17a5ca2
--- /dev/null
+++ b/core/java/android/text/FontConfig.aidl
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2017, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+/** @hide */
+parcelable FontConfig;
diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java
new file mode 100644
index 0000000..df694ff
--- /dev/null
+++ b/core/java/android/text/FontConfig.java
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Font configuration descriptions for System fonts.
+ */
+public final class FontConfig implements Parcelable {
+    private final List<Family> mFamilies = new ArrayList<>();
+    private final List<Alias> mAliases = new ArrayList<>();
+
+    public FontConfig() {
+    }
+
+    public FontConfig(FontConfig config) {
+        for (int i = 0; i < config.mFamilies.size(); i++) {
+            mFamilies.add(new Family(config.mFamilies.get(i)));
+        }
+        mAliases.addAll(config.mAliases);
+    }
+
+    /**
+     * Returns the ordered list of families included in the system fonts.
+     */
+    public List<Family> getFamilies() {
+        return mFamilies;
+    }
+
+    /**
+     * Returns the list of aliases defined for the font families in the system fonts.
+     */
+    public List<Alias> getAliases() {
+        return mAliases;
+    }
+
+    /**
+     * @hide
+     */
+    public FontConfig(Parcel in) {
+        readFromParcel(in);
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flag) {
+        out.writeInt(mFamilies.size());
+        for (int i = 0; i < mFamilies.size(); i++) {
+            mFamilies.get(i).writeToParcel(out, flag);
+        }
+        out.writeInt(mAliases.size());
+        for (int i = 0; i < mAliases.size(); i++) {
+            mAliases.get(i).writeToParcel(out, flag);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void readFromParcel(Parcel in) {
+        int size = in.readInt();
+        for (int i = 0; i < size; i++) {
+            mFamilies.add(new Family(in));
+        }
+        size = in.readInt();
+        for (int i = 0; i < size; i++) {
+            mAliases.add(new Alias(in));
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<FontConfig> CREATOR = new Parcelable.Creator() {
+        public FontConfig createFromParcel(Parcel in) {
+            return new FontConfig(in);
+        }
+        public FontConfig[] newArray(int size) {
+            return new FontConfig[size];
+        }
+    };
+
+    /**
+     * Class that holds information about a Font axis.
+     */
+    public static final class Axis implements Parcelable {
+        private final int mTag;
+        private final float mStyleValue;
+
+        public Axis(int tag, float styleValue) {
+            this.mTag = tag;
+            this.mStyleValue = styleValue;
+        }
+
+        /**
+         * Returns the variable font axis tag associated to this axis.
+         */
+        public int getTag() {
+            return mTag;
+        }
+
+        /**
+         * Returns the style value associated to the given axis for this font.
+         */
+        public float getStyleValue() {
+            return mStyleValue;
+        }
+
+        /**
+         * @hide
+         */
+        public Axis(Parcel in) {
+            mTag = in.readInt();
+            mStyleValue = in.readFloat();
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flag) {
+            out.writeInt(mTag);
+            out.writeFloat(mStyleValue);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Creator<Axis> CREATOR = new Creator<Axis>() {
+            @Override
+            public Axis createFromParcel(Parcel in) {
+                return new Axis(in);
+            }
+
+            @Override
+            public Axis[] newArray(int size) {
+                return new Axis[size];
+            }
+        };
+    }
+
+    /**
+     * Class that holds information about a Font.
+     */
+    public static final class Font implements Parcelable {
+        private final String mFontName;
+        private final int mTtcIndex;
+        private final List<Axis> mAxes;
+        private final int mWeight;
+        private final boolean mIsItalic;
+        private ParcelFileDescriptor mFd;
+
+        public Font(String fontName, int ttcIndex, List<Axis> axes, int weight, boolean isItalic) {
+            mFontName = fontName;
+            mTtcIndex = ttcIndex;
+            mAxes = axes;
+            mWeight = weight;
+            mIsItalic = isItalic;
+            mFd = null;
+        }
+
+        public Font(Font origin) {
+            mFontName = origin.mFontName;
+            mTtcIndex = origin.mTtcIndex;
+            mAxes = new ArrayList<>(origin.mAxes);
+            mWeight = origin.mWeight;
+            mIsItalic = origin.mIsItalic;
+            if (origin.mFd != null) {
+                try {
+                    mFd = origin.mFd.dup();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        /**
+         * Returns the name associated by the system to this font.
+         */
+        public String getFontName() {
+            return mFontName;
+        }
+
+        /**
+         * Returns the index to be used to access this font when accessing a TTC file.
+         */
+        public int getTtcIndex() {
+            return mTtcIndex;
+        }
+
+        /**
+         * Returns the list of axes associated to this font.
+         */
+        public List<Axis> getAxes() {
+            return mAxes;
+        }
+
+        /**
+         * Returns the weight value for this font.
+         */
+        public int getWeight() {
+            return mWeight;
+        }
+
+        /**
+         * Returns whether this font is italic.
+         */
+        public boolean isItalic() {
+            return mIsItalic;
+        }
+
+        /**
+         * Returns a file descriptor to access the specified font. This should be closed after use.
+         */
+        public ParcelFileDescriptor getFd() {
+            return mFd;
+        }
+
+        /**
+         * @hide
+         */
+        public void setFd(ParcelFileDescriptor fd) {
+            mFd = fd;
+        }
+
+        /**
+         * @hide
+         */
+        public Font(Parcel in) {
+            mFontName = in.readString();
+            mTtcIndex = in.readInt();
+            final int numAxes = in.readInt();
+            mAxes = new ArrayList<>();
+            for (int i = 0; i < numAxes; i++) {
+                mAxes.add(new Axis(in));
+            }
+            mWeight = in.readInt();
+            mIsItalic = in.readInt() == 1;
+            if (in.readInt() == 1) { /* has FD */
+                mFd = ParcelFileDescriptor.CREATOR.createFromParcel(in);
+            } else {
+                mFd = null;
+            }
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flag) {
+            out.writeString(mFontName);
+            out.writeInt(mTtcIndex);
+            out.writeInt(mAxes.size());
+            for (int i = 0; i < mAxes.size(); i++) {
+                mAxes.get(i).writeToParcel(out, flag);
+            }
+            out.writeInt(mWeight);
+            out.writeInt(mIsItalic ? 1 : 0);
+            out.writeInt(mFd == null ? 0 : 1);
+            if (mFd != null) {
+                mFd.writeToParcel(out, flag);
+            }
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Creator<Font> CREATOR = new Creator<Font>() {
+            @Override
+            public Font createFromParcel(Parcel in) {
+                return new Font(in);
+            }
+
+            @Override
+            public Font[] newArray(int size) {
+                return new Font[size];
+            }
+        };
+    }
+
+    /**
+     * Class that holds information about a Font alias.
+     */
+    public static final class Alias implements Parcelable {
+        private final String mName;
+        private final String mToName;
+        private final int mWeight;
+
+        public Alias(String name, String toName, int weight) {
+            this.mName = name;
+            this.mToName = toName;
+            this.mWeight = weight;
+        }
+
+        /**
+         * Returns the new name for the alias.
+         */
+        public String getName() {
+            return mName;
+        }
+
+        /**
+         * Returns the existing name to which this alias points to.
+         */
+        public String getToName() {
+            return mToName;
+        }
+
+        /**
+         * Returns the weight associated with this alias.
+         */
+        public int getWeight() {
+            return mWeight;
+        }
+
+        /**
+         * @hide
+         */
+        public Alias(Parcel in) {
+            mName = in.readString();
+            mToName = in.readString();
+            mWeight = in.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flag) {
+            out.writeString(mName);
+            out.writeString(mToName);
+            out.writeInt(mWeight);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Creator<Alias> CREATOR = new Creator<Alias>() {
+            @Override
+            public Alias createFromParcel(Parcel in) {
+                return new Alias(in);
+            }
+
+            @Override
+            public Alias[] newArray(int size) {
+                return new Alias[size];
+            }
+        };
+    }
+
+    /**
+     * Class that holds information about a Font family.
+     */
+    public static final class Family implements Parcelable {
+        private final String mName;
+        private final List<Font> mFonts;
+        private final String mLanguage;
+        private final String mVariant;
+
+        public Family(String name, List<Font> fonts, String language, String variant) {
+            this.mName = name;
+            this.mFonts = fonts;
+            this.mLanguage = language;
+            this.mVariant = variant;
+        }
+
+        public Family(Family origin) {
+            this.mName = origin.mName;
+            this.mLanguage = origin.mLanguage;
+            this.mVariant = origin.mVariant;
+            this.mFonts = new ArrayList<>();
+            for (int i = 0; i < origin.mFonts.size(); i++) {
+                mFonts.add(new Font(origin.mFonts.get(i)));
+            }
+        }
+
+        /**
+         * Returns the name given by the system to this font family.
+         */
+        public String getName() {
+            return mName;
+        }
+
+        /**
+         * Returns the list of fonts included in this family.
+         */
+        public List<Font> getFonts() {
+            return mFonts;
+        }
+
+        /**
+         * Returns the language for this family. May be null.
+         */
+        public String getLanguage() {
+            return mLanguage;
+        }
+
+        /**
+         * Returns the font variant for this family, e.g. "elegant" or "compact". May be null.
+         */
+        public String getVariant() {
+            return mVariant;
+        }
+
+        /**
+         * @hide
+         */
+        public Family(Parcel in) {
+            mName = in.readString();
+            final int size = in.readInt();
+            mFonts = new ArrayList<>();
+            for (int i = 0; i < size; i++) {
+                mFonts.add(new Font(in));
+            }
+            mLanguage = in.readString();
+            mVariant = in.readString();
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flag) {
+            out.writeString(mName);
+            out.writeInt(mFonts.size());
+            for (int i = 0; i < mFonts.size(); i++) {
+                mFonts.get(i).writeToParcel(out, flag);
+            }
+            out.writeString(mLanguage);
+            out.writeString(mVariant);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final Creator<Family> CREATOR = new Creator<Family>() {
+            @Override
+            public Family createFromParcel(Parcel in) {
+                return new Family(in);
+            }
+
+            @Override
+            public Family[] newArray(int size) {
+                return new Family[size];
+            }
+        };
+    }
+}
diff --git a/core/java/android/text/FontManager.java b/core/java/android/text/FontManager.java
new file mode 100644
index 0000000..b61cbf3
--- /dev/null
+++ b/core/java/android/text/FontManager.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import android.os.RemoteException;
+
+import com.android.internal.font.IFontManager;
+
+/**
+ * Interact with the Font service.
+ */
+public final class FontManager {
+    private static final String TAG = "FontManager";
+
+    private final IFontManager mService;
+
+    /**
+     * @hide
+     */
+    public FontManager(IFontManager service) {
+        mService = service;
+    }
+
+    /**
+     * Retrieve the system fonts data. This loads the fonts.xml data if needed and loads all system
+     * fonts in to memory, providing file descriptors for them.
+     */
+    public FontConfig getSystemFonts() {
+        try {
+            return mService.getSystemFonts();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/core/java/android/webkit/UserPackage.java b/core/java/android/webkit/UserPackage.java
new file mode 100644
index 0000000..404bcf4
--- /dev/null
+++ b/core/java/android/webkit/UserPackage.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.webkit;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.os.UserManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class for storing a (user,PackageInfo) mapping.
+ * @hide
+ */
+public class UserPackage {
+    private final UserInfo mUserInfo;
+    private final PackageInfo mPackageInfo;
+
+    public UserPackage(UserInfo user, PackageInfo packageInfo) {
+        this.mUserInfo = user;
+        this.mPackageInfo = packageInfo;
+    }
+
+    /**
+     * Returns a list of (User,PackageInfo) pairs corresponding to the PackageInfos for all
+     * device users for the package named {@param packageName}.
+     */
+    public static List<UserPackage> getPackageInfosAllUsers(Context context,
+            String packageName, int packageFlags) {
+        List<UserInfo> users = getAllUsers(context);
+        List<UserPackage> userPackages = new ArrayList<UserPackage>(users.size());
+        for (UserInfo user : users) {
+            PackageInfo packageInfo = null;
+            try {
+                packageInfo = context.getPackageManager().getPackageInfoAsUser(
+                        packageName, packageFlags, user.id);
+            } catch (NameNotFoundException e) {
+            }
+            userPackages.add(new UserPackage(user, packageInfo));
+        }
+        return userPackages;
+    }
+
+    /**
+     * Returns whether the given package is enabled.
+     * This state can be changed by the user from Settings->Apps
+     */
+    public boolean isEnabledPackage() {
+        if (mPackageInfo == null) return false;
+        return mPackageInfo.applicationInfo.enabled;
+    }
+
+    /**
+     * Return true if the package is installed and not hidden
+     */
+    public boolean isInstalledPackage() {
+        if (mPackageInfo == null) return false;
+        return (((mPackageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0)
+            && ((mPackageInfo.applicationInfo.privateFlags
+                        & ApplicationInfo.PRIVATE_FLAG_HIDDEN) == 0));
+    }
+
+    public UserInfo getUserInfo() {
+        return mUserInfo;
+    }
+
+    public PackageInfo getPackageInfo() {
+        return mPackageInfo;
+    }
+
+
+    private static List<UserInfo> getAllUsers(Context context) {
+        UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        return userManager.getUsers(false);
+    }
+
+}
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index 2cdff79..92d0d71 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -26,6 +26,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.SparseArray;
@@ -206,4 +207,15 @@
                     appInfo.getBaseResourcePath(), newAssetPath);
         }
     }
+
+    /**
+     * Returns whether WebView should run in multiprocess mode.
+     */
+    public boolean isMultiProcessEnabled() {
+        try {
+            return WebViewFactory.getUpdateService().isMultiProcessEnabled();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index d734d17..ab1d9b9 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -749,10 +749,7 @@
                     }
                 } else {
                     try {
-                        AppGlobals.getPackageManager().setLastChosenActivity(intent,
-                                intent.resolveType(getContentResolver()),
-                                PackageManager.MATCH_DEFAULT_ONLY,
-                                filter, bestMatch, intent.getComponent());
+                        mAdapter.mResolverListController.setLastChosen(intent, filter, bestMatch);
                     } catch (RemoteException re) {
                         Log.d(TAG, "Error calling setLastChosenActivity\n" + re);
                     }
@@ -1312,10 +1309,7 @@
         protected boolean rebuildList() {
             List<ResolvedComponentInfo> currentResolveList = null;
             try {
-                final Intent primaryIntent = getTargetIntent();
-                mLastChosen = AppGlobals.getPackageManager().getLastChosenActivity(
-                        primaryIntent, primaryIntent.resolveTypeIfNeeded(getContentResolver()),
-                        PackageManager.MATCH_DEFAULT_ONLY);
+                mLastChosen = mResolverListController.getLastChosen();
             } catch (RemoteException re) {
                 Log.d(TAG, "Error calling getLastChosenActivity\n" + re);
             }
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index f88f6f9..00faf65 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -19,13 +19,16 @@
 
 import android.annotation.WorkerThread;
 import android.app.ActivityManager;
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.os.RemoteException;
 import android.util.Log;
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -66,6 +69,22 @@
     }
 
     @VisibleForTesting
+    ResolveInfo getLastChosen() throws RemoteException {
+        return AppGlobals.getPackageManager().getLastChosenActivity(
+                mTargetIntent, mTargetIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                PackageManager.MATCH_DEFAULT_ONLY);
+    }
+
+    @VisibleForTesting
+    void setLastChosen(Intent intent, IntentFilter filter, int match)
+            throws RemoteException {
+        AppGlobals.getPackageManager().setLastChosenActivity(intent,
+                intent.resolveType(mContext.getContentResolver()),
+                PackageManager.MATCH_DEFAULT_ONLY,
+                filter, match, intent.getComponent());
+    }
+
+    @VisibleForTesting
     public List<ResolverActivity.ResolvedComponentInfo> getResolversForIntent(
             boolean shouldGetResolvedFilter,
             boolean shouldGetActivityMetadata,
diff --git a/core/java/com/android/internal/font/IFontManager.aidl b/core/java/com/android/internal/font/IFontManager.aidl
new file mode 100644
index 0000000..52a6262
--- /dev/null
+++ b/core/java/com/android/internal/font/IFontManager.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.font;
+
+import android.text.FontConfig;
+
+/**
+ * Interface to the font manager.
+ * @hide
+ */
+interface IFontManager {
+    FontConfig getSystemFonts();
+}
diff --git a/core/java/com/android/internal/widget/AdapterHelper.java b/core/java/com/android/internal/widget/AdapterHelper.java
new file mode 100644
index 0000000..f47d430
--- /dev/null
+++ b/core/java/com/android/internal/widget/AdapterHelper.java
@@ -0,0 +1,775 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.util.Log;
+import android.util.Pools;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Helper class that can enqueue and process adapter update operations.
+ * <p>
+ * To support animations, RecyclerView presents an older version the Adapter to best represent
+ * previous state of the layout. Sometimes, this is not trivial when items are removed that were
+ * not laid out, in which case, RecyclerView has no way of providing that item's view for
+ * animations.
+ * <p>
+ * AdapterHelper creates an UpdateOp for each adapter data change then pre-processes them. During
+ * pre processing, AdapterHelper finds out which UpdateOps can be deferred to second layout pass
+ * and which cannot. For the UpdateOps that cannot be deferred, AdapterHelper will change them
+ * according to previously deferred operation and dispatch them before the first layout pass. It
+ * also takes care of updating deferred UpdateOps since order of operations is changed by this
+ * process.
+ * <p>
+ * Although operations may be forwarded to LayoutManager in different orders, resulting data set
+ * is guaranteed to be the consistent.
+ */
+class AdapterHelper implements OpReorderer.Callback {
+
+    static final int POSITION_TYPE_INVISIBLE = 0;
+
+    static final int POSITION_TYPE_NEW_OR_LAID_OUT = 1;
+
+    private static final boolean DEBUG = false;
+
+    private static final String TAG = "AHT";
+
+    private Pools.Pool<UpdateOp> mUpdateOpPool = new Pools.SimplePool<UpdateOp>(UpdateOp.POOL_SIZE);
+
+    final ArrayList<UpdateOp> mPendingUpdates = new ArrayList<UpdateOp>();
+
+    final ArrayList<UpdateOp> mPostponedList = new ArrayList<UpdateOp>();
+
+    final Callback mCallback;
+
+    Runnable mOnItemProcessedCallback;
+
+    final boolean mDisableRecycler;
+
+    final OpReorderer mOpReorderer;
+
+    private int mExistingUpdateTypes = 0;
+
+    AdapterHelper(Callback callback) {
+        this(callback, false);
+    }
+
+    AdapterHelper(Callback callback, boolean disableRecycler) {
+        mCallback = callback;
+        mDisableRecycler = disableRecycler;
+        mOpReorderer = new OpReorderer(this);
+    }
+
+    AdapterHelper addUpdateOp(UpdateOp... ops) {
+        Collections.addAll(mPendingUpdates, ops);
+        return this;
+    }
+
+    void reset() {
+        recycleUpdateOpsAndClearList(mPendingUpdates);
+        recycleUpdateOpsAndClearList(mPostponedList);
+        mExistingUpdateTypes = 0;
+    }
+
+    void preProcess() {
+        mOpReorderer.reorderOps(mPendingUpdates);
+        final int count = mPendingUpdates.size();
+        for (int i = 0; i < count; i++) {
+            UpdateOp op = mPendingUpdates.get(i);
+            switch (op.cmd) {
+                case UpdateOp.ADD:
+                    applyAdd(op);
+                    break;
+                case UpdateOp.REMOVE:
+                    applyRemove(op);
+                    break;
+                case UpdateOp.UPDATE:
+                    applyUpdate(op);
+                    break;
+                case UpdateOp.MOVE:
+                    applyMove(op);
+                    break;
+            }
+            if (mOnItemProcessedCallback != null) {
+                mOnItemProcessedCallback.run();
+            }
+        }
+        mPendingUpdates.clear();
+    }
+
+    void consumePostponedUpdates() {
+        final int count = mPostponedList.size();
+        for (int i = 0; i < count; i++) {
+            mCallback.onDispatchSecondPass(mPostponedList.get(i));
+        }
+        recycleUpdateOpsAndClearList(mPostponedList);
+        mExistingUpdateTypes = 0;
+    }
+
+    private void applyMove(UpdateOp op) {
+        // MOVE ops are pre-processed so at this point, we know that item is still in the adapter.
+        // otherwise, it would be converted into a REMOVE operation
+        postponeAndUpdateViewHolders(op);
+    }
+
+    private void applyRemove(UpdateOp op) {
+        int tmpStart = op.positionStart;
+        int tmpCount = 0;
+        int tmpEnd = op.positionStart + op.itemCount;
+        int type = -1;
+        for (int position = op.positionStart; position < tmpEnd; position++) {
+            boolean typeChanged = false;
+            RecyclerView.ViewHolder vh = mCallback.findViewHolder(position);
+            if (vh != null || canFindInPreLayout(position)) {
+                // If a ViewHolder exists or this is a newly added item, we can defer this update
+                // to post layout stage.
+                // * For existing ViewHolders, we'll fake its existence in the pre-layout phase.
+                // * For items that are added and removed in the same process cycle, they won't
+                // have any effect in pre-layout since their add ops are already deferred to
+                // post-layout pass.
+                if (type == POSITION_TYPE_INVISIBLE) {
+                    // Looks like we have other updates that we cannot merge with this one.
+                    // Create an UpdateOp and dispatch it to LayoutManager.
+                    UpdateOp newOp = obtainUpdateOp(UpdateOp.REMOVE, tmpStart, tmpCount, null);
+                    dispatchAndUpdateViewHolders(newOp);
+                    typeChanged = true;
+                }
+                type = POSITION_TYPE_NEW_OR_LAID_OUT;
+            } else {
+                // This update cannot be recovered because we don't have a ViewHolder representing
+                // this position. Instead, post it to LayoutManager immediately
+                if (type == POSITION_TYPE_NEW_OR_LAID_OUT) {
+                    // Looks like we have other updates that we cannot merge with this one.
+                    // Create UpdateOp op and dispatch it to LayoutManager.
+                    UpdateOp newOp = obtainUpdateOp(UpdateOp.REMOVE, tmpStart, tmpCount, null);
+                    postponeAndUpdateViewHolders(newOp);
+                    typeChanged = true;
+                }
+                type = POSITION_TYPE_INVISIBLE;
+            }
+            if (typeChanged) {
+                position -= tmpCount; // also equal to tmpStart
+                tmpEnd -= tmpCount;
+                tmpCount = 1;
+            } else {
+                tmpCount++;
+            }
+        }
+        if (tmpCount != op.itemCount) { // all 1 effect
+            recycleUpdateOp(op);
+            op = obtainUpdateOp(UpdateOp.REMOVE, tmpStart, tmpCount, null);
+        }
+        if (type == POSITION_TYPE_INVISIBLE) {
+            dispatchAndUpdateViewHolders(op);
+        } else {
+            postponeAndUpdateViewHolders(op);
+        }
+    }
+
+    private void applyUpdate(UpdateOp op) {
+        int tmpStart = op.positionStart;
+        int tmpCount = 0;
+        int tmpEnd = op.positionStart + op.itemCount;
+        int type = -1;
+        for (int position = op.positionStart; position < tmpEnd; position++) {
+            RecyclerView.ViewHolder vh = mCallback.findViewHolder(position);
+            if (vh != null || canFindInPreLayout(position)) { // deferred
+                if (type == POSITION_TYPE_INVISIBLE) {
+                    UpdateOp newOp = obtainUpdateOp(UpdateOp.UPDATE, tmpStart, tmpCount,
+                            op.payload);
+                    dispatchAndUpdateViewHolders(newOp);
+                    tmpCount = 0;
+                    tmpStart = position;
+                }
+                type = POSITION_TYPE_NEW_OR_LAID_OUT;
+            } else { // applied
+                if (type == POSITION_TYPE_NEW_OR_LAID_OUT) {
+                    UpdateOp newOp = obtainUpdateOp(UpdateOp.UPDATE, tmpStart, tmpCount,
+                            op.payload);
+                    postponeAndUpdateViewHolders(newOp);
+                    tmpCount = 0;
+                    tmpStart = position;
+                }
+                type = POSITION_TYPE_INVISIBLE;
+            }
+            tmpCount++;
+        }
+        if (tmpCount != op.itemCount) { // all 1 effect
+            Object payload = op.payload;
+            recycleUpdateOp(op);
+            op = obtainUpdateOp(UpdateOp.UPDATE, tmpStart, tmpCount, payload);
+        }
+        if (type == POSITION_TYPE_INVISIBLE) {
+            dispatchAndUpdateViewHolders(op);
+        } else {
+            postponeAndUpdateViewHolders(op);
+        }
+    }
+
+    private void dispatchAndUpdateViewHolders(UpdateOp op) {
+        // tricky part.
+        // traverse all postpones and revert their changes on this op if necessary, apply updated
+        // dispatch to them since now they are after this op.
+        if (op.cmd == UpdateOp.ADD || op.cmd == UpdateOp.MOVE) {
+            throw new IllegalArgumentException("should not dispatch add or move for pre layout");
+        }
+        if (DEBUG) {
+            Log.d(TAG, "dispatch (pre)" + op);
+            Log.d(TAG, "postponed state before:");
+            for (UpdateOp updateOp : mPostponedList) {
+                Log.d(TAG, updateOp.toString());
+            }
+            Log.d(TAG, "----");
+        }
+
+        // handle each pos 1 by 1 to ensure continuity. If it breaks, dispatch partial
+        // TODO Since move ops are pushed to end, we should not need this anymore
+        int tmpStart = updatePositionWithPostponed(op.positionStart, op.cmd);
+        if (DEBUG) {
+            Log.d(TAG, "pos:" + op.positionStart + ",updatedPos:" + tmpStart);
+        }
+        int tmpCnt = 1;
+        int offsetPositionForPartial = op.positionStart;
+        final int positionMultiplier;
+        switch (op.cmd) {
+            case UpdateOp.UPDATE:
+                positionMultiplier = 1;
+                break;
+            case UpdateOp.REMOVE:
+                positionMultiplier = 0;
+                break;
+            default:
+                throw new IllegalArgumentException("op should be remove or update." + op);
+        }
+        for (int p = 1; p < op.itemCount; p++) {
+            final int pos = op.positionStart + (positionMultiplier * p);
+            int updatedPos = updatePositionWithPostponed(pos, op.cmd);
+            if (DEBUG) {
+                Log.d(TAG, "pos:" + pos + ",updatedPos:" + updatedPos);
+            }
+            boolean continuous = false;
+            switch (op.cmd) {
+                case UpdateOp.UPDATE:
+                    continuous = updatedPos == tmpStart + 1;
+                    break;
+                case UpdateOp.REMOVE:
+                    continuous = updatedPos == tmpStart;
+                    break;
+            }
+            if (continuous) {
+                tmpCnt++;
+            } else {
+                // need to dispatch this separately
+                UpdateOp tmp = obtainUpdateOp(op.cmd, tmpStart, tmpCnt, op.payload);
+                if (DEBUG) {
+                    Log.d(TAG, "need to dispatch separately " + tmp);
+                }
+                dispatchFirstPassAndUpdateViewHolders(tmp, offsetPositionForPartial);
+                recycleUpdateOp(tmp);
+                if (op.cmd == UpdateOp.UPDATE) {
+                    offsetPositionForPartial += tmpCnt;
+                }
+                tmpStart = updatedPos; // need to remove previously dispatched
+                tmpCnt = 1;
+            }
+        }
+        Object payload = op.payload;
+        recycleUpdateOp(op);
+        if (tmpCnt > 0) {
+            UpdateOp tmp = obtainUpdateOp(op.cmd, tmpStart, tmpCnt, payload);
+            if (DEBUG) {
+                Log.d(TAG, "dispatching:" + tmp);
+            }
+            dispatchFirstPassAndUpdateViewHolders(tmp, offsetPositionForPartial);
+            recycleUpdateOp(tmp);
+        }
+        if (DEBUG) {
+            Log.d(TAG, "post dispatch");
+            Log.d(TAG, "postponed state after:");
+            for (UpdateOp updateOp : mPostponedList) {
+                Log.d(TAG, updateOp.toString());
+            }
+            Log.d(TAG, "----");
+        }
+    }
+
+    void dispatchFirstPassAndUpdateViewHolders(UpdateOp op, int offsetStart) {
+        mCallback.onDispatchFirstPass(op);
+        switch (op.cmd) {
+            case UpdateOp.REMOVE:
+                mCallback.offsetPositionsForRemovingInvisible(offsetStart, op.itemCount);
+                break;
+            case UpdateOp.UPDATE:
+                mCallback.markViewHoldersUpdated(offsetStart, op.itemCount, op.payload);
+                break;
+            default:
+                throw new IllegalArgumentException("only remove and update ops can be dispatched"
+                        + " in first pass");
+        }
+    }
+
+    private int updatePositionWithPostponed(int pos, int cmd) {
+        final int count = mPostponedList.size();
+        for (int i = count - 1; i >= 0; i--) {
+            UpdateOp postponed = mPostponedList.get(i);
+            if (postponed.cmd == UpdateOp.MOVE) {
+                int start, end;
+                if (postponed.positionStart < postponed.itemCount) {
+                    start = postponed.positionStart;
+                    end = postponed.itemCount;
+                } else {
+                    start = postponed.itemCount;
+                    end = postponed.positionStart;
+                }
+                if (pos >= start && pos <= end) {
+                    //i'm affected
+                    if (start == postponed.positionStart) {
+                        if (cmd == UpdateOp.ADD) {
+                            postponed.itemCount++;
+                        } else if (cmd == UpdateOp.REMOVE) {
+                            postponed.itemCount--;
+                        }
+                        // op moved to left, move it right to revert
+                        pos++;
+                    } else {
+                        if (cmd == UpdateOp.ADD) {
+                            postponed.positionStart++;
+                        } else if (cmd == UpdateOp.REMOVE) {
+                            postponed.positionStart--;
+                        }
+                        // op was moved right, move left to revert
+                        pos--;
+                    }
+                } else if (pos < postponed.positionStart) {
+                    // postponed MV is outside the dispatched OP. if it is before, offset
+                    if (cmd == UpdateOp.ADD) {
+                        postponed.positionStart++;
+                        postponed.itemCount++;
+                    } else if (cmd == UpdateOp.REMOVE) {
+                        postponed.positionStart--;
+                        postponed.itemCount--;
+                    }
+                }
+            } else {
+                if (postponed.positionStart <= pos) {
+                    if (postponed.cmd == UpdateOp.ADD) {
+                        pos -= postponed.itemCount;
+                    } else if (postponed.cmd == UpdateOp.REMOVE) {
+                        pos += postponed.itemCount;
+                    }
+                } else {
+                    if (cmd == UpdateOp.ADD) {
+                        postponed.positionStart++;
+                    } else if (cmd == UpdateOp.REMOVE) {
+                        postponed.positionStart--;
+                    }
+                }
+            }
+            if (DEBUG) {
+                Log.d(TAG, "dispath (step" + i + ")");
+                Log.d(TAG, "postponed state:" + i + ", pos:" + pos);
+                for (UpdateOp updateOp : mPostponedList) {
+                    Log.d(TAG, updateOp.toString());
+                }
+                Log.d(TAG, "----");
+            }
+        }
+        for (int i = mPostponedList.size() - 1; i >= 0; i--) {
+            UpdateOp op = mPostponedList.get(i);
+            if (op.cmd == UpdateOp.MOVE) {
+                if (op.itemCount == op.positionStart || op.itemCount < 0) {
+                    mPostponedList.remove(i);
+                    recycleUpdateOp(op);
+                }
+            } else if (op.itemCount <= 0) {
+                mPostponedList.remove(i);
+                recycleUpdateOp(op);
+            }
+        }
+        return pos;
+    }
+
+    private boolean canFindInPreLayout(int position) {
+        final int count = mPostponedList.size();
+        for (int i = 0; i < count; i++) {
+            UpdateOp op = mPostponedList.get(i);
+            if (op.cmd == UpdateOp.MOVE) {
+                if (findPositionOffset(op.itemCount, i + 1) == position) {
+                    return true;
+                }
+            } else if (op.cmd == UpdateOp.ADD) {
+                // TODO optimize.
+                final int end = op.positionStart + op.itemCount;
+                for (int pos = op.positionStart; pos < end; pos++) {
+                    if (findPositionOffset(pos, i + 1) == position) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    private void applyAdd(UpdateOp op) {
+        postponeAndUpdateViewHolders(op);
+    }
+
+    private void postponeAndUpdateViewHolders(UpdateOp op) {
+        if (DEBUG) {
+            Log.d(TAG, "postponing " + op);
+        }
+        mPostponedList.add(op);
+        switch (op.cmd) {
+            case UpdateOp.ADD:
+                mCallback.offsetPositionsForAdd(op.positionStart, op.itemCount);
+                break;
+            case UpdateOp.MOVE:
+                mCallback.offsetPositionsForMove(op.positionStart, op.itemCount);
+                break;
+            case UpdateOp.REMOVE:
+                mCallback.offsetPositionsForRemovingLaidOutOrNewView(op.positionStart,
+                        op.itemCount);
+                break;
+            case UpdateOp.UPDATE:
+                mCallback.markViewHoldersUpdated(op.positionStart, op.itemCount, op.payload);
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown update op type for " + op);
+        }
+    }
+
+    boolean hasPendingUpdates() {
+        return mPendingUpdates.size() > 0;
+    }
+
+    boolean hasAnyUpdateTypes(int updateTypes) {
+        return (mExistingUpdateTypes & updateTypes) != 0;
+    }
+
+    int findPositionOffset(int position) {
+        return findPositionOffset(position, 0);
+    }
+
+    int findPositionOffset(int position, int firstPostponedItem) {
+        int count = mPostponedList.size();
+        for (int i = firstPostponedItem; i < count; ++i) {
+            UpdateOp op = mPostponedList.get(i);
+            if (op.cmd == UpdateOp.MOVE) {
+                if (op.positionStart == position) {
+                    position = op.itemCount;
+                } else {
+                    if (op.positionStart < position) {
+                        position--; // like a remove
+                    }
+                    if (op.itemCount <= position) {
+                        position++; // like an add
+                    }
+                }
+            } else if (op.positionStart <= position) {
+                if (op.cmd == UpdateOp.REMOVE) {
+                    if (position < op.positionStart + op.itemCount) {
+                        return -1;
+                    }
+                    position -= op.itemCount;
+                } else if (op.cmd == UpdateOp.ADD) {
+                    position += op.itemCount;
+                }
+            }
+        }
+        return position;
+    }
+
+    /**
+     * @return True if updates should be processed.
+     */
+    boolean onItemRangeChanged(int positionStart, int itemCount, Object payload) {
+        if (itemCount < 1) {
+            return false;
+        }
+        mPendingUpdates.add(obtainUpdateOp(UpdateOp.UPDATE, positionStart, itemCount, payload));
+        mExistingUpdateTypes |= UpdateOp.UPDATE;
+        return mPendingUpdates.size() == 1;
+    }
+
+    /**
+     * @return True if updates should be processed.
+     */
+    boolean onItemRangeInserted(int positionStart, int itemCount) {
+        if (itemCount < 1) {
+            return false;
+        }
+        mPendingUpdates.add(obtainUpdateOp(UpdateOp.ADD, positionStart, itemCount, null));
+        mExistingUpdateTypes |= UpdateOp.ADD;
+        return mPendingUpdates.size() == 1;
+    }
+
+    /**
+     * @return True if updates should be processed.
+     */
+    boolean onItemRangeRemoved(int positionStart, int itemCount) {
+        if (itemCount < 1) {
+            return false;
+        }
+        mPendingUpdates.add(obtainUpdateOp(UpdateOp.REMOVE, positionStart, itemCount, null));
+        mExistingUpdateTypes |= UpdateOp.REMOVE;
+        return mPendingUpdates.size() == 1;
+    }
+
+    /**
+     * @return True if updates should be processed.
+     */
+    boolean onItemRangeMoved(int from, int to, int itemCount) {
+        if (from == to) {
+            return false; // no-op
+        }
+        if (itemCount != 1) {
+            throw new IllegalArgumentException("Moving more than 1 item is not supported yet");
+        }
+        mPendingUpdates.add(obtainUpdateOp(UpdateOp.MOVE, from, to, null));
+        mExistingUpdateTypes |= UpdateOp.MOVE;
+        return mPendingUpdates.size() == 1;
+    }
+
+    /**
+     * Skips pre-processing and applies all updates in one pass.
+     */
+    void consumeUpdatesInOnePass() {
+        // we still consume postponed updates (if there is) in case there was a pre-process call
+        // w/o a matching consumePostponedUpdates.
+        consumePostponedUpdates();
+        final int count = mPendingUpdates.size();
+        for (int i = 0; i < count; i++) {
+            UpdateOp op = mPendingUpdates.get(i);
+            switch (op.cmd) {
+                case UpdateOp.ADD:
+                    mCallback.onDispatchSecondPass(op);
+                    mCallback.offsetPositionsForAdd(op.positionStart, op.itemCount);
+                    break;
+                case UpdateOp.REMOVE:
+                    mCallback.onDispatchSecondPass(op);
+                    mCallback.offsetPositionsForRemovingInvisible(op.positionStart, op.itemCount);
+                    break;
+                case UpdateOp.UPDATE:
+                    mCallback.onDispatchSecondPass(op);
+                    mCallback.markViewHoldersUpdated(op.positionStart, op.itemCount, op.payload);
+                    break;
+                case UpdateOp.MOVE:
+                    mCallback.onDispatchSecondPass(op);
+                    mCallback.offsetPositionsForMove(op.positionStart, op.itemCount);
+                    break;
+            }
+            if (mOnItemProcessedCallback != null) {
+                mOnItemProcessedCallback.run();
+            }
+        }
+        recycleUpdateOpsAndClearList(mPendingUpdates);
+        mExistingUpdateTypes = 0;
+    }
+
+    public int applyPendingUpdatesToPosition(int position) {
+        final int size = mPendingUpdates.size();
+        for (int i = 0; i < size; i++) {
+            UpdateOp op = mPendingUpdates.get(i);
+            switch (op.cmd) {
+                case UpdateOp.ADD:
+                    if (op.positionStart <= position) {
+                        position += op.itemCount;
+                    }
+                    break;
+                case UpdateOp.REMOVE:
+                    if (op.positionStart <= position) {
+                        final int end = op.positionStart + op.itemCount;
+                        if (end > position) {
+                            return RecyclerView.NO_POSITION;
+                        }
+                        position -= op.itemCount;
+                    }
+                    break;
+                case UpdateOp.MOVE:
+                    if (op.positionStart == position) {
+                        position = op.itemCount; //position end
+                    } else {
+                        if (op.positionStart < position) {
+                            position -= 1;
+                        }
+                        if (op.itemCount <= position) {
+                            position += 1;
+                        }
+                    }
+                    break;
+            }
+        }
+        return position;
+    }
+
+    boolean hasUpdates() {
+        return !mPostponedList.isEmpty() && !mPendingUpdates.isEmpty();
+    }
+
+    /**
+     * Queued operation to happen when child views are updated.
+     */
+    static class UpdateOp {
+
+        static final int ADD = 1;
+
+        static final int REMOVE = 1 << 1;
+
+        static final int UPDATE = 1 << 2;
+
+        static final int MOVE = 1 << 3;
+
+        static final int POOL_SIZE = 30;
+
+        int cmd;
+
+        int positionStart;
+
+        Object payload;
+
+        // holds the target position if this is a MOVE
+        int itemCount;
+
+        UpdateOp(int cmd, int positionStart, int itemCount, Object payload) {
+            this.cmd = cmd;
+            this.positionStart = positionStart;
+            this.itemCount = itemCount;
+            this.payload = payload;
+        }
+
+        String cmdToString() {
+            switch (cmd) {
+                case ADD:
+                    return "add";
+                case REMOVE:
+                    return "rm";
+                case UPDATE:
+                    return "up";
+                case MOVE:
+                    return "mv";
+            }
+            return "??";
+        }
+
+        @Override
+        public String toString() {
+            return Integer.toHexString(System.identityHashCode(this))
+                    + "[" + cmdToString() + ",s:" + positionStart + "c:" + itemCount
+                    + ",p:" + payload + "]";
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            UpdateOp op = (UpdateOp) o;
+
+            if (cmd != op.cmd) {
+                return false;
+            }
+            if (cmd == MOVE && Math.abs(itemCount - positionStart) == 1) {
+                // reverse of this is also true
+                if (itemCount == op.positionStart && positionStart == op.itemCount) {
+                    return true;
+                }
+            }
+            if (itemCount != op.itemCount) {
+                return false;
+            }
+            if (positionStart != op.positionStart) {
+                return false;
+            }
+            if (payload != null) {
+                if (!payload.equals(op.payload)) {
+                    return false;
+                }
+            } else if (op.payload != null) {
+                return false;
+            }
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = cmd;
+            result = 31 * result + positionStart;
+            result = 31 * result + itemCount;
+            return result;
+        }
+    }
+
+    @Override
+    public UpdateOp obtainUpdateOp(int cmd, int positionStart, int itemCount, Object payload) {
+        UpdateOp op = mUpdateOpPool.acquire();
+        if (op == null) {
+            op = new UpdateOp(cmd, positionStart, itemCount, payload);
+        } else {
+            op.cmd = cmd;
+            op.positionStart = positionStart;
+            op.itemCount = itemCount;
+            op.payload = payload;
+        }
+        return op;
+    }
+
+    @Override
+    public void recycleUpdateOp(UpdateOp op) {
+        if (!mDisableRecycler) {
+            op.payload = null;
+            mUpdateOpPool.release(op);
+        }
+    }
+
+    void recycleUpdateOpsAndClearList(List<UpdateOp> ops) {
+        final int count = ops.size();
+        for (int i = 0; i < count; i++) {
+            recycleUpdateOp(ops.get(i));
+        }
+        ops.clear();
+    }
+
+    /**
+     * Contract between AdapterHelper and RecyclerView.
+     */
+    interface Callback {
+
+        RecyclerView.ViewHolder findViewHolder(int position);
+
+        void offsetPositionsForRemovingInvisible(int positionStart, int itemCount);
+
+        void offsetPositionsForRemovingLaidOutOrNewView(int positionStart, int itemCount);
+
+        void markViewHoldersUpdated(int positionStart, int itemCount, Object payloads);
+
+        void onDispatchFirstPass(UpdateOp updateOp);
+
+        void onDispatchSecondPass(UpdateOp updateOp);
+
+        void offsetPositionsForAdd(int positionStart, int itemCount);
+
+        void offsetPositionsForMove(int from, int to);
+    }
+}
diff --git a/core/java/com/android/internal/widget/ChildHelper.java b/core/java/com/android/internal/widget/ChildHelper.java
new file mode 100644
index 0000000..e9136d0
--- /dev/null
+++ b/core/java/com/android/internal/widget/ChildHelper.java
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper class to manage children.
+ * <p>
+ * It wraps a RecyclerView and adds ability to hide some children. There are two sets of methods
+ * provided by this class. <b>Regular</b> methods are the ones that replicate ViewGroup methods
+ * like getChildAt, getChildCount etc. These methods ignore hidden children.
+ * <p>
+ * When RecyclerView needs direct access to the view group children, it can call unfiltered
+ * methods like get getUnfilteredChildCount or getUnfilteredChildAt.
+ */
+class ChildHelper {
+
+    private static final boolean DEBUG = false;
+
+    private static final String TAG = "ChildrenHelper";
+
+    final Callback mCallback;
+
+    final Bucket mBucket;
+
+    final List<View> mHiddenViews;
+
+    ChildHelper(Callback callback) {
+        mCallback = callback;
+        mBucket = new Bucket();
+        mHiddenViews = new ArrayList<View>();
+    }
+
+    /**
+     * Marks a child view as hidden
+     *
+     * @param child  View to hide.
+     */
+    private void hideViewInternal(View child) {
+        mHiddenViews.add(child);
+        mCallback.onEnteredHiddenState(child);
+    }
+
+    /**
+     * Unmarks a child view as hidden.
+     *
+     * @param child  View to hide.
+     */
+    private boolean unhideViewInternal(View child) {
+        if (mHiddenViews.remove(child)) {
+            mCallback.onLeftHiddenState(child);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Adds a view to the ViewGroup
+     *
+     * @param child  View to add.
+     * @param hidden If set to true, this item will be invisible from regular methods.
+     */
+    void addView(View child, boolean hidden) {
+        addView(child, -1, hidden);
+    }
+
+    /**
+     * Add a view to the ViewGroup at an index
+     *
+     * @param child  View to add.
+     * @param index  Index of the child from the regular perspective (excluding hidden views).
+     *               ChildHelper offsets this index to actual ViewGroup index.
+     * @param hidden If set to true, this item will be invisible from regular methods.
+     */
+    void addView(View child, int index, boolean hidden) {
+        final int offset;
+        if (index < 0) {
+            offset = mCallback.getChildCount();
+        } else {
+            offset = getOffset(index);
+        }
+        mBucket.insert(offset, hidden);
+        if (hidden) {
+            hideViewInternal(child);
+        }
+        mCallback.addView(child, offset);
+        if (DEBUG) {
+            Log.d(TAG, "addViewAt " + index + ",h:" + hidden + ", " + this);
+        }
+    }
+
+    private int getOffset(int index) {
+        if (index < 0) {
+            return -1; //anything below 0 won't work as diff will be undefined.
+        }
+        final int limit = mCallback.getChildCount();
+        int offset = index;
+        while (offset < limit) {
+            final int removedBefore = mBucket.countOnesBefore(offset);
+            final int diff = index - (offset - removedBefore);
+            if (diff == 0) {
+                while (mBucket.get(offset)) { // ensure this offset is not hidden
+                    offset++;
+                }
+                return offset;
+            } else {
+                offset += diff;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Removes the provided View from underlying RecyclerView.
+     *
+     * @param view The view to remove.
+     */
+    void removeView(View view) {
+        int index = mCallback.indexOfChild(view);
+        if (index < 0) {
+            return;
+        }
+        if (mBucket.remove(index)) {
+            unhideViewInternal(view);
+        }
+        mCallback.removeViewAt(index);
+        if (DEBUG) {
+            Log.d(TAG, "remove View off:" + index + "," + this);
+        }
+    }
+
+    /**
+     * Removes the view at the provided index from RecyclerView.
+     *
+     * @param index Index of the child from the regular perspective (excluding hidden views).
+     *              ChildHelper offsets this index to actual ViewGroup index.
+     */
+    void removeViewAt(int index) {
+        final int offset = getOffset(index);
+        final View view = mCallback.getChildAt(offset);
+        if (view == null) {
+            return;
+        }
+        if (mBucket.remove(offset)) {
+            unhideViewInternal(view);
+        }
+        mCallback.removeViewAt(offset);
+        if (DEBUG) {
+            Log.d(TAG, "removeViewAt " + index + ", off:" + offset + ", " + this);
+        }
+    }
+
+    /**
+     * Returns the child at provided index.
+     *
+     * @param index Index of the child to return in regular perspective.
+     */
+    View getChildAt(int index) {
+        final int offset = getOffset(index);
+        return mCallback.getChildAt(offset);
+    }
+
+    /**
+     * Removes all views from the ViewGroup including the hidden ones.
+     */
+    void removeAllViewsUnfiltered() {
+        mBucket.reset();
+        for (int i = mHiddenViews.size() - 1; i >= 0; i--) {
+            mCallback.onLeftHiddenState(mHiddenViews.get(i));
+            mHiddenViews.remove(i);
+        }
+        mCallback.removeAllViews();
+        if (DEBUG) {
+            Log.d(TAG, "removeAllViewsUnfiltered");
+        }
+    }
+
+    /**
+     * This can be used to find a disappearing view by position.
+     *
+     * @param position The adapter position of the item.
+     * @return         A hidden view with a valid ViewHolder that matches the position.
+     */
+    View findHiddenNonRemovedView(int position) {
+        final int count = mHiddenViews.size();
+        for (int i = 0; i < count; i++) {
+            final View view = mHiddenViews.get(i);
+            RecyclerView.ViewHolder holder = mCallback.getChildViewHolder(view);
+            if (holder.getLayoutPosition() == position
+                    && !holder.isInvalid()
+                    && !holder.isRemoved()) {
+                return view;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Attaches the provided view to the underlying ViewGroup.
+     *
+     * @param child        Child to attach.
+     * @param index        Index of the child to attach in regular perspective.
+     * @param layoutParams LayoutParams for the child.
+     * @param hidden       If set to true, this item will be invisible to the regular methods.
+     */
+    void attachViewToParent(View child, int index, ViewGroup.LayoutParams layoutParams,
+            boolean hidden) {
+        final int offset;
+        if (index < 0) {
+            offset = mCallback.getChildCount();
+        } else {
+            offset = getOffset(index);
+        }
+        mBucket.insert(offset, hidden);
+        if (hidden) {
+            hideViewInternal(child);
+        }
+        mCallback.attachViewToParent(child, offset, layoutParams);
+        if (DEBUG) {
+            Log.d(TAG, "attach view to parent index:" + index + ",off:" + offset + ","
+                    + "h:" + hidden + ", " + this);
+        }
+    }
+
+    /**
+     * Returns the number of children that are not hidden.
+     *
+     * @return Number of children that are not hidden.
+     * @see #getChildAt(int)
+     */
+    int getChildCount() {
+        return mCallback.getChildCount() - mHiddenViews.size();
+    }
+
+    /**
+     * Returns the total number of children.
+     *
+     * @return The total number of children including the hidden views.
+     * @see #getUnfilteredChildAt(int)
+     */
+    int getUnfilteredChildCount() {
+        return mCallback.getChildCount();
+    }
+
+    /**
+     * Returns a child by ViewGroup offset. ChildHelper won't offset this index.
+     *
+     * @param index ViewGroup index of the child to return.
+     * @return The view in the provided index.
+     */
+    View getUnfilteredChildAt(int index) {
+        return mCallback.getChildAt(index);
+    }
+
+    /**
+     * Detaches the view at the provided index.
+     *
+     * @param index Index of the child to return in regular perspective.
+     */
+    void detachViewFromParent(int index) {
+        final int offset = getOffset(index);
+        mBucket.remove(offset);
+        mCallback.detachViewFromParent(offset);
+        if (DEBUG) {
+            Log.d(TAG, "detach view from parent " + index + ", off:" + offset);
+        }
+    }
+
+    /**
+     * Returns the index of the child in regular perspective.
+     *
+     * @param child The child whose index will be returned.
+     * @return The regular perspective index of the child or -1 if it does not exists.
+     */
+    int indexOfChild(View child) {
+        final int index = mCallback.indexOfChild(child);
+        if (index == -1) {
+            return -1;
+        }
+        if (mBucket.get(index)) {
+            if (DEBUG) {
+                throw new IllegalArgumentException("cannot get index of a hidden child");
+            } else {
+                return -1;
+            }
+        }
+        // reverse the index
+        return index - mBucket.countOnesBefore(index);
+    }
+
+    /**
+     * Returns whether a View is visible to LayoutManager or not.
+     *
+     * @param view The child view to check. Should be a child of the Callback.
+     * @return True if the View is not visible to LayoutManager
+     */
+    boolean isHidden(View view) {
+        return mHiddenViews.contains(view);
+    }
+
+    /**
+     * Marks a child view as hidden.
+     *
+     * @param view The view to hide.
+     */
+    void hide(View view) {
+        final int offset = mCallback.indexOfChild(view);
+        if (offset < 0) {
+            throw new IllegalArgumentException("view is not a child, cannot hide " + view);
+        }
+        if (DEBUG && mBucket.get(offset)) {
+            throw new RuntimeException("trying to hide same view twice, how come ? " + view);
+        }
+        mBucket.set(offset);
+        hideViewInternal(view);
+        if (DEBUG) {
+            Log.d(TAG, "hiding child " + view + " at offset " + offset + ", " + this);
+        }
+    }
+
+    /**
+     * Moves a child view from hidden list to regular list.
+     * Calling this method should probably be followed by a detach, otherwise, it will suddenly
+     * show up in LayoutManager's children list.
+     *
+     * @param view The hidden View to unhide
+     */
+    void unhide(View view) {
+        final int offset = mCallback.indexOfChild(view);
+        if (offset < 0) {
+            throw new IllegalArgumentException("view is not a child, cannot hide " + view);
+        }
+        if (!mBucket.get(offset)) {
+            throw new RuntimeException("trying to unhide a view that was not hidden" + view);
+        }
+        mBucket.clear(offset);
+        unhideViewInternal(view);
+    }
+
+    @Override
+    public String toString() {
+        return mBucket.toString() + ", hidden list:" + mHiddenViews.size();
+    }
+
+    /**
+     * Removes a view from the ViewGroup if it is hidden.
+     *
+     * @param view The view to remove.
+     * @return True if the View is found and it is hidden. False otherwise.
+     */
+    boolean removeViewIfHidden(View view) {
+        final int index = mCallback.indexOfChild(view);
+        if (index == -1) {
+            if (unhideViewInternal(view) && DEBUG) {
+                throw new IllegalStateException("view is in hidden list but not in view group");
+            }
+            return true;
+        }
+        if (mBucket.get(index)) {
+            mBucket.remove(index);
+            if (!unhideViewInternal(view) && DEBUG) {
+                throw new IllegalStateException(
+                        "removed a hidden view but it is not in hidden views list");
+            }
+            mCallback.removeViewAt(index);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Bitset implementation that provides methods to offset indices.
+     */
+    static class Bucket {
+
+        static final int BITS_PER_WORD = Long.SIZE;
+
+        static final long LAST_BIT = 1L << (Long.SIZE - 1);
+
+        long mData = 0;
+
+        Bucket mNext;
+
+        void set(int index) {
+            if (index >= BITS_PER_WORD) {
+                ensureNext();
+                mNext.set(index - BITS_PER_WORD);
+            } else {
+                mData |= 1L << index;
+            }
+        }
+
+        private void ensureNext() {
+            if (mNext == null) {
+                mNext = new Bucket();
+            }
+        }
+
+        void clear(int index) {
+            if (index >= BITS_PER_WORD) {
+                if (mNext != null) {
+                    mNext.clear(index - BITS_PER_WORD);
+                }
+            } else {
+                mData &= ~(1L << index);
+            }
+
+        }
+
+        boolean get(int index) {
+            if (index >= BITS_PER_WORD) {
+                ensureNext();
+                return mNext.get(index - BITS_PER_WORD);
+            } else {
+                return (mData & (1L << index)) != 0;
+            }
+        }
+
+        void reset() {
+            mData = 0;
+            if (mNext != null) {
+                mNext.reset();
+            }
+        }
+
+        void insert(int index, boolean value) {
+            if (index >= BITS_PER_WORD) {
+                ensureNext();
+                mNext.insert(index - BITS_PER_WORD, value);
+            } else {
+                final boolean lastBit = (mData & LAST_BIT) != 0;
+                long mask = (1L << index) - 1;
+                final long before = mData & mask;
+                final long after = ((mData & ~mask)) << 1;
+                mData = before | after;
+                if (value) {
+                    set(index);
+                } else {
+                    clear(index);
+                }
+                if (lastBit || mNext != null) {
+                    ensureNext();
+                    mNext.insert(0, lastBit);
+                }
+            }
+        }
+
+        boolean remove(int index) {
+            if (index >= BITS_PER_WORD) {
+                ensureNext();
+                return mNext.remove(index - BITS_PER_WORD);
+            } else {
+                long mask = (1L << index);
+                final boolean value = (mData & mask) != 0;
+                mData &= ~mask;
+                mask = mask - 1;
+                final long before = mData & mask;
+                // cannot use >> because it adds one.
+                final long after = Long.rotateRight(mData & ~mask, 1);
+                mData = before | after;
+                if (mNext != null) {
+                    if (mNext.get(0)) {
+                        set(BITS_PER_WORD - 1);
+                    }
+                    mNext.remove(0);
+                }
+                return value;
+            }
+        }
+
+        int countOnesBefore(int index) {
+            if (mNext == null) {
+                if (index >= BITS_PER_WORD) {
+                    return Long.bitCount(mData);
+                }
+                return Long.bitCount(mData & ((1L << index) - 1));
+            }
+            if (index < BITS_PER_WORD) {
+                return Long.bitCount(mData & ((1L << index) - 1));
+            } else {
+                return mNext.countOnesBefore(index - BITS_PER_WORD) + Long.bitCount(mData);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return mNext == null ? Long.toBinaryString(mData)
+                    : mNext.toString() + "xx" + Long.toBinaryString(mData);
+        }
+    }
+
+    interface Callback {
+
+        int getChildCount();
+
+        void addView(View child, int index);
+
+        int indexOfChild(View view);
+
+        void removeViewAt(int index);
+
+        View getChildAt(int offset);
+
+        void removeAllViews();
+
+        RecyclerView.ViewHolder getChildViewHolder(View view);
+
+        void attachViewToParent(View child, int index, ViewGroup.LayoutParams layoutParams);
+
+        void detachViewFromParent(int offset);
+
+        void onEnteredHiddenState(View child);
+
+        void onLeftHiddenState(View child);
+    }
+}
+
diff --git a/core/java/com/android/internal/widget/DefaultItemAnimator.java b/core/java/com/android/internal/widget/DefaultItemAnimator.java
new file mode 100644
index 0000000..92345af
--- /dev/null
+++ b/core/java/com/android/internal/widget/DefaultItemAnimator.java
@@ -0,0 +1,668 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.annotation.NonNull;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+
+import com.android.internal.widget.RecyclerView.ViewHolder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This implementation of {@link RecyclerView.ItemAnimator} provides basic
+ * animations on remove, add, and move events that happen to the items in
+ * a RecyclerView. RecyclerView uses a DefaultItemAnimator by default.
+ *
+ * @see RecyclerView#setItemAnimator(RecyclerView.ItemAnimator)
+ */
+public class DefaultItemAnimator extends SimpleItemAnimator {
+    private static final boolean DEBUG = false;
+
+    private static TimeInterpolator sDefaultInterpolator;
+
+    private ArrayList<ViewHolder> mPendingRemovals = new ArrayList<>();
+    private ArrayList<ViewHolder> mPendingAdditions = new ArrayList<>();
+    private ArrayList<MoveInfo> mPendingMoves = new ArrayList<>();
+    private ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>();
+
+    ArrayList<ArrayList<ViewHolder>> mAdditionsList = new ArrayList<>();
+    ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>();
+    ArrayList<ArrayList<ChangeInfo>> mChangesList = 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;
+
+        MoveInfo(ViewHolder holder, int fromX, int fromY, int toX, int toY) {
+            this.holder = holder;
+            this.fromX = fromX;
+            this.fromY = fromY;
+            this.toX = toX;
+            this.toY = toY;
+        }
+    }
+
+    private static class ChangeInfo {
+        public ViewHolder oldHolder, newHolder;
+        public int fromX, fromY, toX, toY;
+        private ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder) {
+            this.oldHolder = oldHolder;
+            this.newHolder = newHolder;
+        }
+
+        ChangeInfo(ViewHolder oldHolder, ViewHolder newHolder,
+                int fromX, int fromY, int toX, int toY) {
+            this(oldHolder, newHolder);
+            this.fromX = fromX;
+            this.fromY = fromY;
+            this.toX = toX;
+            this.toY = toY;
+        }
+
+        @Override
+        public String toString() {
+            return "ChangeInfo{"
+                    + "oldHolder=" + oldHolder
+                    + ", newHolder=" + newHolder
+                    + ", fromX=" + fromX
+                    + ", fromY=" + fromY
+                    + ", toX=" + toX
+                    + ", toY=" + toY
+                    + '}';
+        }
+    }
+
+    @Override
+    public void runPendingAnimations() {
+        boolean removalsPending = !mPendingRemovals.isEmpty();
+        boolean movesPending = !mPendingMoves.isEmpty();
+        boolean changesPending = !mPendingChanges.isEmpty();
+        boolean additionsPending = !mPendingAdditions.isEmpty();
+        if (!removalsPending && !movesPending && !additionsPending && !changesPending) {
+            // nothing to animate
+            return;
+        }
+        // First, remove stuff
+        for (ViewHolder holder : mPendingRemovals) {
+            animateRemoveImpl(holder);
+        }
+        mPendingRemovals.clear();
+        // Next, move stuff
+        if (movesPending) {
+            final ArrayList<MoveInfo> moves = new ArrayList<>();
+            moves.addAll(mPendingMoves);
+            mMovesList.add(moves);
+            mPendingMoves.clear();
+            Runnable mover = new Runnable() {
+                @Override
+                public void run() {
+                    for (MoveInfo moveInfo : moves) {
+                        animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY,
+                                moveInfo.toX, moveInfo.toY);
+                    }
+                    moves.clear();
+                    mMovesList.remove(moves);
+                }
+            };
+            if (removalsPending) {
+                View view = moves.get(0).holder.itemView;
+                view.postOnAnimationDelayed(mover, getRemoveDuration());
+            } else {
+                mover.run();
+            }
+        }
+        // Next, change stuff, to run in parallel with move animations
+        if (changesPending) {
+            final ArrayList<ChangeInfo> changes = new ArrayList<>();
+            changes.addAll(mPendingChanges);
+            mChangesList.add(changes);
+            mPendingChanges.clear();
+            Runnable changer = new Runnable() {
+                @Override
+                public void run() {
+                    for (ChangeInfo change : changes) {
+                        animateChangeImpl(change);
+                    }
+                    changes.clear();
+                    mChangesList.remove(changes);
+                }
+            };
+            if (removalsPending) {
+                ViewHolder holder = changes.get(0).oldHolder;
+                holder.itemView.postOnAnimationDelayed(changer, getRemoveDuration());
+            } else {
+                changer.run();
+            }
+        }
+        // Next, add stuff
+        if (additionsPending) {
+            final ArrayList<ViewHolder> additions = new ArrayList<>();
+            additions.addAll(mPendingAdditions);
+            mAdditionsList.add(additions);
+            mPendingAdditions.clear();
+            Runnable adder = new Runnable() {
+                @Override
+                public void run() {
+                    for (ViewHolder holder : additions) {
+                        animateAddImpl(holder);
+                    }
+                    additions.clear();
+                    mAdditionsList.remove(additions);
+                }
+            };
+            if (removalsPending || movesPending || changesPending) {
+                long removeDuration = removalsPending ? getRemoveDuration() : 0;
+                long moveDuration = movesPending ? getMoveDuration() : 0;
+                long changeDuration = changesPending ? getChangeDuration() : 0;
+                long totalDelay = removeDuration + Math.max(moveDuration, changeDuration);
+                View view = additions.get(0).itemView;
+                view.postOnAnimationDelayed(adder, totalDelay);
+            } else {
+                adder.run();
+            }
+        }
+    }
+
+    @Override
+    public boolean animateRemove(final ViewHolder holder) {
+        resetAnimation(holder);
+        mPendingRemovals.add(holder);
+        return true;
+    }
+
+    private void animateRemoveImpl(final ViewHolder holder) {
+        final View view = holder.itemView;
+        final ViewPropertyAnimator animation = view.animate();
+        mRemoveAnimations.add(holder);
+        animation.setDuration(getRemoveDuration()).alpha(0).setListener(
+                new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationStart(Animator animator) {
+                        dispatchRemoveStarting(holder);
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Animator animator) {
+                        animation.setListener(null);
+                        view.setAlpha(1);
+                        dispatchRemoveFinished(holder);
+                        mRemoveAnimations.remove(holder);
+                        dispatchFinishedWhenDone();
+                    }
+                }).start();
+    }
+
+    @Override
+    public boolean animateAdd(final ViewHolder holder) {
+        resetAnimation(holder);
+        holder.itemView.setAlpha(0);
+        mPendingAdditions.add(holder);
+        return true;
+    }
+
+    void animateAddImpl(final ViewHolder holder) {
+        final View view = holder.itemView;
+        final ViewPropertyAnimator animation = view.animate();
+        mAddAnimations.add(holder);
+        animation.alpha(1).setDuration(getAddDuration())
+                .setListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationStart(Animator animator) {
+                        dispatchAddStarting(holder);
+                    }
+
+                    @Override
+                    public void onAnimationCancel(Animator animator) {
+                        view.setAlpha(1);
+                    }
+
+                    @Override
+                    public void onAnimationEnd(Animator animator) {
+                        animation.setListener(null);
+                        dispatchAddFinished(holder);
+                        mAddAnimations.remove(holder);
+                        dispatchFinishedWhenDone();
+                    }
+                }).start();
+    }
+
+    @Override
+    public boolean animateMove(final ViewHolder holder, int fromX, int fromY,
+            int toX, int toY) {
+        final View view = holder.itemView;
+        fromX += holder.itemView.getTranslationX();
+        fromY += holder.itemView.getTranslationY();
+        resetAnimation(holder);
+        int deltaX = toX - fromX;
+        int deltaY = toY - fromY;
+        if (deltaX == 0 && deltaY == 0) {
+            dispatchMoveFinished(holder);
+            return false;
+        }
+        if (deltaX != 0) {
+            view.setTranslationX(-deltaX);
+        }
+        if (deltaY != 0) {
+            view.setTranslationY(-deltaY);
+        }
+        mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
+        return true;
+    }
+
+    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;
+        if (deltaX != 0) {
+            view.animate().translationX(0);
+        }
+        if (deltaY != 0) {
+            view.animate().translationY(0);
+        }
+        // TODO: make EndActions end listeners instead, since end actions aren't called when
+        // vpas are canceled (and can't end them. why?)
+        // need listener functionality in VPACompat for this. Ick.
+        final ViewPropertyAnimator animation = view.animate();
+        mMoveAnimations.add(holder);
+        animation.setDuration(getMoveDuration()).setListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animator) {
+                dispatchMoveStarting(holder);
+            }
+
+            @Override
+            public void onAnimationCancel(Animator animator) {
+                if (deltaX != 0) {
+                    view.setTranslationX(0);
+                }
+                if (deltaY != 0) {
+                    view.setTranslationY(0);
+                }
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animator) {
+                animation.setListener(null);
+                dispatchMoveFinished(holder);
+                mMoveAnimations.remove(holder);
+                dispatchFinishedWhenDone();
+            }
+        }).start();
+    }
+
+    @Override
+    public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder,
+            int fromX, int fromY, int toX, int toY) {
+        if (oldHolder == newHolder) {
+            // Don't know how to run change animations when the same view holder is re-used.
+            // run a move animation to handle position changes.
+            return animateMove(oldHolder, fromX, fromY, toX, toY);
+        }
+        final float prevTranslationX = oldHolder.itemView.getTranslationX();
+        final float prevTranslationY = oldHolder.itemView.getTranslationY();
+        final float prevAlpha = oldHolder.itemView.getAlpha();
+        resetAnimation(oldHolder);
+        int deltaX = (int) (toX - fromX - prevTranslationX);
+        int deltaY = (int) (toY - fromY - prevTranslationY);
+        // recover prev translation state after ending animation
+        oldHolder.itemView.setTranslationX(prevTranslationX);
+        oldHolder.itemView.setTranslationY(prevTranslationY);
+        oldHolder.itemView.setAlpha(prevAlpha);
+        if (newHolder != null) {
+            // carry over translation values
+            resetAnimation(newHolder);
+            newHolder.itemView.setTranslationX(-deltaX);
+            newHolder.itemView.setTranslationY(-deltaY);
+            newHolder.itemView.setAlpha(0);
+        }
+        mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
+        return true;
+    }
+
+    void animateChangeImpl(final ChangeInfo changeInfo) {
+        final ViewHolder holder = changeInfo.oldHolder;
+        final View view = holder == null ? null : holder.itemView;
+        final ViewHolder newHolder = changeInfo.newHolder;
+        final View newView = newHolder != null ? newHolder.itemView : null;
+        if (view != null) {
+            final ViewPropertyAnimator oldViewAnim = view.animate().setDuration(
+                    getChangeDuration());
+            mChangeAnimations.add(changeInfo.oldHolder);
+            oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX);
+            oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY);
+            oldViewAnim.alpha(0).setListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animator) {
+                    dispatchChangeStarting(changeInfo.oldHolder, true);
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animator) {
+                    oldViewAnim.setListener(null);
+                    view.setAlpha(1);
+                    view.setTranslationX(0);
+                    view.setTranslationY(0);
+                    dispatchChangeFinished(changeInfo.oldHolder, true);
+                    mChangeAnimations.remove(changeInfo.oldHolder);
+                    dispatchFinishedWhenDone();
+                }
+            }).start();
+        }
+        if (newView != null) {
+            final ViewPropertyAnimator newViewAnimation = newView.animate();
+            mChangeAnimations.add(changeInfo.newHolder);
+            newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration())
+                    .alpha(1).setListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationStart(Animator animator) {
+                            dispatchChangeStarting(changeInfo.newHolder, false);
+                        }
+                        @Override
+                        public void onAnimationEnd(Animator animator) {
+                            newViewAnimation.setListener(null);
+                            newView.setAlpha(1);
+                            newView.setTranslationX(0);
+                            newView.setTranslationY(0);
+                            dispatchChangeFinished(changeInfo.newHolder, false);
+                            mChangeAnimations.remove(changeInfo.newHolder);
+                            dispatchFinishedWhenDone();
+                        }
+                    }).start();
+        }
+    }
+
+    private void endChangeAnimation(List<ChangeInfo> infoList, ViewHolder item) {
+        for (int i = infoList.size() - 1; i >= 0; i--) {
+            ChangeInfo changeInfo = infoList.get(i);
+            if (endChangeAnimationIfNecessary(changeInfo, item)) {
+                if (changeInfo.oldHolder == null && changeInfo.newHolder == null) {
+                    infoList.remove(changeInfo);
+                }
+            }
+        }
+    }
+
+    private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) {
+        if (changeInfo.oldHolder != null) {
+            endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder);
+        }
+        if (changeInfo.newHolder != null) {
+            endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder);
+        }
+    }
+    private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, ViewHolder item) {
+        boolean oldItem = false;
+        if (changeInfo.newHolder == item) {
+            changeInfo.newHolder = null;
+        } else if (changeInfo.oldHolder == item) {
+            changeInfo.oldHolder = null;
+            oldItem = true;
+        } else {
+            return false;
+        }
+        item.itemView.setAlpha(1);
+        item.itemView.setTranslationX(0);
+        item.itemView.setTranslationY(0);
+        dispatchChangeFinished(item, oldItem);
+        return true;
+    }
+
+    @Override
+    public void endAnimation(ViewHolder item) {
+        final View view = item.itemView;
+        // this will trigger end callback which should set properties to their target values.
+        view.animate().cancel();
+        // TODO if some other animations are chained to end, how do we cancel them as well?
+        for (int i = mPendingMoves.size() - 1; i >= 0; i--) {
+            MoveInfo moveInfo = mPendingMoves.get(i);
+            if (moveInfo.holder == item) {
+                view.setTranslationY(0);
+                view.setTranslationX(0);
+                dispatchMoveFinished(item);
+                mPendingMoves.remove(i);
+            }
+        }
+        endChangeAnimation(mPendingChanges, item);
+        if (mPendingRemovals.remove(item)) {
+            view.setAlpha(1);
+            dispatchRemoveFinished(item);
+        }
+        if (mPendingAdditions.remove(item)) {
+            view.setAlpha(1);
+            dispatchAddFinished(item);
+        }
+
+        for (int i = mChangesList.size() - 1; i >= 0; i--) {
+            ArrayList<ChangeInfo> changes = mChangesList.get(i);
+            endChangeAnimation(changes, item);
+            if (changes.isEmpty()) {
+                mChangesList.remove(i);
+            }
+        }
+        for (int i = mMovesList.size() - 1; i >= 0; i--) {
+            ArrayList<MoveInfo> moves = mMovesList.get(i);
+            for (int j = moves.size() - 1; j >= 0; j--) {
+                MoveInfo moveInfo = moves.get(j);
+                if (moveInfo.holder == item) {
+                    view.setTranslationY(0);
+                    view.setTranslationX(0);
+                    dispatchMoveFinished(item);
+                    moves.remove(j);
+                    if (moves.isEmpty()) {
+                        mMovesList.remove(i);
+                    }
+                    break;
+                }
+            }
+        }
+        for (int i = mAdditionsList.size() - 1; i >= 0; i--) {
+            ArrayList<ViewHolder> additions = mAdditionsList.get(i);
+            if (additions.remove(item)) {
+                view.setAlpha(1);
+                dispatchAddFinished(item);
+                if (additions.isEmpty()) {
+                    mAdditionsList.remove(i);
+                }
+            }
+        }
+
+        // animations should be ended by the cancel above.
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        if (mRemoveAnimations.remove(item) && DEBUG) {
+            throw new IllegalStateException("after animation is cancelled, item should not be in "
+                    + "mRemoveAnimations list");
+        }
+
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        if (mAddAnimations.remove(item) && DEBUG) {
+            throw new IllegalStateException("after animation is cancelled, item should not be in "
+                    + "mAddAnimations list");
+        }
+
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        if (mChangeAnimations.remove(item) && DEBUG) {
+            throw new IllegalStateException("after animation is cancelled, item should not be in "
+                    + "mChangeAnimations list");
+        }
+
+        //noinspection PointlessBooleanExpression,ConstantConditions
+        if (mMoveAnimations.remove(item) && DEBUG) {
+            throw new IllegalStateException("after animation is cancelled, item should not be in "
+                    + "mMoveAnimations list");
+        }
+        dispatchFinishedWhenDone();
+    }
+
+    private void resetAnimation(ViewHolder holder) {
+        if (sDefaultInterpolator == null) {
+            sDefaultInterpolator = new ValueAnimator().getInterpolator();
+        }
+        holder.itemView.animate().setInterpolator(sDefaultInterpolator);
+        endAnimation(holder);
+    }
+
+    @Override
+    public boolean isRunning() {
+        return (!mPendingAdditions.isEmpty()
+                || !mPendingChanges.isEmpty()
+                || !mPendingMoves.isEmpty()
+                || !mPendingRemovals.isEmpty()
+                || !mMoveAnimations.isEmpty()
+                || !mRemoveAnimations.isEmpty()
+                || !mAddAnimations.isEmpty()
+                || !mChangeAnimations.isEmpty()
+                || !mMovesList.isEmpty()
+                || !mAdditionsList.isEmpty()
+                || !mChangesList.isEmpty());
+    }
+
+    /**
+     * Check the state of currently pending and running animations. If there are none
+     * pending/running, call {@link #dispatchAnimationsFinished()} to notify any
+     * listeners.
+     */
+    void dispatchFinishedWhenDone() {
+        if (!isRunning()) {
+            dispatchAnimationsFinished();
+        }
+    }
+
+    @Override
+    public void endAnimations() {
+        int count = mPendingMoves.size();
+        for (int i = count - 1; i >= 0; i--) {
+            MoveInfo item = mPendingMoves.get(i);
+            View view = item.holder.itemView;
+            view.setTranslationY(0);
+            view.setTranslationX(0);
+            dispatchMoveFinished(item.holder);
+            mPendingMoves.remove(i);
+        }
+        count = mPendingRemovals.size();
+        for (int i = count - 1; i >= 0; i--) {
+            ViewHolder item = mPendingRemovals.get(i);
+            dispatchRemoveFinished(item);
+            mPendingRemovals.remove(i);
+        }
+        count = mPendingAdditions.size();
+        for (int i = count - 1; i >= 0; i--) {
+            ViewHolder item = mPendingAdditions.get(i);
+            item.itemView.setAlpha(1);
+            dispatchAddFinished(item);
+            mPendingAdditions.remove(i);
+        }
+        count = mPendingChanges.size();
+        for (int i = count - 1; i >= 0; i--) {
+            endChangeAnimationIfNecessary(mPendingChanges.get(i));
+        }
+        mPendingChanges.clear();
+        if (!isRunning()) {
+            return;
+        }
+
+        int listCount = mMovesList.size();
+        for (int i = listCount - 1; i >= 0; i--) {
+            ArrayList<MoveInfo> moves = mMovesList.get(i);
+            count = moves.size();
+            for (int j = count - 1; j >= 0; j--) {
+                MoveInfo moveInfo = moves.get(j);
+                ViewHolder item = moveInfo.holder;
+                View view = item.itemView;
+                view.setTranslationY(0);
+                view.setTranslationX(0);
+                dispatchMoveFinished(moveInfo.holder);
+                moves.remove(j);
+                if (moves.isEmpty()) {
+                    mMovesList.remove(moves);
+                }
+            }
+        }
+        listCount = mAdditionsList.size();
+        for (int i = listCount - 1; i >= 0; i--) {
+            ArrayList<ViewHolder> additions = mAdditionsList.get(i);
+            count = additions.size();
+            for (int j = count - 1; j >= 0; j--) {
+                ViewHolder item = additions.get(j);
+                View view = item.itemView;
+                view.setAlpha(1);
+                dispatchAddFinished(item);
+                additions.remove(j);
+                if (additions.isEmpty()) {
+                    mAdditionsList.remove(additions);
+                }
+            }
+        }
+        listCount = mChangesList.size();
+        for (int i = listCount - 1; i >= 0; i--) {
+            ArrayList<ChangeInfo> changes = mChangesList.get(i);
+            count = changes.size();
+            for (int j = count - 1; j >= 0; j--) {
+                endChangeAnimationIfNecessary(changes.get(j));
+                if (changes.isEmpty()) {
+                    mChangesList.remove(changes);
+                }
+            }
+        }
+
+        cancelAll(mRemoveAnimations);
+        cancelAll(mMoveAnimations);
+        cancelAll(mAddAnimations);
+        cancelAll(mChangeAnimations);
+
+        dispatchAnimationsFinished();
+    }
+
+    void cancelAll(List<ViewHolder> viewHolders) {
+        for (int i = viewHolders.size() - 1; i >= 0; i--) {
+            viewHolders.get(i).itemView.animate().cancel();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * If the payload list is not empty, DefaultItemAnimator returns <code>true</code>.
+     * When this is the case:
+     * <ul>
+     * <li>If you override {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)}, both
+     * ViewHolder arguments will be the same instance.
+     * </li>
+     * <li>
+     * If you are not overriding {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)},
+     * then DefaultItemAnimator will call {@link #animateMove(ViewHolder, int, int, int, int)} and
+     * run a move animation instead.
+     * </li>
+     * </ul>
+     */
+    @Override
+    public boolean canReuseUpdatedViewHolder(@NonNull ViewHolder viewHolder,
+            @NonNull List<Object> payloads) {
+        return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads);
+    }
+}
diff --git a/core/java/com/android/internal/widget/GapWorker.java b/core/java/com/android/internal/widget/GapWorker.java
new file mode 100644
index 0000000..5972396
--- /dev/null
+++ b/core/java/com/android/internal/widget/GapWorker.java
@@ -0,0 +1,379 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.annotation.Nullable;
+import android.os.Trace;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.concurrent.TimeUnit;
+
+final class GapWorker implements Runnable {
+
+    static final ThreadLocal<GapWorker> sGapWorker = new ThreadLocal<>();
+
+    ArrayList<RecyclerView> mRecyclerViews = new ArrayList<>();
+    long mPostTimeNs;
+    long mFrameIntervalNs;
+
+    static class Task {
+        public boolean immediate;
+        public int viewVelocity;
+        public int distanceToItem;
+        public RecyclerView view;
+        public int position;
+
+        public void clear() {
+            immediate = false;
+            viewVelocity = 0;
+            distanceToItem = 0;
+            view = null;
+            position = 0;
+        }
+    }
+
+    /**
+     * Temporary storage for prefetch Tasks that execute in {@link #prefetch(long)}. Task objects
+     * are pooled in the ArrayList, and never removed to avoid allocations, but always cleared
+     * in between calls.
+     */
+    private ArrayList<Task> mTasks = new ArrayList<>();
+
+    /**
+     * Prefetch information associated with a specific RecyclerView.
+     */
+    static class LayoutPrefetchRegistryImpl
+            implements RecyclerView.LayoutManager.LayoutPrefetchRegistry {
+        int mPrefetchDx;
+        int mPrefetchDy;
+        int[] mPrefetchArray;
+
+        int mCount;
+
+        void setPrefetchVector(int dx, int dy) {
+            mPrefetchDx = dx;
+            mPrefetchDy = dy;
+        }
+
+        void collectPrefetchPositionsFromView(RecyclerView view, boolean nested) {
+            mCount = 0;
+            if (mPrefetchArray != null) {
+                Arrays.fill(mPrefetchArray, -1);
+            }
+
+            final RecyclerView.LayoutManager layout = view.mLayout;
+            if (view.mAdapter != null
+                    && layout != null
+                    && layout.isItemPrefetchEnabled()) {
+                if (nested) {
+                    // nested prefetch, only if no adapter updates pending. Note: we don't query
+                    // view.hasPendingAdapterUpdates(), as first layout may not have occurred
+                    if (!view.mAdapterHelper.hasPendingUpdates()) {
+                        layout.collectInitialPrefetchPositions(view.mAdapter.getItemCount(), this);
+                    }
+                } else {
+                    // momentum based prefetch, only if we trust current child/adapter state
+                    if (!view.hasPendingAdapterUpdates()) {
+                        layout.collectAdjacentPrefetchPositions(mPrefetchDx, mPrefetchDy,
+                                view.mState, this);
+                    }
+                }
+
+                if (mCount > layout.mPrefetchMaxCountObserved) {
+                    layout.mPrefetchMaxCountObserved = mCount;
+                    layout.mPrefetchMaxObservedInInitialPrefetch = nested;
+                    view.mRecycler.updateViewCacheSize();
+                }
+            }
+        }
+
+        @Override
+        public void addPosition(int layoutPosition, int pixelDistance) {
+            if (pixelDistance < 0) {
+                throw new IllegalArgumentException("Pixel distance must be non-negative");
+            }
+
+            // allocate or expand array as needed, doubling when needed
+            final int storagePosition = mCount * 2;
+            if (mPrefetchArray == null) {
+                mPrefetchArray = new int[4];
+                Arrays.fill(mPrefetchArray, -1);
+            } else if (storagePosition >= mPrefetchArray.length) {
+                final int[] oldArray = mPrefetchArray;
+                mPrefetchArray = new int[storagePosition * 2];
+                System.arraycopy(oldArray, 0, mPrefetchArray, 0, oldArray.length);
+            }
+
+            // add position
+            mPrefetchArray[storagePosition] = layoutPosition;
+            mPrefetchArray[storagePosition + 1] = pixelDistance;
+
+            mCount++;
+        }
+
+        boolean lastPrefetchIncludedPosition(int position) {
+            if (mPrefetchArray != null) {
+                final int count = mCount * 2;
+                for (int i = 0; i < count; i += 2) {
+                    if (mPrefetchArray[i] == position) return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Called when prefetch indices are no longer valid for cache prioritization.
+         */
+        void clearPrefetchPositions() {
+            if (mPrefetchArray != null) {
+                Arrays.fill(mPrefetchArray, -1);
+            }
+        }
+    }
+
+    public void add(RecyclerView recyclerView) {
+        if (RecyclerView.DEBUG && mRecyclerViews.contains(recyclerView)) {
+            throw new IllegalStateException("RecyclerView already present in worker list!");
+        }
+        mRecyclerViews.add(recyclerView);
+    }
+
+    public void remove(RecyclerView recyclerView) {
+        boolean removeSuccess = mRecyclerViews.remove(recyclerView);
+        if (RecyclerView.DEBUG && !removeSuccess) {
+            throw new IllegalStateException("RecyclerView removal failed!");
+        }
+    }
+
+    /**
+     * Schedule a prefetch immediately after the current traversal.
+     */
+    void postFromTraversal(RecyclerView recyclerView, int prefetchDx, int prefetchDy) {
+        if (recyclerView.isAttachedToWindow()) {
+            if (RecyclerView.DEBUG && !mRecyclerViews.contains(recyclerView)) {
+                throw new IllegalStateException("attempting to post unregistered view!");
+            }
+            if (mPostTimeNs == 0) {
+                mPostTimeNs = recyclerView.getNanoTime();
+                recyclerView.post(this);
+            }
+        }
+
+        recyclerView.mPrefetchRegistry.setPrefetchVector(prefetchDx, prefetchDy);
+    }
+
+    static Comparator<Task> sTaskComparator = new Comparator<Task>() {
+        @Override
+        public int compare(Task lhs, Task rhs) {
+            // first, prioritize non-cleared tasks
+            if ((lhs.view == null) != (rhs.view == null)) {
+                return lhs.view == null ? 1 : -1;
+            }
+
+            // then prioritize immediate
+            if (lhs.immediate != rhs.immediate) {
+                return lhs.immediate ? -1 : 1;
+            }
+
+            // then prioritize _highest_ view velocity
+            int deltaViewVelocity = rhs.viewVelocity - lhs.viewVelocity;
+            if (deltaViewVelocity != 0) return deltaViewVelocity;
+
+            // then prioritize _lowest_ distance to item
+            int deltaDistanceToItem = lhs.distanceToItem - rhs.distanceToItem;
+            if (deltaDistanceToItem != 0) return deltaDistanceToItem;
+
+            return 0;
+        }
+    };
+
+    private void buildTaskList() {
+        // Update PrefetchRegistry in each view
+        final int viewCount = mRecyclerViews.size();
+        int totalTaskCount = 0;
+        for (int i = 0; i < viewCount; i++) {
+            RecyclerView view = mRecyclerViews.get(i);
+            view.mPrefetchRegistry.collectPrefetchPositionsFromView(view, false);
+            totalTaskCount += view.mPrefetchRegistry.mCount;
+        }
+
+        // Populate task list from prefetch data...
+        mTasks.ensureCapacity(totalTaskCount);
+        int totalTaskIndex = 0;
+        for (int i = 0; i < viewCount; i++) {
+            RecyclerView view = mRecyclerViews.get(i);
+            LayoutPrefetchRegistryImpl prefetchRegistry = view.mPrefetchRegistry;
+            final int viewVelocity = Math.abs(prefetchRegistry.mPrefetchDx)
+                    + Math.abs(prefetchRegistry.mPrefetchDy);
+            for (int j = 0; j < prefetchRegistry.mCount * 2; j += 2) {
+                final Task task;
+                if (totalTaskIndex >= mTasks.size()) {
+                    task = new Task();
+                    mTasks.add(task);
+                } else {
+                    task = mTasks.get(totalTaskIndex);
+                }
+                final int distanceToItem = prefetchRegistry.mPrefetchArray[j + 1];
+
+                task.immediate = distanceToItem <= viewVelocity;
+                task.viewVelocity = viewVelocity;
+                task.distanceToItem = distanceToItem;
+                task.view = view;
+                task.position = prefetchRegistry.mPrefetchArray[j];
+
+                totalTaskIndex++;
+            }
+        }
+
+        // ... and priority sort
+        Collections.sort(mTasks, sTaskComparator);
+    }
+
+    static boolean isPrefetchPositionAttached(RecyclerView view, int position) {
+        final int childCount = view.mChildHelper.getUnfilteredChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View attachedView = view.mChildHelper.getUnfilteredChildAt(i);
+            RecyclerView.ViewHolder holder = RecyclerView.getChildViewHolderInt(attachedView);
+            // Note: can use mPosition here because adapter doesn't have pending updates
+            if (holder.mPosition == position && !holder.isInvalid()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private RecyclerView.ViewHolder prefetchPositionWithDeadline(RecyclerView view,
+            int position, long deadlineNs) {
+        if (isPrefetchPositionAttached(view, position)) {
+            // don't attempt to prefetch attached views
+            return null;
+        }
+
+        RecyclerView.Recycler recycler = view.mRecycler;
+        RecyclerView.ViewHolder holder = recycler.tryGetViewHolderForPositionByDeadline(
+                position, false, deadlineNs);
+
+        if (holder != null) {
+            if (holder.isBound()) {
+                // Only give the view a chance to go into the cache if binding succeeded
+                // Note that we must use public method, since item may need cleanup
+                recycler.recycleView(holder.itemView);
+            } else {
+                // Didn't bind, so we can't cache the view, but it will stay in the pool until
+                // next prefetch/traversal. If a View fails to bind, it means we didn't have
+                // enough time prior to the deadline (and won't for other instances of this
+                // type, during this GapWorker prefetch pass).
+                recycler.addViewHolderToRecycledViewPool(holder, false);
+            }
+        }
+        return holder;
+    }
+
+    private void prefetchInnerRecyclerViewWithDeadline(@Nullable RecyclerView innerView,
+            long deadlineNs) {
+        if (innerView == null) {
+            return;
+        }
+
+        if (innerView.mDataSetHasChangedAfterLayout
+                && innerView.mChildHelper.getUnfilteredChildCount() != 0) {
+            // RecyclerView has new data, but old attached views. Clear everything, so that
+            // we can prefetch without partially stale data.
+            innerView.removeAndRecycleViews();
+        }
+
+        // do nested prefetch!
+        final LayoutPrefetchRegistryImpl innerPrefetchRegistry = innerView.mPrefetchRegistry;
+        innerPrefetchRegistry.collectPrefetchPositionsFromView(innerView, true);
+
+        if (innerPrefetchRegistry.mCount != 0) {
+            try {
+                Trace.beginSection(RecyclerView.TRACE_NESTED_PREFETCH_TAG);
+                innerView.mState.prepareForNestedPrefetch(innerView.mAdapter);
+                for (int i = 0; i < innerPrefetchRegistry.mCount * 2; i += 2) {
+                    // Note that we ignore immediate flag for inner items because
+                    // we have lower confidence they're needed next frame.
+                    final int innerPosition = innerPrefetchRegistry.mPrefetchArray[i];
+                    prefetchPositionWithDeadline(innerView, innerPosition, deadlineNs);
+                }
+            } finally {
+                Trace.endSection();
+            }
+        }
+    }
+
+    private void flushTaskWithDeadline(Task task, long deadlineNs) {
+        long taskDeadlineNs = task.immediate ? RecyclerView.FOREVER_NS : deadlineNs;
+        RecyclerView.ViewHolder holder = prefetchPositionWithDeadline(task.view,
+                task.position, taskDeadlineNs);
+        if (holder != null && holder.mNestedRecyclerView != null) {
+            prefetchInnerRecyclerViewWithDeadline(holder.mNestedRecyclerView.get(), deadlineNs);
+        }
+    }
+
+    private void flushTasksWithDeadline(long deadlineNs) {
+        for (int i = 0; i < mTasks.size(); i++) {
+            final Task task = mTasks.get(i);
+            if (task.view == null) {
+                break; // done with populated tasks
+            }
+            flushTaskWithDeadline(task, deadlineNs);
+            task.clear();
+        }
+    }
+
+    void prefetch(long deadlineNs) {
+        buildTaskList();
+        flushTasksWithDeadline(deadlineNs);
+    }
+
+    @Override
+    public void run() {
+        try {
+            Trace.beginSection(RecyclerView.TRACE_PREFETCH_TAG);
+
+            if (mRecyclerViews.isEmpty()) {
+                // abort - no work to do
+                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 lastFrameVsyncNs = TimeUnit.MILLISECONDS.toNanos(
+                    mRecyclerViews.get(0).getDrawingTime());
+            if (lastFrameVsyncNs == 0) {
+                // abort - couldn't get last vsync for estimating next
+                return;
+            }
+
+            // TODO: consider rebasing deadline if frame was already dropped due to long UI work.
+            // Next frame will still wait for VSYNC, so we can still use the gap if it exists.
+            long nextFrameNs = lastFrameVsyncNs + mFrameIntervalNs;
+
+            prefetch(nextFrameNs);
+
+            // TODO: consider rescheduling self, if there's more work to do
+        } finally {
+            mPostTimeNs = 0;
+            Trace.endSection();
+        }
+    }
+}
diff --git a/core/java/com/android/internal/widget/LinearLayoutManager.java b/core/java/com/android/internal/widget/LinearLayoutManager.java
new file mode 100644
index 0000000..d82c746
--- /dev/null
+++ b/core/java/com/android/internal/widget/LinearLayoutManager.java
@@ -0,0 +1,2398 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import static com.android.internal.widget.RecyclerView.NO_POSITION;
+
+import android.content.Context;
+import android.graphics.PointF;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+
+import com.android.internal.widget.RecyclerView.LayoutParams;
+import com.android.internal.widget.helper.ItemTouchHelper;
+
+import java.util.List;
+
+/**
+ * A {@link com.android.internal.widget.RecyclerView.LayoutManager} implementation which provides
+ * similar functionality to {@link android.widget.ListView}.
+ */
+public class LinearLayoutManager extends RecyclerView.LayoutManager implements
+        ItemTouchHelper.ViewDropHandler, RecyclerView.SmoothScroller.ScrollVectorProvider {
+
+    private static final String TAG = "LinearLayoutManager";
+
+    static final boolean DEBUG = false;
+
+    public static final int HORIZONTAL = OrientationHelper.HORIZONTAL;
+
+    public static final int VERTICAL = OrientationHelper.VERTICAL;
+
+    public 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
+     * height minus padding, if layout is horizontal, total space is the width minus padding.
+     */
+    private static final float MAX_SCROLL_FACTOR = 1 / 3f;
+
+
+    /**
+     * Current orientation. Either {@link #HORIZONTAL} or {@link #VERTICAL}
+     */
+    int mOrientation;
+
+    /**
+     * Helper class that keeps temporary layout state.
+     * It does not keep state after layout is complete but we still keep a reference to re-use
+     * the same object.
+     */
+    private LayoutState mLayoutState;
+
+    /**
+     * Many calculations are made depending on orientation. To keep it clean, this interface
+     * helps {@link LinearLayoutManager} make those decisions.
+     * Based on {@link #mOrientation}, an implementation is lazily created in
+     * {@link #ensureLayoutState} method.
+     */
+    OrientationHelper mOrientationHelper;
+
+    /**
+     * We need to track this so that we can ignore current position when it changes.
+     */
+    private boolean mLastStackFromEnd;
+
+
+    /**
+     * Defines if layout should be calculated from end to start.
+     *
+     * @see #mShouldReverseLayout
+     */
+    private boolean mReverseLayout = false;
+
+    /**
+     * This keeps the final value for how LayoutManager should start laying out views.
+     * It is calculated by checking {@link #getReverseLayout()} and View's layout direction.
+     * {@link #onLayoutChildren(RecyclerView.Recycler, RecyclerView.State)} is run.
+     */
+    boolean mShouldReverseLayout = false;
+
+    /**
+     * Works the same way as {@link android.widget.AbsListView#setStackFromBottom(boolean)} and
+     * it supports both orientations.
+     * see {@link android.widget.AbsListView#setStackFromBottom(boolean)}
+     */
+    private boolean mStackFromEnd = false;
+
+    /**
+     * Works the same way as {@link android.widget.AbsListView#setSmoothScrollbarEnabled(boolean)}.
+     * see {@link android.widget.AbsListView#setSmoothScrollbarEnabled(boolean)}
+     */
+    private boolean mSmoothScrollbarEnabled = true;
+
+    /**
+     * When LayoutManager needs to scroll to a position, it sets this variable and requests a
+     * layout which will check this variable and re-layout accordingly.
+     */
+    int mPendingScrollPosition = NO_POSITION;
+
+    /**
+     * Used to keep the offset value when {@link #scrollToPositionWithOffset(int, int)} is
+     * called.
+     */
+    int mPendingScrollPositionOffset = INVALID_OFFSET;
+
+    private boolean mRecycleChildrenOnDetach;
+
+    SavedState mPendingSavedState = null;
+
+    /**
+     *  Re-used variable to keep anchor information on re-layout.
+     *  Anchor position and coordinate defines the reference point for LLM while doing a layout.
+     * */
+    final AnchorInfo mAnchorInfo = new AnchorInfo();
+
+    /**
+     * Stashed to avoid allocation, currently only used in #fill()
+     */
+    private final LayoutChunkResult mLayoutChunkResult = new LayoutChunkResult();
+
+    /**
+     * Number of items to prefetch when first coming on screen with new data.
+     */
+    private int mInitialItemPrefetchCount = 2;
+
+    /**
+     * Creates a vertical LinearLayoutManager
+     *
+     * @param context Current context, will be used to access resources.
+     */
+    public LinearLayoutManager(Context context) {
+        this(context, VERTICAL, false);
+    }
+
+    /**
+     * @param context       Current context, will be used to access resources.
+     * @param orientation   Layout orientation. Should be {@link #HORIZONTAL} or {@link
+     *                      #VERTICAL}.
+     * @param reverseLayout When set to true, layouts from end to start.
+     */
+    public LinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
+        setOrientation(orientation);
+        setReverseLayout(reverseLayout);
+        setAutoMeasureEnabled(true);
+    }
+
+    /**
+     * Constructor used when layout manager is set in XML by RecyclerView attribute
+     * "layoutManager". Defaults to vertical orientation.
+     *
+     * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_android_orientation
+     * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_reverseLayout
+     * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_stackFromEnd
+     */
+    public LinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        Properties properties = getProperties(context, attrs, defStyleAttr, defStyleRes);
+        setOrientation(properties.orientation);
+        setReverseLayout(properties.reverseLayout);
+        setStackFromEnd(properties.stackFromEnd);
+        setAutoMeasureEnabled(true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public LayoutParams generateDefaultLayoutParams() {
+        return new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+    }
+
+    /**
+     * Returns whether LayoutManager will recycle its children when it is detached from
+     * RecyclerView.
+     *
+     * @return true if LayoutManager will recycle its children when it is detached from
+     * RecyclerView.
+     */
+    public boolean getRecycleChildrenOnDetach() {
+        return mRecycleChildrenOnDetach;
+    }
+
+    /**
+     * Set whether LayoutManager will recycle its children when it is detached from
+     * RecyclerView.
+     * <p>
+     * If you are using a {@link RecyclerView.RecycledViewPool}, it might be a good idea to set
+     * this flag to <code>true</code> so that views will be available to other RecyclerViews
+     * immediately.
+     * <p>
+     * Note that, setting this flag will result in a performance drop if RecyclerView
+     * is restored.
+     *
+     * @param recycleChildrenOnDetach Whether children should be recycled in detach or not.
+     */
+    public void setRecycleChildrenOnDetach(boolean recycleChildrenOnDetach) {
+        mRecycleChildrenOnDetach = recycleChildrenOnDetach;
+    }
+
+    @Override
+    public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
+        super.onDetachedFromWindow(view, recycler);
+        if (mRecycleChildrenOnDetach) {
+            removeAndRecycleAllViews(recycler);
+            recycler.clear();
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        if (getChildCount() > 0) {
+            event.setFromIndex(findFirstVisibleItemPosition());
+            event.setToIndex(findLastVisibleItemPosition());
+        }
+    }
+
+    @Override
+    public Parcelable onSaveInstanceState() {
+        if (mPendingSavedState != null) {
+            return new SavedState(mPendingSavedState);
+        }
+        SavedState state = new SavedState();
+        if (getChildCount() > 0) {
+            ensureLayoutState();
+            boolean didLayoutFromEnd = mLastStackFromEnd ^ mShouldReverseLayout;
+            state.mAnchorLayoutFromEnd = didLayoutFromEnd;
+            if (didLayoutFromEnd) {
+                final View refChild = getChildClosestToEnd();
+                state.mAnchorOffset = mOrientationHelper.getEndAfterPadding()
+                        - mOrientationHelper.getDecoratedEnd(refChild);
+                state.mAnchorPosition = getPosition(refChild);
+            } else {
+                final View refChild = getChildClosestToStart();
+                state.mAnchorPosition = getPosition(refChild);
+                state.mAnchorOffset = mOrientationHelper.getDecoratedStart(refChild)
+                        - mOrientationHelper.getStartAfterPadding();
+            }
+        } else {
+            state.invalidateAnchor();
+        }
+        return state;
+    }
+
+    @Override
+    public void onRestoreInstanceState(Parcelable state) {
+        if (state instanceof SavedState) {
+            mPendingSavedState = (SavedState) state;
+            requestLayout();
+            if (DEBUG) {
+                Log.d(TAG, "loaded saved state");
+            }
+        } else if (DEBUG) {
+            Log.d(TAG, "invalid saved state class");
+        }
+    }
+
+    /**
+     * @return true if {@link #getOrientation()} is {@link #HORIZONTAL}
+     */
+    @Override
+    public boolean canScrollHorizontally() {
+        return mOrientation == HORIZONTAL;
+    }
+
+    /**
+     * @return true if {@link #getOrientation()} is {@link #VERTICAL}
+     */
+    @Override
+    public boolean canScrollVertically() {
+        return mOrientation == VERTICAL;
+    }
+
+    /**
+     * Compatibility support for {@link android.widget.AbsListView#setStackFromBottom(boolean)}
+     */
+    public void setStackFromEnd(boolean stackFromEnd) {
+        assertNotInLayoutOrScroll(null);
+        if (mStackFromEnd == stackFromEnd) {
+            return;
+        }
+        mStackFromEnd = stackFromEnd;
+        requestLayout();
+    }
+
+    public boolean getStackFromEnd() {
+        return mStackFromEnd;
+    }
+
+    /**
+     * Returns the current orientation of the layout.
+     *
+     * @return Current orientation,  either {@link #HORIZONTAL} or {@link #VERTICAL}
+     * @see #setOrientation(int)
+     */
+    public int getOrientation() {
+        return mOrientation;
+    }
+
+    /**
+     * Sets the orientation of the layout. {@link com.android.internal.widget.LinearLayoutManager}
+     * will do its best to keep scroll position.
+     *
+     * @param orientation {@link #HORIZONTAL} or {@link #VERTICAL}
+     */
+    public void setOrientation(int orientation) {
+        if (orientation != HORIZONTAL && orientation != VERTICAL) {
+            throw new IllegalArgumentException("invalid orientation:" + orientation);
+        }
+        assertNotInLayoutOrScroll(null);
+        if (orientation == mOrientation) {
+            return;
+        }
+        mOrientation = orientation;
+        mOrientationHelper = null;
+        requestLayout();
+    }
+
+    /**
+     * Calculates the view layout order. (e.g. from end to start or start to end)
+     * RTL layout support is applied automatically. So if layout is RTL and
+     * {@link #getReverseLayout()} is {@code true}, elements will be laid out starting from left.
+     */
+    private void resolveShouldLayoutReverse() {
+        // A == B is the same result, but we rather keep it readable
+        if (mOrientation == VERTICAL || !isLayoutRTL()) {
+            mShouldReverseLayout = mReverseLayout;
+        } else {
+            mShouldReverseLayout = !mReverseLayout;
+        }
+    }
+
+    /**
+     * Returns if views are laid out from the opposite direction of the layout.
+     *
+     * @return If layout is reversed or not.
+     * @see #setReverseLayout(boolean)
+     */
+    public boolean getReverseLayout() {
+        return mReverseLayout;
+    }
+
+    /**
+     * Used to reverse item traversal and layout order.
+     * This behaves similar to the layout change for RTL views. When set to true, first item is
+     * laid out at the end of the UI, second item is laid out before it etc.
+     *
+     * For horizontal layouts, it depends on the layout direction.
+     * When set to true, If {@link com.android.internal.widget.RecyclerView} is LTR, than it will
+     * layout from RTL, if {@link com.android.internal.widget.RecyclerView}} is RTL, it will layout
+     * from LTR.
+     *
+     * If you are looking for the exact same behavior of
+     * {@link android.widget.AbsListView#setStackFromBottom(boolean)}, use
+     * {@link #setStackFromEnd(boolean)}
+     */
+    public void setReverseLayout(boolean reverseLayout) {
+        assertNotInLayoutOrScroll(null);
+        if (reverseLayout == mReverseLayout) {
+            return;
+        }
+        mReverseLayout = reverseLayout;
+        requestLayout();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public View findViewByPosition(int position) {
+        final int childCount = getChildCount();
+        if (childCount == 0) {
+            return null;
+        }
+        final int firstChild = getPosition(getChildAt(0));
+        final int viewPosition = position - firstChild;
+        if (viewPosition >= 0 && viewPosition < childCount) {
+            final View child = getChildAt(viewPosition);
+            if (getPosition(child) == position) {
+                return child; // in pre-layout, this may not match
+            }
+        }
+        // fallback to traversal. This might be necessary in pre-layout.
+        return super.findViewByPosition(position);
+    }
+
+    /**
+     * <p>Returns the amount of extra space that should be laid out by LayoutManager.</p>
+     *
+     * <p>By default, {@link com.android.internal.widget.LinearLayoutManager} lays out 1 extra page
+     * of items while smooth scrolling and 0 otherwise. You can override this method to implement
+     * your custom layout pre-cache logic.</p>
+     *
+     * <p><strong>Note:</strong>Laying out invisible elements generally comes with significant
+     * performance cost. It's typically only desirable in places like smooth scrolling to an unknown
+     * location, where 1) the extra content helps LinearLayoutManager know in advance when its
+     * target is approaching, so it can decelerate early and smoothly and 2) while motion is
+     * continuous.</p>
+     *
+     * <p>Extending the extra layout space is especially expensive if done while the user may change
+     * scrolling direction. Changing direction will cause the extra layout space to swap to the
+     * opposite side of the viewport, incurring many rebinds/recycles, unless the cache is large
+     * enough to handle it.</p>
+     *
+     * @return The extra space that should be laid out (in pixels).
+     */
+    protected int getExtraLayoutSpace(RecyclerView.State state) {
+        if (state.hasTargetScrollPosition()) {
+            return mOrientationHelper.getTotalSpace();
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
+            int position) {
+        LinearSmoothScroller linearSmoothScroller =
+                new LinearSmoothScroller(recyclerView.getContext());
+        linearSmoothScroller.setTargetPosition(position);
+        startSmoothScroll(linearSmoothScroller);
+    }
+
+    @Override
+    public PointF computeScrollVectorForPosition(int targetPosition) {
+        if (getChildCount() == 0) {
+            return null;
+        }
+        final int firstChildPos = getPosition(getChildAt(0));
+        final int direction = targetPosition < firstChildPos != mShouldReverseLayout ? -1 : 1;
+        if (mOrientation == HORIZONTAL) {
+            return new PointF(direction, 0);
+        } else {
+            return new PointF(0, direction);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+        // layout algorithm:
+        // 1) by checking children and other variables, find an anchor coordinate and an anchor
+        //  item position.
+        // 2) fill towards start, stacking from bottom
+        // 3) fill towards end, stacking from top
+        // 4) scroll to fulfill requirements like stack from bottom.
+        // create layout state
+        if (DEBUG) {
+            Log.d(TAG, "is pre layout:" + state.isPreLayout());
+        }
+        if (mPendingSavedState != null || mPendingScrollPosition != NO_POSITION) {
+            if (state.getItemCount() == 0) {
+                removeAndRecycleAllViews(recycler);
+                return;
+            }
+        }
+        if (mPendingSavedState != null && mPendingSavedState.hasValidAnchor()) {
+            mPendingScrollPosition = mPendingSavedState.mAnchorPosition;
+        }
+
+        ensureLayoutState();
+        mLayoutState.mRecycle = false;
+        // resolve layout direction
+        resolveShouldLayoutReverse();
+
+        if (!mAnchorInfo.mValid || mPendingScrollPosition != NO_POSITION
+                || mPendingSavedState != null) {
+            mAnchorInfo.reset();
+            mAnchorInfo.mLayoutFromEnd = mShouldReverseLayout ^ mStackFromEnd;
+            // calculate anchor position and coordinate
+            updateAnchorInfoForLayout(recycler, state, mAnchorInfo);
+            mAnchorInfo.mValid = true;
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Anchor info:" + mAnchorInfo);
+        }
+
+        // LLM may decide to layout items for "extra" pixels to account for scrolling target,
+        // caching or predictive animations.
+        int extraForStart;
+        int extraForEnd;
+        final int extra = getExtraLayoutSpace(state);
+        // If the previous scroll delta was less than zero, the extra space should be laid out
+        // at the start. Otherwise, it should be at the end.
+        if (mLayoutState.mLastScrollDelta >= 0) {
+            extraForEnd = extra;
+            extraForStart = 0;
+        } else {
+            extraForStart = extra;
+            extraForEnd = 0;
+        }
+        extraForStart += mOrientationHelper.getStartAfterPadding();
+        extraForEnd += mOrientationHelper.getEndPadding();
+        if (state.isPreLayout() && mPendingScrollPosition != NO_POSITION
+                && mPendingScrollPositionOffset != INVALID_OFFSET) {
+            // if the child is visible and we are going to move it around, we should layout
+            // extra items in the opposite direction to make sure new items animate nicely
+            // instead of just fading in
+            final View existing = findViewByPosition(mPendingScrollPosition);
+            if (existing != null) {
+                final int current;
+                final int upcomingOffset;
+                if (mShouldReverseLayout) {
+                    current = mOrientationHelper.getEndAfterPadding()
+                            - mOrientationHelper.getDecoratedEnd(existing);
+                    upcomingOffset = current - mPendingScrollPositionOffset;
+                } else {
+                    current = mOrientationHelper.getDecoratedStart(existing)
+                            - mOrientationHelper.getStartAfterPadding();
+                    upcomingOffset = mPendingScrollPositionOffset - current;
+                }
+                if (upcomingOffset > 0) {
+                    extraForStart += upcomingOffset;
+                } else {
+                    extraForEnd -= upcomingOffset;
+                }
+            }
+        }
+        int startOffset;
+        int endOffset;
+        final int firstLayoutDirection;
+        if (mAnchorInfo.mLayoutFromEnd) {
+            firstLayoutDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_TAIL
+                    : LayoutState.ITEM_DIRECTION_HEAD;
+        } else {
+            firstLayoutDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_HEAD
+                    : LayoutState.ITEM_DIRECTION_TAIL;
+        }
+
+        onAnchorReady(recycler, state, mAnchorInfo, firstLayoutDirection);
+        detachAndScrapAttachedViews(recycler);
+        mLayoutState.mInfinite = resolveIsInfinite();
+        mLayoutState.mIsPreLayout = state.isPreLayout();
+        if (mAnchorInfo.mLayoutFromEnd) {
+            // fill towards start
+            updateLayoutStateToFillStart(mAnchorInfo);
+            mLayoutState.mExtra = extraForStart;
+            fill(recycler, mLayoutState, state, false);
+            startOffset = mLayoutState.mOffset;
+            final int firstElement = mLayoutState.mCurrentPosition;
+            if (mLayoutState.mAvailable > 0) {
+                extraForEnd += mLayoutState.mAvailable;
+            }
+            // fill towards end
+            updateLayoutStateToFillEnd(mAnchorInfo);
+            mLayoutState.mExtra = extraForEnd;
+            mLayoutState.mCurrentPosition += mLayoutState.mItemDirection;
+            fill(recycler, mLayoutState, state, false);
+            endOffset = mLayoutState.mOffset;
+
+            if (mLayoutState.mAvailable > 0) {
+                // end could not consume all. add more items towards start
+                extraForStart = mLayoutState.mAvailable;
+                updateLayoutStateToFillStart(firstElement, startOffset);
+                mLayoutState.mExtra = extraForStart;
+                fill(recycler, mLayoutState, state, false);
+                startOffset = mLayoutState.mOffset;
+            }
+        } else {
+            // fill towards end
+            updateLayoutStateToFillEnd(mAnchorInfo);
+            mLayoutState.mExtra = extraForEnd;
+            fill(recycler, mLayoutState, state, false);
+            endOffset = mLayoutState.mOffset;
+            final int lastElement = mLayoutState.mCurrentPosition;
+            if (mLayoutState.mAvailable > 0) {
+                extraForStart += mLayoutState.mAvailable;
+            }
+            // fill towards start
+            updateLayoutStateToFillStart(mAnchorInfo);
+            mLayoutState.mExtra = extraForStart;
+            mLayoutState.mCurrentPosition += mLayoutState.mItemDirection;
+            fill(recycler, mLayoutState, state, false);
+            startOffset = mLayoutState.mOffset;
+
+            if (mLayoutState.mAvailable > 0) {
+                extraForEnd = mLayoutState.mAvailable;
+                // start could not consume all it should. add more items towards end
+                updateLayoutStateToFillEnd(lastElement, endOffset);
+                mLayoutState.mExtra = extraForEnd;
+                fill(recycler, mLayoutState, state, false);
+                endOffset = mLayoutState.mOffset;
+            }
+        }
+
+        // changes may cause gaps on the UI, try to fix them.
+        // TODO we can probably avoid this if neither stackFromEnd/reverseLayout/RTL values have
+        // changed
+        if (getChildCount() > 0) {
+            // because layout from end may be changed by scroll to position
+            // we re-calculate it.
+            // find which side we should check for gaps.
+            if (mShouldReverseLayout ^ mStackFromEnd) {
+                int fixOffset = fixLayoutEndGap(endOffset, recycler, state, true);
+                startOffset += fixOffset;
+                endOffset += fixOffset;
+                fixOffset = fixLayoutStartGap(startOffset, recycler, state, false);
+                startOffset += fixOffset;
+                endOffset += fixOffset;
+            } else {
+                int fixOffset = fixLayoutStartGap(startOffset, recycler, state, true);
+                startOffset += fixOffset;
+                endOffset += fixOffset;
+                fixOffset = fixLayoutEndGap(endOffset, recycler, state, false);
+                startOffset += fixOffset;
+                endOffset += fixOffset;
+            }
+        }
+        layoutForPredictiveAnimations(recycler, state, startOffset, endOffset);
+        if (!state.isPreLayout()) {
+            mOrientationHelper.onLayoutComplete();
+        } else {
+            mAnchorInfo.reset();
+        }
+        mLastStackFromEnd = mStackFromEnd;
+        if (DEBUG) {
+            validateChildOrder();
+        }
+    }
+
+    @Override
+    public void onLayoutCompleted(RecyclerView.State state) {
+        super.onLayoutCompleted(state);
+        mPendingSavedState = null; // we don't need this anymore
+        mPendingScrollPosition = NO_POSITION;
+        mPendingScrollPositionOffset = INVALID_OFFSET;
+        mAnchorInfo.reset();
+    }
+
+    /**
+     * Method called when Anchor position is decided. Extending class can setup accordingly or
+     * even update anchor info if necessary.
+     * @param recycler The recycler for the layout
+     * @param state The layout state
+     * @param anchorInfo The mutable POJO that keeps the position and offset.
+     * @param firstLayoutItemDirection The direction of the first layout filling in terms of adapter
+     *                                 indices.
+     */
+    void onAnchorReady(RecyclerView.Recycler recycler, RecyclerView.State state,
+            AnchorInfo anchorInfo, int firstLayoutItemDirection) {
+    }
+
+    /**
+     * If necessary, layouts new items for predictive animations
+     */
+    private void layoutForPredictiveAnimations(RecyclerView.Recycler recycler,
+            RecyclerView.State state, int startOffset,  int endOffset) {
+        // If there are scrap children that we did not layout, we need to find where they did go
+        // and layout them accordingly so that animations can work as expected.
+        // This case may happen if new views are added or an existing view expands and pushes
+        // another view out of bounds.
+        if (!state.willRunPredictiveAnimations() ||  getChildCount() == 0 || state.isPreLayout()
+                || !supportsPredictiveItemAnimations()) {
+            return;
+        }
+        // to make the logic simpler, we calculate the size of children and call fill.
+        int scrapExtraStart = 0, scrapExtraEnd = 0;
+        final List<RecyclerView.ViewHolder> scrapList = recycler.getScrapList();
+        final int scrapSize = scrapList.size();
+        final int firstChildPos = getPosition(getChildAt(0));
+        for (int i = 0; i < scrapSize; i++) {
+            RecyclerView.ViewHolder scrap = scrapList.get(i);
+            if (scrap.isRemoved()) {
+                continue;
+            }
+            final int position = scrap.getLayoutPosition();
+            final int direction = position < firstChildPos != mShouldReverseLayout
+                    ? LayoutState.LAYOUT_START : LayoutState.LAYOUT_END;
+            if (direction == LayoutState.LAYOUT_START) {
+                scrapExtraStart += mOrientationHelper.getDecoratedMeasurement(scrap.itemView);
+            } else {
+                scrapExtraEnd += mOrientationHelper.getDecoratedMeasurement(scrap.itemView);
+            }
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "for unused scrap, decided to add " + scrapExtraStart
+                    + " towards start and " + scrapExtraEnd + " towards end");
+        }
+        mLayoutState.mScrapList = scrapList;
+        if (scrapExtraStart > 0) {
+            View anchor = getChildClosestToStart();
+            updateLayoutStateToFillStart(getPosition(anchor), startOffset);
+            mLayoutState.mExtra = scrapExtraStart;
+            mLayoutState.mAvailable = 0;
+            mLayoutState.assignPositionFromScrapList();
+            fill(recycler, mLayoutState, state, false);
+        }
+
+        if (scrapExtraEnd > 0) {
+            View anchor = getChildClosestToEnd();
+            updateLayoutStateToFillEnd(getPosition(anchor), endOffset);
+            mLayoutState.mExtra = scrapExtraEnd;
+            mLayoutState.mAvailable = 0;
+            mLayoutState.assignPositionFromScrapList();
+            fill(recycler, mLayoutState, state, false);
+        }
+        mLayoutState.mScrapList = null;
+    }
+
+    private void updateAnchorInfoForLayout(RecyclerView.Recycler recycler, RecyclerView.State state,
+            AnchorInfo anchorInfo) {
+        if (updateAnchorFromPendingData(state, anchorInfo)) {
+            if (DEBUG) {
+                Log.d(TAG, "updated anchor info from pending information");
+            }
+            return;
+        }
+
+        if (updateAnchorFromChildren(recycler, state, anchorInfo)) {
+            if (DEBUG) {
+                Log.d(TAG, "updated anchor info from existing children");
+            }
+            return;
+        }
+        if (DEBUG) {
+            Log.d(TAG, "deciding anchor info for fresh state");
+        }
+        anchorInfo.assignCoordinateFromPadding();
+        anchorInfo.mPosition = mStackFromEnd ? state.getItemCount() - 1 : 0;
+    }
+
+    /**
+     * Finds an anchor child from existing Views. Most of the time, this is the view closest to
+     * start or end that has a valid position (e.g. not removed).
+     * <p>
+     * If a child has focus, it is given priority.
+     */
+    private boolean updateAnchorFromChildren(RecyclerView.Recycler recycler,
+            RecyclerView.State state, AnchorInfo anchorInfo) {
+        if (getChildCount() == 0) {
+            return false;
+        }
+        final View focused = getFocusedChild();
+        if (focused != null && anchorInfo.isViewValidAsAnchor(focused, state)) {
+            anchorInfo.assignFromViewAndKeepVisibleRect(focused);
+            return true;
+        }
+        if (mLastStackFromEnd != mStackFromEnd) {
+            return false;
+        }
+        View referenceChild = anchorInfo.mLayoutFromEnd
+                ? findReferenceChildClosestToEnd(recycler, state)
+                : findReferenceChildClosestToStart(recycler, state);
+        if (referenceChild != null) {
+            anchorInfo.assignFromView(referenceChild);
+            // If all visible views are removed in 1 pass, reference child might be out of bounds.
+            // If that is the case, offset it back to 0 so that we use these pre-layout children.
+            if (!state.isPreLayout() && supportsPredictiveItemAnimations()) {
+                // validate this child is at least partially visible. if not, offset it to start
+                final boolean notVisible =
+                        mOrientationHelper.getDecoratedStart(referenceChild) >= mOrientationHelper
+                                .getEndAfterPadding()
+                                || mOrientationHelper.getDecoratedEnd(referenceChild)
+                                < mOrientationHelper.getStartAfterPadding();
+                if (notVisible) {
+                    anchorInfo.mCoordinate = anchorInfo.mLayoutFromEnd
+                            ? mOrientationHelper.getEndAfterPadding()
+                            : mOrientationHelper.getStartAfterPadding();
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * If there is a pending scroll position or saved states, updates the anchor info from that
+     * data and returns true
+     */
+    private boolean updateAnchorFromPendingData(RecyclerView.State state, AnchorInfo anchorInfo) {
+        if (state.isPreLayout() || mPendingScrollPosition == NO_POSITION) {
+            return false;
+        }
+        // validate scroll position
+        if (mPendingScrollPosition < 0 || mPendingScrollPosition >= state.getItemCount()) {
+            mPendingScrollPosition = NO_POSITION;
+            mPendingScrollPositionOffset = INVALID_OFFSET;
+            if (DEBUG) {
+                Log.e(TAG, "ignoring invalid scroll position " + mPendingScrollPosition);
+            }
+            return false;
+        }
+
+        // if child is visible, try to make it a reference child and ensure it is fully visible.
+        // if child is not visible, align it depending on its virtual position.
+        anchorInfo.mPosition = mPendingScrollPosition;
+        if (mPendingSavedState != null && mPendingSavedState.hasValidAnchor()) {
+            // Anchor offset depends on how that child was laid out. Here, we update it
+            // according to our current view bounds
+            anchorInfo.mLayoutFromEnd = mPendingSavedState.mAnchorLayoutFromEnd;
+            if (anchorInfo.mLayoutFromEnd) {
+                anchorInfo.mCoordinate = mOrientationHelper.getEndAfterPadding()
+                        - mPendingSavedState.mAnchorOffset;
+            } else {
+                anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding()
+                        + mPendingSavedState.mAnchorOffset;
+            }
+            return true;
+        }
+
+        if (mPendingScrollPositionOffset == INVALID_OFFSET) {
+            View child = findViewByPosition(mPendingScrollPosition);
+            if (child != null) {
+                final int childSize = mOrientationHelper.getDecoratedMeasurement(child);
+                if (childSize > mOrientationHelper.getTotalSpace()) {
+                    // item does not fit. fix depending on layout direction
+                    anchorInfo.assignCoordinateFromPadding();
+                    return true;
+                }
+                final int startGap = mOrientationHelper.getDecoratedStart(child)
+                        - mOrientationHelper.getStartAfterPadding();
+                if (startGap < 0) {
+                    anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding();
+                    anchorInfo.mLayoutFromEnd = false;
+                    return true;
+                }
+                final int endGap = mOrientationHelper.getEndAfterPadding()
+                        - mOrientationHelper.getDecoratedEnd(child);
+                if (endGap < 0) {
+                    anchorInfo.mCoordinate = mOrientationHelper.getEndAfterPadding();
+                    anchorInfo.mLayoutFromEnd = true;
+                    return true;
+                }
+                anchorInfo.mCoordinate = anchorInfo.mLayoutFromEnd
+                        ? (mOrientationHelper.getDecoratedEnd(child) + mOrientationHelper
+                                .getTotalSpaceChange())
+                        : mOrientationHelper.getDecoratedStart(child);
+            } else { // item is not visible.
+                if (getChildCount() > 0) {
+                    // get position of any child, does not matter
+                    int pos = getPosition(getChildAt(0));
+                    anchorInfo.mLayoutFromEnd = mPendingScrollPosition < pos
+                            == mShouldReverseLayout;
+                }
+                anchorInfo.assignCoordinateFromPadding();
+            }
+            return true;
+        }
+        // override layout from end values for consistency
+        anchorInfo.mLayoutFromEnd = mShouldReverseLayout;
+        // if this changes, we should update prepareForDrop as well
+        if (mShouldReverseLayout) {
+            anchorInfo.mCoordinate = mOrientationHelper.getEndAfterPadding()
+                    - mPendingScrollPositionOffset;
+        } else {
+            anchorInfo.mCoordinate = mOrientationHelper.getStartAfterPadding()
+                    + mPendingScrollPositionOffset;
+        }
+        return true;
+    }
+
+    /**
+     * @return The final offset amount for children
+     */
+    private int fixLayoutEndGap(int endOffset, RecyclerView.Recycler recycler,
+            RecyclerView.State state, boolean canOffsetChildren) {
+        int gap = mOrientationHelper.getEndAfterPadding() - endOffset;
+        int fixOffset = 0;
+        if (gap > 0) {
+            fixOffset = -scrollBy(-gap, recycler, state);
+        } else {
+            return 0; // nothing to fix
+        }
+        // move offset according to scroll amount
+        endOffset += fixOffset;
+        if (canOffsetChildren) {
+            // re-calculate gap, see if we could fix it
+            gap = mOrientationHelper.getEndAfterPadding() - endOffset;
+            if (gap > 0) {
+                mOrientationHelper.offsetChildren(gap);
+                return gap + fixOffset;
+            }
+        }
+        return fixOffset;
+    }
+
+    /**
+     * @return The final offset amount for children
+     */
+    private int fixLayoutStartGap(int startOffset, RecyclerView.Recycler recycler,
+            RecyclerView.State state, boolean canOffsetChildren) {
+        int gap = startOffset - mOrientationHelper.getStartAfterPadding();
+        int fixOffset = 0;
+        if (gap > 0) {
+            // check if we should fix this gap.
+            fixOffset = -scrollBy(gap, recycler, state);
+        } else {
+            return 0; // nothing to fix
+        }
+        startOffset += fixOffset;
+        if (canOffsetChildren) {
+            // re-calculate gap, see if we could fix it
+            gap = startOffset - mOrientationHelper.getStartAfterPadding();
+            if (gap > 0) {
+                mOrientationHelper.offsetChildren(-gap);
+                return fixOffset - gap;
+            }
+        }
+        return fixOffset;
+    }
+
+    private void updateLayoutStateToFillEnd(AnchorInfo anchorInfo) {
+        updateLayoutStateToFillEnd(anchorInfo.mPosition, anchorInfo.mCoordinate);
+    }
+
+    private void updateLayoutStateToFillEnd(int itemPosition, int offset) {
+        mLayoutState.mAvailable = mOrientationHelper.getEndAfterPadding() - offset;
+        mLayoutState.mItemDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_HEAD :
+                LayoutState.ITEM_DIRECTION_TAIL;
+        mLayoutState.mCurrentPosition = itemPosition;
+        mLayoutState.mLayoutDirection = LayoutState.LAYOUT_END;
+        mLayoutState.mOffset = offset;
+        mLayoutState.mScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN;
+    }
+
+    private void updateLayoutStateToFillStart(AnchorInfo anchorInfo) {
+        updateLayoutStateToFillStart(anchorInfo.mPosition, anchorInfo.mCoordinate);
+    }
+
+    private void updateLayoutStateToFillStart(int itemPosition, int offset) {
+        mLayoutState.mAvailable = offset - mOrientationHelper.getStartAfterPadding();
+        mLayoutState.mCurrentPosition = itemPosition;
+        mLayoutState.mItemDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_TAIL :
+                LayoutState.ITEM_DIRECTION_HEAD;
+        mLayoutState.mLayoutDirection = LayoutState.LAYOUT_START;
+        mLayoutState.mOffset = offset;
+        mLayoutState.mScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN;
+
+    }
+
+    protected boolean isLayoutRTL() {
+        return getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+    }
+
+    void ensureLayoutState() {
+        if (mLayoutState == null) {
+            mLayoutState = createLayoutState();
+        }
+        if (mOrientationHelper == null) {
+            mOrientationHelper = OrientationHelper.createOrientationHelper(this, mOrientation);
+        }
+    }
+
+    /**
+     * Test overrides this to plug some tracking and verification.
+     *
+     * @return A new LayoutState
+     */
+    LayoutState createLayoutState() {
+        return new LayoutState();
+    }
+
+    /**
+     * <p>Scroll the RecyclerView to make the position visible.</p>
+     *
+     * <p>RecyclerView will scroll the minimum amount that is necessary to make the
+     * target position visible. If you are looking for a similar behavior to
+     * {@link android.widget.ListView#setSelection(int)} or
+     * {@link android.widget.ListView#setSelectionFromTop(int, int)}, use
+     * {@link #scrollToPositionWithOffset(int, int)}.</p>
+     *
+     * <p>Note that scroll position change will not be reflected until the next layout call.</p>
+     *
+     * @param position Scroll to this adapter position
+     * @see #scrollToPositionWithOffset(int, int)
+     */
+    @Override
+    public void scrollToPosition(int position) {
+        mPendingScrollPosition = position;
+        mPendingScrollPositionOffset = INVALID_OFFSET;
+        if (mPendingSavedState != null) {
+            mPendingSavedState.invalidateAnchor();
+        }
+        requestLayout();
+    }
+
+    /**
+     * Scroll to the specified adapter position with the given offset from resolved layout
+     * start. Resolved layout start depends on {@link #getReverseLayout()},
+     * {@link View#getLayoutDirection()} and {@link #getStackFromEnd()}.
+     * <p>
+     * For example, if layout is {@link #VERTICAL} and {@link #getStackFromEnd()} is true, calling
+     * <code>scrollToPositionWithOffset(10, 20)</code> will layout such that
+     * <code>item[10]</code>'s bottom is 20 pixels above the RecyclerView's bottom.
+     * <p>
+     * Note that scroll position change will not be reflected until the next layout call.
+     * <p>
+     * If you are just trying to make a position visible, use {@link #scrollToPosition(int)}.
+     *
+     * @param position Index (starting at 0) of the reference item.
+     * @param offset   The distance (in pixels) between the start edge of the item view and
+     *                 start edge of the RecyclerView.
+     * @see #setReverseLayout(boolean)
+     * @see #scrollToPosition(int)
+     */
+    public void scrollToPositionWithOffset(int position, int offset) {
+        mPendingScrollPosition = position;
+        mPendingScrollPositionOffset = offset;
+        if (mPendingSavedState != null) {
+            mPendingSavedState.invalidateAnchor();
+        }
+        requestLayout();
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        if (mOrientation == VERTICAL) {
+            return 0;
+        }
+        return scrollBy(dx, recycler, state);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        if (mOrientation == HORIZONTAL) {
+            return 0;
+        }
+        return scrollBy(dy, recycler, state);
+    }
+
+    @Override
+    public int computeHorizontalScrollOffset(RecyclerView.State state) {
+        return computeScrollOffset(state);
+    }
+
+    @Override
+    public int computeVerticalScrollOffset(RecyclerView.State state) {
+        return computeScrollOffset(state);
+    }
+
+    @Override
+    public int computeHorizontalScrollExtent(RecyclerView.State state) {
+        return computeScrollExtent(state);
+    }
+
+    @Override
+    public int computeVerticalScrollExtent(RecyclerView.State state) {
+        return computeScrollExtent(state);
+    }
+
+    @Override
+    public int computeHorizontalScrollRange(RecyclerView.State state) {
+        return computeScrollRange(state);
+    }
+
+    @Override
+    public int computeVerticalScrollRange(RecyclerView.State state) {
+        return computeScrollRange(state);
+    }
+
+    private int computeScrollOffset(RecyclerView.State state) {
+        if (getChildCount() == 0) {
+            return 0;
+        }
+        ensureLayoutState();
+        return ScrollbarHelper.computeScrollOffset(state, mOrientationHelper,
+                findFirstVisibleChildClosestToStart(!mSmoothScrollbarEnabled, true),
+                findFirstVisibleChildClosestToEnd(!mSmoothScrollbarEnabled, true),
+                this, mSmoothScrollbarEnabled, mShouldReverseLayout);
+    }
+
+    private int computeScrollExtent(RecyclerView.State state) {
+        if (getChildCount() == 0) {
+            return 0;
+        }
+        ensureLayoutState();
+        return ScrollbarHelper.computeScrollExtent(state, mOrientationHelper,
+                findFirstVisibleChildClosestToStart(!mSmoothScrollbarEnabled, true),
+                findFirstVisibleChildClosestToEnd(!mSmoothScrollbarEnabled, true),
+                this,  mSmoothScrollbarEnabled);
+    }
+
+    private int computeScrollRange(RecyclerView.State state) {
+        if (getChildCount() == 0) {
+            return 0;
+        }
+        ensureLayoutState();
+        return ScrollbarHelper.computeScrollRange(state, mOrientationHelper,
+                findFirstVisibleChildClosestToStart(!mSmoothScrollbarEnabled, true),
+                findFirstVisibleChildClosestToEnd(!mSmoothScrollbarEnabled, true),
+                this, mSmoothScrollbarEnabled);
+    }
+
+    /**
+     * When smooth scrollbar is enabled, the position and size of the scrollbar thumb is computed
+     * based on the number of visible pixels in the visible items. This however assumes that all
+     * list items have similar or equal widths or heights (depending on list orientation).
+     * If you use a list in which items have different dimensions, the scrollbar will change
+     * appearance as the user scrolls through the list. To avoid this issue,  you need to disable
+     * this property.
+     *
+     * When smooth scrollbar is disabled, the position and size of the scrollbar thumb is based
+     * solely on the number of items in the adapter and the position of the visible items inside
+     * the adapter. This provides a stable scrollbar as the user navigates through a list of items
+     * with varying widths / heights.
+     *
+     * @param enabled Whether or not to enable smooth scrollbar.
+     *
+     * @see #setSmoothScrollbarEnabled(boolean)
+     */
+    public void setSmoothScrollbarEnabled(boolean enabled) {
+        mSmoothScrollbarEnabled = enabled;
+    }
+
+    /**
+     * Returns the current state of the smooth scrollbar feature. It is enabled by default.
+     *
+     * @return True if smooth scrollbar is enabled, false otherwise.
+     *
+     * @see #setSmoothScrollbarEnabled(boolean)
+     */
+    public boolean isSmoothScrollbarEnabled() {
+        return mSmoothScrollbarEnabled;
+    }
+
+    private void updateLayoutState(int layoutDirection, int requiredSpace,
+            boolean canUseExistingSpace, RecyclerView.State state) {
+        // If parent provides a hint, don't measure unlimited.
+        mLayoutState.mInfinite = resolveIsInfinite();
+        mLayoutState.mExtra = getExtraLayoutSpace(state);
+        mLayoutState.mLayoutDirection = layoutDirection;
+        int scrollingOffset;
+        if (layoutDirection == LayoutState.LAYOUT_END) {
+            mLayoutState.mExtra += mOrientationHelper.getEndPadding();
+            // get the first child in the direction we are going
+            final View child = getChildClosestToEnd();
+            // the direction in which we are traversing children
+            mLayoutState.mItemDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_HEAD
+                    : LayoutState.ITEM_DIRECTION_TAIL;
+            mLayoutState.mCurrentPosition = getPosition(child) + mLayoutState.mItemDirection;
+            mLayoutState.mOffset = mOrientationHelper.getDecoratedEnd(child);
+            // calculate how much we can scroll without adding new children (independent of layout)
+            scrollingOffset = mOrientationHelper.getDecoratedEnd(child)
+                    - mOrientationHelper.getEndAfterPadding();
+
+        } else {
+            final View child = getChildClosestToStart();
+            mLayoutState.mExtra += mOrientationHelper.getStartAfterPadding();
+            mLayoutState.mItemDirection = mShouldReverseLayout ? LayoutState.ITEM_DIRECTION_TAIL
+                    : LayoutState.ITEM_DIRECTION_HEAD;
+            mLayoutState.mCurrentPosition = getPosition(child) + mLayoutState.mItemDirection;
+            mLayoutState.mOffset = mOrientationHelper.getDecoratedStart(child);
+            scrollingOffset = -mOrientationHelper.getDecoratedStart(child)
+                    + mOrientationHelper.getStartAfterPadding();
+        }
+        mLayoutState.mAvailable = requiredSpace;
+        if (canUseExistingSpace) {
+            mLayoutState.mAvailable -= scrollingOffset;
+        }
+        mLayoutState.mScrollingOffset = scrollingOffset;
+    }
+
+    boolean resolveIsInfinite() {
+        return mOrientationHelper.getMode() == View.MeasureSpec.UNSPECIFIED
+                && mOrientationHelper.getEnd() == 0;
+    }
+
+    void collectPrefetchPositionsForLayoutState(RecyclerView.State state, LayoutState layoutState,
+            LayoutPrefetchRegistry layoutPrefetchRegistry) {
+        final int pos = layoutState.mCurrentPosition;
+        if (pos >= 0 && pos < state.getItemCount()) {
+            layoutPrefetchRegistry.addPosition(pos, layoutState.mScrollingOffset);
+        }
+    }
+
+    @Override
+    public void collectInitialPrefetchPositions(int adapterItemCount,
+            LayoutPrefetchRegistry layoutPrefetchRegistry) {
+        final boolean fromEnd;
+        final int anchorPos;
+        if (mPendingSavedState != null && mPendingSavedState.hasValidAnchor()) {
+            // use restored state, since it hasn't been resolved yet
+            fromEnd = mPendingSavedState.mAnchorLayoutFromEnd;
+            anchorPos = mPendingSavedState.mAnchorPosition;
+        } else {
+            resolveShouldLayoutReverse();
+            fromEnd = mShouldReverseLayout;
+            if (mPendingScrollPosition == NO_POSITION) {
+                anchorPos = fromEnd ? adapterItemCount - 1 : 0;
+            } else {
+                anchorPos = mPendingScrollPosition;
+            }
+        }
+
+        final int direction = fromEnd
+                ? LayoutState.ITEM_DIRECTION_HEAD
+                : LayoutState.ITEM_DIRECTION_TAIL;
+        int targetPos = anchorPos;
+        for (int i = 0; i < mInitialItemPrefetchCount; i++) {
+            if (targetPos >= 0 && targetPos < adapterItemCount) {
+                layoutPrefetchRegistry.addPosition(targetPos, 0);
+            } else {
+                break; // no more to prefetch
+            }
+            targetPos += direction;
+        }
+    }
+
+    /**
+     * Sets the number of items to prefetch in
+     * {@link #collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)}, which defines
+     * how many inner items should be prefetched when this LayoutManager's RecyclerView
+     * is nested inside another RecyclerView.
+     *
+     * <p>Set this value to the number of items this inner LayoutManager will display when it is
+     * first scrolled into the viewport. RecyclerView will attempt to prefetch that number of items
+     * so they are ready, avoiding jank as the inner RecyclerView is scrolled into the viewport.</p>
+     *
+     * <p>For example, take a vertically scrolling RecyclerView with horizontally scrolling inner
+     * RecyclerViews. The rows always have 4 items visible in them (or 5 if not aligned). Passing
+     * <code>4</code> to this method for each inner RecyclerView's LinearLayoutManager will enable
+     * RecyclerView's prefetching feature to do create/bind work for 4 views within a row early,
+     * before it is scrolled on screen, instead of just the default 2.</p>
+     *
+     * <p>Calling this method does nothing unless the LayoutManager is in a RecyclerView
+     * nested in another RecyclerView.</p>
+     *
+     * <p class="note"><strong>Note:</strong> Setting this value to be larger than the number of
+     * views that will be visible in this view can incur unnecessary bind work, and an increase to
+     * the number of Views created and in active use.</p>
+     *
+     * @param itemCount Number of items to prefetch
+     *
+     * @see #isItemPrefetchEnabled()
+     * @see #getInitialItemPrefetchCount()
+     * @see #collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)
+     */
+    public void setInitialPrefetchItemCount(int itemCount) {
+        mInitialItemPrefetchCount = itemCount;
+    }
+
+    /**
+     * Gets the number of items to prefetch in
+     * {@link #collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)}, which defines
+     * how many inner items should be prefetched when this LayoutManager's RecyclerView
+     * is nested inside another RecyclerView.
+     *
+     * @see #isItemPrefetchEnabled()
+     * @see #setInitialPrefetchItemCount(int)
+     * @see #collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)
+     *
+     * @return number of items to prefetch.
+     */
+    public int getInitialItemPrefetchCount() {
+        return mInitialItemPrefetchCount;
+    }
+
+    @Override
+    public void collectAdjacentPrefetchPositions(int dx, int dy, RecyclerView.State state,
+            LayoutPrefetchRegistry layoutPrefetchRegistry) {
+        int delta = (mOrientation == HORIZONTAL) ? dx : dy;
+        if (getChildCount() == 0 || delta == 0) {
+            // can't support this scroll, so don't bother prefetching
+            return;
+        }
+
+        final int layoutDirection = delta > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START;
+        final int absDy = Math.abs(delta);
+        updateLayoutState(layoutDirection, absDy, true, state);
+        collectPrefetchPositionsForLayoutState(state, mLayoutState, layoutPrefetchRegistry);
+    }
+
+    int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
+        if (getChildCount() == 0 || dy == 0) {
+            return 0;
+        }
+        mLayoutState.mRecycle = true;
+        ensureLayoutState();
+        final int layoutDirection = dy > 0 ? LayoutState.LAYOUT_END : LayoutState.LAYOUT_START;
+        final int absDy = Math.abs(dy);
+        updateLayoutState(layoutDirection, absDy, true, state);
+        final int consumed = mLayoutState.mScrollingOffset
+                + fill(recycler, mLayoutState, state, false);
+        if (consumed < 0) {
+            if (DEBUG) {
+                Log.d(TAG, "Don't have any more elements to scroll");
+            }
+            return 0;
+        }
+        final int scrolled = absDy > consumed ? layoutDirection * consumed : dy;
+        mOrientationHelper.offsetChildren(-scrolled);
+        if (DEBUG) {
+            Log.d(TAG, "scroll req: " + dy + " scrolled: " + scrolled);
+        }
+        mLayoutState.mLastScrollDelta = scrolled;
+        return scrolled;
+    }
+
+    @Override
+    public void assertNotInLayoutOrScroll(String message) {
+        if (mPendingSavedState == null) {
+            super.assertNotInLayoutOrScroll(message);
+        }
+    }
+
+    /**
+     * Recycles children between given indices.
+     *
+     * @param startIndex inclusive
+     * @param endIndex   exclusive
+     */
+    private void recycleChildren(RecyclerView.Recycler recycler, int startIndex, int endIndex) {
+        if (startIndex == endIndex) {
+            return;
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Recycling " + Math.abs(startIndex - endIndex) + " items");
+        }
+        if (endIndex > startIndex) {
+            for (int i = endIndex - 1; i >= startIndex; i--) {
+                removeAndRecycleViewAt(i, recycler);
+            }
+        } else {
+            for (int i = startIndex; i > endIndex; i--) {
+                removeAndRecycleViewAt(i, recycler);
+            }
+        }
+    }
+
+    /**
+     * Recycles views that went out of bounds after scrolling towards the end of the layout.
+     * <p>
+     * Checks both layout position and visible position to guarantee that the view is not visible.
+     *
+     * @param recycler Recycler instance of {@link com.android.internal.widget.RecyclerView}
+     * @param dt       This can be used to add additional padding to the visible area. This is used
+     *                 to detect children that will go out of bounds after scrolling, without
+     *                 actually moving them.
+     */
+    private void recycleViewsFromStart(RecyclerView.Recycler recycler, int dt) {
+        if (dt < 0) {
+            if (DEBUG) {
+                Log.d(TAG, "Called recycle from start with a negative value. This might happen"
+                        + " during layout changes but may be sign of a bug");
+            }
+            return;
+        }
+        // ignore padding, ViewGroup may not clip children.
+        final int limit = dt;
+        final int childCount = getChildCount();
+        if (mShouldReverseLayout) {
+            for (int i = childCount - 1; i >= 0; i--) {
+                View child = getChildAt(i);
+                if (mOrientationHelper.getDecoratedEnd(child) > limit
+                        || mOrientationHelper.getTransformedEndWithDecoration(child) > limit) {
+                    // stop here
+                    recycleChildren(recycler, childCount - 1, i);
+                    return;
+                }
+            }
+        } else {
+            for (int i = 0; i < childCount; i++) {
+                View child = getChildAt(i);
+                if (mOrientationHelper.getDecoratedEnd(child) > limit
+                        || mOrientationHelper.getTransformedEndWithDecoration(child) > limit) {
+                    // stop here
+                    recycleChildren(recycler, 0, i);
+                    return;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Recycles views that went out of bounds after scrolling towards the start of the layout.
+     * <p>
+     * Checks both layout position and visible position to guarantee that the view is not visible.
+     *
+     * @param recycler Recycler instance of {@link com.android.internal.widget.RecyclerView}
+     * @param dt       This can be used to add additional padding to the visible area. This is used
+     *                 to detect children that will go out of bounds after scrolling, without
+     *                 actually moving them.
+     */
+    private void recycleViewsFromEnd(RecyclerView.Recycler recycler, int dt) {
+        final int childCount = getChildCount();
+        if (dt < 0) {
+            if (DEBUG) {
+                Log.d(TAG, "Called recycle from end with a negative value. This might happen"
+                        + " during layout changes but may be sign of a bug");
+            }
+            return;
+        }
+        final int limit = mOrientationHelper.getEnd() - dt;
+        if (mShouldReverseLayout) {
+            for (int i = 0; i < childCount; i++) {
+                View child = getChildAt(i);
+                if (mOrientationHelper.getDecoratedStart(child) < limit
+                        || mOrientationHelper.getTransformedStartWithDecoration(child) < limit) {
+                    // stop here
+                    recycleChildren(recycler, 0, i);
+                    return;
+                }
+            }
+        } else {
+            for (int i = childCount - 1; i >= 0; i--) {
+                View child = getChildAt(i);
+                if (mOrientationHelper.getDecoratedStart(child) < limit
+                        || mOrientationHelper.getTransformedStartWithDecoration(child) < limit) {
+                    // stop here
+                    recycleChildren(recycler, childCount - 1, i);
+                    return;
+                }
+            }
+        }
+    }
+
+    /**
+     * Helper method to call appropriate recycle method depending on current layout direction
+     *
+     * @param recycler    Current recycler that is attached to RecyclerView
+     * @param layoutState Current layout state. Right now, this object does not change but
+     *                    we may consider moving it out of this view so passing around as a
+     *                    parameter for now, rather than accessing {@link #mLayoutState}
+     * @see #recycleViewsFromStart(com.android.internal.widget.RecyclerView.Recycler, int)
+     * @see #recycleViewsFromEnd(com.android.internal.widget.RecyclerView.Recycler, int)
+     * @see com.android.internal.widget.LinearLayoutManager.LayoutState#mLayoutDirection
+     */
+    private void recycleByLayoutState(RecyclerView.Recycler recycler, LayoutState layoutState) {
+        if (!layoutState.mRecycle || layoutState.mInfinite) {
+            return;
+        }
+        if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) {
+            recycleViewsFromEnd(recycler, layoutState.mScrollingOffset);
+        } else {
+            recycleViewsFromStart(recycler, layoutState.mScrollingOffset);
+        }
+    }
+
+    /**
+     * The magic functions :). Fills the given layout, defined by the layoutState. This is fairly
+     * independent from the rest of the {@link com.android.internal.widget.LinearLayoutManager}
+     * and with little change, can be made publicly available as a helper class.
+     *
+     * @param recycler        Current recycler that is attached to RecyclerView
+     * @param layoutState     Configuration on how we should fill out the available space.
+     * @param state           Context passed by the RecyclerView to control scroll steps.
+     * @param stopOnFocusable If true, filling stops in the first focusable new child
+     * @return Number of pixels that it added. Useful for scroll functions.
+     */
+    int fill(RecyclerView.Recycler recycler, LayoutState layoutState,
+            RecyclerView.State state, boolean stopOnFocusable) {
+        // max offset we should set is mFastScroll + available
+        final int start = layoutState.mAvailable;
+        if (layoutState.mScrollingOffset != LayoutState.SCROLLING_OFFSET_NaN) {
+            // TODO ugly bug fix. should not happen
+            if (layoutState.mAvailable < 0) {
+                layoutState.mScrollingOffset += layoutState.mAvailable;
+            }
+            recycleByLayoutState(recycler, layoutState);
+        }
+        int remainingSpace = layoutState.mAvailable + layoutState.mExtra;
+        LayoutChunkResult layoutChunkResult = mLayoutChunkResult;
+        while ((layoutState.mInfinite || remainingSpace > 0) && layoutState.hasMore(state)) {
+            layoutChunkResult.resetInternal();
+            layoutChunk(recycler, state, layoutState, layoutChunkResult);
+            if (layoutChunkResult.mFinished) {
+                break;
+            }
+            layoutState.mOffset += layoutChunkResult.mConsumed * layoutState.mLayoutDirection;
+            /**
+             * Consume the available space if:
+             * * layoutChunk did not request to be ignored
+             * * OR we are laying out scrap children
+             * * OR we are not doing pre-layout
+             */
+            if (!layoutChunkResult.mIgnoreConsumed || mLayoutState.mScrapList != null
+                    || !state.isPreLayout()) {
+                layoutState.mAvailable -= layoutChunkResult.mConsumed;
+                // we keep a separate remaining space because mAvailable is important for recycling
+                remainingSpace -= layoutChunkResult.mConsumed;
+            }
+
+            if (layoutState.mScrollingOffset != LayoutState.SCROLLING_OFFSET_NaN) {
+                layoutState.mScrollingOffset += layoutChunkResult.mConsumed;
+                if (layoutState.mAvailable < 0) {
+                    layoutState.mScrollingOffset += layoutState.mAvailable;
+                }
+                recycleByLayoutState(recycler, layoutState);
+            }
+            if (stopOnFocusable && layoutChunkResult.mFocusable) {
+                break;
+            }
+        }
+        if (DEBUG) {
+            validateChildOrder();
+        }
+        return start - layoutState.mAvailable;
+    }
+
+    void layoutChunk(RecyclerView.Recycler recycler, RecyclerView.State state,
+            LayoutState layoutState, LayoutChunkResult result) {
+        View view = layoutState.next(recycler);
+        if (view == null) {
+            if (DEBUG && layoutState.mScrapList == null) {
+                throw new RuntimeException("received null view when unexpected");
+            }
+            // if we are laying out views in scrap, this may return null which means there is
+            // no more items to layout.
+            result.mFinished = true;
+            return;
+        }
+        LayoutParams params = (LayoutParams) view.getLayoutParams();
+        if (layoutState.mScrapList == null) {
+            if (mShouldReverseLayout == (layoutState.mLayoutDirection
+                    == LayoutState.LAYOUT_START)) {
+                addView(view);
+            } else {
+                addView(view, 0);
+            }
+        } else {
+            if (mShouldReverseLayout == (layoutState.mLayoutDirection
+                    == LayoutState.LAYOUT_START)) {
+                addDisappearingView(view);
+            } else {
+                addDisappearingView(view, 0);
+            }
+        }
+        measureChildWithMargins(view, 0, 0);
+        result.mConsumed = mOrientationHelper.getDecoratedMeasurement(view);
+        int left, top, right, bottom;
+        if (mOrientation == VERTICAL) {
+            if (isLayoutRTL()) {
+                right = getWidth() - getPaddingRight();
+                left = right - mOrientationHelper.getDecoratedMeasurementInOther(view);
+            } else {
+                left = getPaddingLeft();
+                right = left + mOrientationHelper.getDecoratedMeasurementInOther(view);
+            }
+            if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) {
+                bottom = layoutState.mOffset;
+                top = layoutState.mOffset - result.mConsumed;
+            } else {
+                top = layoutState.mOffset;
+                bottom = layoutState.mOffset + result.mConsumed;
+            }
+        } else {
+            top = getPaddingTop();
+            bottom = top + mOrientationHelper.getDecoratedMeasurementInOther(view);
+
+            if (layoutState.mLayoutDirection == LayoutState.LAYOUT_START) {
+                right = layoutState.mOffset;
+                left = layoutState.mOffset - result.mConsumed;
+            } else {
+                left = layoutState.mOffset;
+                right = layoutState.mOffset + result.mConsumed;
+            }
+        }
+        // We calculate everything with View's bounding box (which includes decor and margins)
+        // To calculate correct layout position, we subtract margins.
+        layoutDecoratedWithMargins(view, left, top, right, bottom);
+        if (DEBUG) {
+            Log.d(TAG, "laid out child at position " + getPosition(view) + ", with l:"
+                    + (left + params.leftMargin) + ", t:" + (top + params.topMargin) + ", r:"
+                    + (right - params.rightMargin) + ", b:" + (bottom - params.bottomMargin));
+        }
+        // Consume the available space if the view is not removed OR changed
+        if (params.isItemRemoved() || params.isItemChanged()) {
+            result.mIgnoreConsumed = true;
+        }
+        result.mFocusable = view.isFocusable();
+    }
+
+    @Override
+    boolean shouldMeasureTwice() {
+        return getHeightMode() != View.MeasureSpec.EXACTLY
+                && getWidthMode() != View.MeasureSpec.EXACTLY
+                && hasFlexibleChildInBothOrientations();
+    }
+
+    /**
+     * Converts a focusDirection to orientation.
+     *
+     * @param focusDirection One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
+     *                       {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT},
+     *                       {@link View#FOCUS_BACKWARD}, {@link View#FOCUS_FORWARD}
+     *                       or 0 for not applicable
+     * @return {@link LayoutState#LAYOUT_START} or {@link LayoutState#LAYOUT_END} if focus direction
+     * is applicable to current state, {@link LayoutState#INVALID_LAYOUT} otherwise.
+     */
+    int convertFocusDirectionToLayoutDirection(int focusDirection) {
+        switch (focusDirection) {
+            case View.FOCUS_BACKWARD:
+                if (mOrientation == VERTICAL) {
+                    return LayoutState.LAYOUT_START;
+                } else if (isLayoutRTL()) {
+                    return LayoutState.LAYOUT_END;
+                } else {
+                    return LayoutState.LAYOUT_START;
+                }
+            case View.FOCUS_FORWARD:
+                if (mOrientation == VERTICAL) {
+                    return LayoutState.LAYOUT_END;
+                } else if (isLayoutRTL()) {
+                    return LayoutState.LAYOUT_START;
+                } else {
+                    return LayoutState.LAYOUT_END;
+                }
+            case View.FOCUS_UP:
+                return mOrientation == VERTICAL ? LayoutState.LAYOUT_START
+                        : LayoutState.INVALID_LAYOUT;
+            case View.FOCUS_DOWN:
+                return mOrientation == VERTICAL ? LayoutState.LAYOUT_END
+                        : LayoutState.INVALID_LAYOUT;
+            case View.FOCUS_LEFT:
+                return mOrientation == HORIZONTAL ? LayoutState.LAYOUT_START
+                        : LayoutState.INVALID_LAYOUT;
+            case View.FOCUS_RIGHT:
+                return mOrientation == HORIZONTAL ? LayoutState.LAYOUT_END
+                        : LayoutState.INVALID_LAYOUT;
+            default:
+                if (DEBUG) {
+                    Log.d(TAG, "Unknown focus request:" + focusDirection);
+                }
+                return LayoutState.INVALID_LAYOUT;
+        }
+
+    }
+
+    /**
+     * Convenience method to find the child closes to start. Caller should check it has enough
+     * children.
+     *
+     * @return The child closes to start of the layout from user's perspective.
+     */
+    private View getChildClosestToStart() {
+        return getChildAt(mShouldReverseLayout ? getChildCount() - 1 : 0);
+    }
+
+    /**
+     * Convenience method to find the child closes to end. Caller should check it has enough
+     * children.
+     *
+     * @return The child closes to end of the layout from user's perspective.
+     */
+    private View getChildClosestToEnd() {
+        return getChildAt(mShouldReverseLayout ? 0 : getChildCount() - 1);
+    }
+
+    /**
+     * Convenience method to find the visible child closes to start. Caller should check if it has
+     * enough children.
+     *
+     * @param completelyVisible Whether child should be completely visible or not
+     * @return The first visible child closest to start of the layout from user's perspective.
+     */
+    private View findFirstVisibleChildClosestToStart(boolean completelyVisible,
+            boolean acceptPartiallyVisible) {
+        if (mShouldReverseLayout) {
+            return findOneVisibleChild(getChildCount() - 1, -1, completelyVisible,
+                    acceptPartiallyVisible);
+        } else {
+            return findOneVisibleChild(0, getChildCount(), completelyVisible,
+                    acceptPartiallyVisible);
+        }
+    }
+
+    /**
+     * Convenience method to find the visible child closes to end. Caller should check if it has
+     * enough children.
+     *
+     * @param completelyVisible Whether child should be completely visible or not
+     * @return The first visible child closest to end of the layout from user's perspective.
+     */
+    private View findFirstVisibleChildClosestToEnd(boolean completelyVisible,
+            boolean acceptPartiallyVisible) {
+        if (mShouldReverseLayout) {
+            return findOneVisibleChild(0, getChildCount(), completelyVisible,
+                    acceptPartiallyVisible);
+        } else {
+            return findOneVisibleChild(getChildCount() - 1, -1, completelyVisible,
+                    acceptPartiallyVisible);
+        }
+    }
+
+
+    /**
+     * Among the children that are suitable to be considered as an anchor child, returns the one
+     * closest to the end of the layout.
+     * <p>
+     * Due to ambiguous adapter updates or children being removed, some children's positions may be
+     * invalid. This method is a best effort to find a position within adapter bounds if possible.
+     * <p>
+     * It also prioritizes children that are within the visible bounds.
+     * @return A View that can be used an an anchor View.
+     */
+    private View findReferenceChildClosestToEnd(RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        return mShouldReverseLayout ? findFirstReferenceChild(recycler, state) :
+                findLastReferenceChild(recycler, state);
+    }
+
+    /**
+     * Among the children that are suitable to be considered as an anchor child, returns the one
+     * closest to the start of the layout.
+     * <p>
+     * Due to ambiguous adapter updates or children being removed, some children's positions may be
+     * invalid. This method is a best effort to find a position within adapter bounds if possible.
+     * <p>
+     * It also prioritizes children that are within the visible bounds.
+     *
+     * @return A View that can be used an an anchor View.
+     */
+    private View findReferenceChildClosestToStart(RecyclerView.Recycler recycler,
+            RecyclerView.State state) {
+        return mShouldReverseLayout ? findLastReferenceChild(recycler, state) :
+                findFirstReferenceChild(recycler, state);
+    }
+
+    private View findFirstReferenceChild(RecyclerView.Recycler recycler, RecyclerView.State state) {
+        return findReferenceChild(recycler, state, 0, getChildCount(), state.getItemCount());
+    }
+
+    private View findLastReferenceChild(RecyclerView.Recycler recycler, RecyclerView.State state) {
+        return findReferenceChild(recycler, state, getChildCount() - 1, -1, state.getItemCount());
+    }
+
+    // overridden by GridLayoutManager
+    View findReferenceChild(RecyclerView.Recycler recycler, RecyclerView.State state,
+            int start, int end, int itemCount) {
+        ensureLayoutState();
+        View invalidMatch = null;
+        View outOfBoundsMatch = null;
+        final int boundsStart = mOrientationHelper.getStartAfterPadding();
+        final int boundsEnd = mOrientationHelper.getEndAfterPadding();
+        final int diff = end > start ? 1 : -1;
+        for (int i = start; i != end; i += diff) {
+            final View view = getChildAt(i);
+            final int position = getPosition(view);
+            if (position >= 0 && position < itemCount) {
+                if (((LayoutParams) view.getLayoutParams()).isItemRemoved()) {
+                    if (invalidMatch == null) {
+                        invalidMatch = view; // removed item, least preferred
+                    }
+                } else if (mOrientationHelper.getDecoratedStart(view) >= boundsEnd
+                        || mOrientationHelper.getDecoratedEnd(view) < boundsStart) {
+                    if (outOfBoundsMatch == null) {
+                        outOfBoundsMatch = view; // item is not visible, less preferred
+                    }
+                } else {
+                    return view;
+                }
+            }
+        }
+        return outOfBoundsMatch != null ? outOfBoundsMatch : invalidMatch;
+    }
+
+    /**
+     * Returns the adapter position of the first visible view. This position does not include
+     * adapter changes that were dispatched after the last layout pass.
+     * <p>
+     * Note that, this value is not affected by layout orientation or item order traversal.
+     * ({@link #setReverseLayout(boolean)}). Views are sorted by their positions in the adapter,
+     * not in the layout.
+     * <p>
+     * If RecyclerView has item decorators, they will be considered in calculations as well.
+     * <p>
+     * LayoutManager may pre-cache some views that are not necessarily visible. Those views
+     * are ignored in this method.
+     *
+     * @return The adapter position of the first visible item or {@link RecyclerView#NO_POSITION} if
+     * there aren't any visible items.
+     * @see #findFirstCompletelyVisibleItemPosition()
+     * @see #findLastVisibleItemPosition()
+     */
+    public int findFirstVisibleItemPosition() {
+        final View child = findOneVisibleChild(0, getChildCount(), false, true);
+        return child == null ? NO_POSITION : getPosition(child);
+    }
+
+    /**
+     * Returns the adapter position of the first fully visible view. This position does not include
+     * adapter changes that were dispatched after the last layout pass.
+     * <p>
+     * Note that bounds check is only performed in the current orientation. That means, if
+     * LayoutManager is horizontal, it will only check the view's left and right edges.
+     *
+     * @return The adapter position of the first fully visible item or
+     * {@link RecyclerView#NO_POSITION} if there aren't any visible items.
+     * @see #findFirstVisibleItemPosition()
+     * @see #findLastCompletelyVisibleItemPosition()
+     */
+    public int findFirstCompletelyVisibleItemPosition() {
+        final View child = findOneVisibleChild(0, getChildCount(), true, false);
+        return child == null ? NO_POSITION : getPosition(child);
+    }
+
+    /**
+     * Returns the adapter position of the last visible view. This position does not include
+     * adapter changes that were dispatched after the last layout pass.
+     * <p>
+     * Note that, this value is not affected by layout orientation or item order traversal.
+     * ({@link #setReverseLayout(boolean)}). Views are sorted by their positions in the adapter,
+     * not in the layout.
+     * <p>
+     * If RecyclerView has item decorators, they will be considered in calculations as well.
+     * <p>
+     * LayoutManager may pre-cache some views that are not necessarily visible. Those views
+     * are ignored in this method.
+     *
+     * @return The adapter position of the last visible view or {@link RecyclerView#NO_POSITION} if
+     * there aren't any visible items.
+     * @see #findLastCompletelyVisibleItemPosition()
+     * @see #findFirstVisibleItemPosition()
+     */
+    public int findLastVisibleItemPosition() {
+        final View child = findOneVisibleChild(getChildCount() - 1, -1, false, true);
+        return child == null ? NO_POSITION : getPosition(child);
+    }
+
+    /**
+     * Returns the adapter position of the last fully visible view. This position does not include
+     * adapter changes that were dispatched after the last layout pass.
+     * <p>
+     * Note that bounds check is only performed in the current orientation. That means, if
+     * LayoutManager is horizontal, it will only check the view's left and right edges.
+     *
+     * @return The adapter position of the last fully visible view or
+     * {@link RecyclerView#NO_POSITION} if there aren't any visible items.
+     * @see #findLastVisibleItemPosition()
+     * @see #findFirstCompletelyVisibleItemPosition()
+     */
+    public int findLastCompletelyVisibleItemPosition() {
+        final View child = findOneVisibleChild(getChildCount() - 1, -1, true, false);
+        return child == null ? NO_POSITION : getPosition(child);
+    }
+
+    View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible,
+            boolean acceptPartiallyVisible) {
+        ensureLayoutState();
+        final int start = mOrientationHelper.getStartAfterPadding();
+        final int end = mOrientationHelper.getEndAfterPadding();
+        final int next = toIndex > fromIndex ? 1 : -1;
+        View partiallyVisible = null;
+        for (int i = fromIndex; i != toIndex; i += next) {
+            final View child = getChildAt(i);
+            final int childStart = mOrientationHelper.getDecoratedStart(child);
+            final int childEnd = mOrientationHelper.getDecoratedEnd(child);
+            if (childStart < end && childEnd > start) {
+                if (completelyVisible) {
+                    if (childStart >= start && childEnd <= end) {
+                        return child;
+                    } else if (acceptPartiallyVisible && partiallyVisible == null) {
+                        partiallyVisible = child;
+                    }
+                } else {
+                    return child;
+                }
+            }
+        }
+        return partiallyVisible;
+    }
+
+    @Override
+    public View onFocusSearchFailed(View focused, int focusDirection,
+            RecyclerView.Recycler recycler, RecyclerView.State state) {
+        resolveShouldLayoutReverse();
+        if (getChildCount() == 0) {
+            return null;
+        }
+
+        final int layoutDir = convertFocusDirectionToLayoutDirection(focusDirection);
+        if (layoutDir == LayoutState.INVALID_LAYOUT) {
+            return null;
+        }
+        ensureLayoutState();
+        final View referenceChild;
+        if (layoutDir == LayoutState.LAYOUT_START) {
+            referenceChild = findReferenceChildClosestToStart(recycler, state);
+        } else {
+            referenceChild = findReferenceChildClosestToEnd(recycler, state);
+        }
+        if (referenceChild == null) {
+            if (DEBUG) {
+                Log.d(TAG,
+                        "Cannot find a child with a valid position to be used for focus search.");
+            }
+            return null;
+        }
+        ensureLayoutState();
+        final int maxScroll = (int) (MAX_SCROLL_FACTOR * mOrientationHelper.getTotalSpace());
+        updateLayoutState(layoutDir, maxScroll, false, state);
+        mLayoutState.mScrollingOffset = LayoutState.SCROLLING_OFFSET_NaN;
+        mLayoutState.mRecycle = false;
+        fill(recycler, mLayoutState, state, true);
+        final View nextFocus;
+        if (layoutDir == LayoutState.LAYOUT_START) {
+            nextFocus = getChildClosestToStart();
+        } else {
+            nextFocus = getChildClosestToEnd();
+        }
+        if (nextFocus == referenceChild || !nextFocus.isFocusable()) {
+            return null;
+        }
+        return nextFocus;
+    }
+
+    /**
+     * Used for debugging.
+     * Logs the internal representation of children to default logger.
+     */
+    private void logChildren() {
+        Log.d(TAG, "internal representation of views on the screen");
+        for (int i = 0; i < getChildCount(); i++) {
+            View child = getChildAt(i);
+            Log.d(TAG, "item " + getPosition(child) + ", coord:"
+                    + mOrientationHelper.getDecoratedStart(child));
+        }
+        Log.d(TAG, "==============");
+    }
+
+    /**
+     * Used for debugging.
+     * Validates that child views are laid out in correct order. This is important because rest of
+     * the algorithm relies on this constraint.
+     *
+     * In default layout, child 0 should be closest to screen position 0 and last child should be
+     * closest to position WIDTH or HEIGHT.
+     * In reverse layout, last child should be closes to screen position 0 and first child should
+     * be closest to position WIDTH  or HEIGHT
+     */
+    void validateChildOrder() {
+        Log.d(TAG, "validating child count " + getChildCount());
+        if (getChildCount() < 1) {
+            return;
+        }
+        int lastPos = getPosition(getChildAt(0));
+        int lastScreenLoc = mOrientationHelper.getDecoratedStart(getChildAt(0));
+        if (mShouldReverseLayout) {
+            for (int i = 1; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                int pos = getPosition(child);
+                int screenLoc = mOrientationHelper.getDecoratedStart(child);
+                if (pos < lastPos) {
+                    logChildren();
+                    throw new RuntimeException("detected invalid position. loc invalid? "
+                            + (screenLoc < lastScreenLoc));
+                }
+                if (screenLoc > lastScreenLoc) {
+                    logChildren();
+                    throw new RuntimeException("detected invalid location");
+                }
+            }
+        } else {
+            for (int i = 1; i < getChildCount(); i++) {
+                View child = getChildAt(i);
+                int pos = getPosition(child);
+                int screenLoc = mOrientationHelper.getDecoratedStart(child);
+                if (pos < lastPos) {
+                    logChildren();
+                    throw new RuntimeException("detected invalid position. loc invalid? "
+                            + (screenLoc < lastScreenLoc));
+                }
+                if (screenLoc < lastScreenLoc) {
+                    logChildren();
+                    throw new RuntimeException("detected invalid location");
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean supportsPredictiveItemAnimations() {
+        return mPendingSavedState == null && mLastStackFromEnd == mStackFromEnd;
+    }
+
+    /**
+     * @hide This method should be called by ItemTouchHelper only.
+     */
+    @Override
+    public void prepareForDrop(View view, View target, int x, int y) {
+        assertNotInLayoutOrScroll("Cannot drop a view during a scroll or layout calculation");
+        ensureLayoutState();
+        resolveShouldLayoutReverse();
+        final int myPos = getPosition(view);
+        final int targetPos = getPosition(target);
+        final int dropDirection = myPos < targetPos ? LayoutState.ITEM_DIRECTION_TAIL
+                : LayoutState.ITEM_DIRECTION_HEAD;
+        if (mShouldReverseLayout) {
+            if (dropDirection == LayoutState.ITEM_DIRECTION_TAIL) {
+                scrollToPositionWithOffset(targetPos,
+                        mOrientationHelper.getEndAfterPadding()
+                                - (mOrientationHelper.getDecoratedStart(target)
+                                        + mOrientationHelper.getDecoratedMeasurement(view)));
+            } else {
+                scrollToPositionWithOffset(targetPos,
+                        mOrientationHelper.getEndAfterPadding()
+                                - mOrientationHelper.getDecoratedEnd(target));
+            }
+        } else {
+            if (dropDirection == LayoutState.ITEM_DIRECTION_HEAD) {
+                scrollToPositionWithOffset(targetPos, mOrientationHelper.getDecoratedStart(target));
+            } else {
+                scrollToPositionWithOffset(targetPos,
+                        mOrientationHelper.getDecoratedEnd(target)
+                                - mOrientationHelper.getDecoratedMeasurement(view));
+            }
+        }
+    }
+
+    /**
+     * Helper class that keeps temporary state while {LayoutManager} is filling out the empty
+     * space.
+     */
+    static class LayoutState {
+
+        static final String TAG = "LLM#LayoutState";
+
+        static final int LAYOUT_START = -1;
+
+        static final int LAYOUT_END = 1;
+
+        static final int INVALID_LAYOUT = Integer.MIN_VALUE;
+
+        static final int ITEM_DIRECTION_HEAD = -1;
+
+        static final int ITEM_DIRECTION_TAIL = 1;
+
+        static final int SCROLLING_OFFSET_NaN = Integer.MIN_VALUE;
+
+        /**
+         * We may not want to recycle children in some cases (e.g. layout)
+         */
+        boolean mRecycle = true;
+
+        /**
+         * Pixel offset where layout should start
+         */
+        int mOffset;
+
+        /**
+         * Number of pixels that we should fill, in the layout direction.
+         */
+        int mAvailable;
+
+        /**
+         * Current position on the adapter to get the next item.
+         */
+        int mCurrentPosition;
+
+        /**
+         * Defines the direction in which the data adapter is traversed.
+         * Should be {@link #ITEM_DIRECTION_HEAD} or {@link #ITEM_DIRECTION_TAIL}
+         */
+        int mItemDirection;
+
+        /**
+         * Defines the direction in which the layout is filled.
+         * Should be {@link #LAYOUT_START} or {@link #LAYOUT_END}
+         */
+        int mLayoutDirection;
+
+        /**
+         * Used when LayoutState is constructed in a scrolling state.
+         * It should be set the amount of scrolling we can make without creating a new view.
+         * Settings this is required for efficient view recycling.
+         */
+        int mScrollingOffset;
+
+        /**
+         * Used if you want to pre-layout items that are not yet visible.
+         * The difference with {@link #mAvailable} is that, when recycling, distance laid out for
+         * {@link #mExtra} is not considered to avoid recycling visible children.
+         */
+        int mExtra = 0;
+
+        /**
+         * Equal to {@link RecyclerView.State#isPreLayout()}. When consuming scrap, if this value
+         * is set to true, we skip removed views since they should not be laid out in post layout
+         * step.
+         */
+        boolean mIsPreLayout = false;
+
+        /**
+         * The most recent {@link #scrollBy(int, RecyclerView.Recycler, RecyclerView.State)}
+         * amount.
+         */
+        int mLastScrollDelta;
+
+        /**
+         * When LLM needs to layout particular views, it sets this list in which case, LayoutState
+         * will only return views from this list and return null if it cannot find an item.
+         */
+        List<RecyclerView.ViewHolder> mScrapList = null;
+
+        /**
+         * Used when there is no limit in how many views can be laid out.
+         */
+        boolean mInfinite;
+
+        /**
+         * @return true if there are more items in the data adapter
+         */
+        boolean hasMore(RecyclerView.State state) {
+            return mCurrentPosition >= 0 && mCurrentPosition < state.getItemCount();
+        }
+
+        /**
+         * Gets the view for the next element that we should layout.
+         * Also updates current item index to the next item, based on {@link #mItemDirection}
+         *
+         * @return The next element that we should layout.
+         */
+        View next(RecyclerView.Recycler recycler) {
+            if (mScrapList != null) {
+                return nextViewFromScrapList();
+            }
+            final View view = recycler.getViewForPosition(mCurrentPosition);
+            mCurrentPosition += mItemDirection;
+            return view;
+        }
+
+        /**
+         * Returns the next item from the scrap list.
+         * <p>
+         * Upon finding a valid VH, sets current item position to VH.itemPosition + mItemDirection
+         *
+         * @return View if an item in the current position or direction exists if not null.
+         */
+        private View nextViewFromScrapList() {
+            final int size = mScrapList.size();
+            for (int i = 0; i < size; i++) {
+                final View view = mScrapList.get(i).itemView;
+                final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+                if (lp.isItemRemoved()) {
+                    continue;
+                }
+                if (mCurrentPosition == lp.getViewLayoutPosition()) {
+                    assignPositionFromScrapList(view);
+                    return view;
+                }
+            }
+            return null;
+        }
+
+        public void assignPositionFromScrapList() {
+            assignPositionFromScrapList(null);
+        }
+
+        public void assignPositionFromScrapList(View ignore) {
+            final View closest = nextViewInLimitedList(ignore);
+            if (closest == null) {
+                mCurrentPosition = NO_POSITION;
+            } else {
+                mCurrentPosition = ((LayoutParams) closest.getLayoutParams())
+                        .getViewLayoutPosition();
+            }
+        }
+
+        public View nextViewInLimitedList(View ignore) {
+            int size = mScrapList.size();
+            View closest = null;
+            int closestDistance = Integer.MAX_VALUE;
+            if (DEBUG && mIsPreLayout) {
+                throw new IllegalStateException("Scrap list cannot be used in pre layout");
+            }
+            for (int i = 0; i < size; i++) {
+                View view = mScrapList.get(i).itemView;
+                final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+                if (view == ignore || lp.isItemRemoved()) {
+                    continue;
+                }
+                final int distance = (lp.getViewLayoutPosition() - mCurrentPosition)
+                        * mItemDirection;
+                if (distance < 0) {
+                    continue; // item is not in current direction
+                }
+                if (distance < closestDistance) {
+                    closest = view;
+                    closestDistance = distance;
+                    if (distance == 0) {
+                        break;
+                    }
+                }
+            }
+            return closest;
+        }
+
+        void log() {
+            Log.d(TAG, "avail:" + mAvailable + ", ind:" + mCurrentPosition + ", dir:"
+                    + mItemDirection + ", offset:" + mOffset + ", layoutDir:" + mLayoutDirection);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static class SavedState implements Parcelable {
+
+        int mAnchorPosition;
+
+        int mAnchorOffset;
+
+        boolean mAnchorLayoutFromEnd;
+
+        public SavedState() {
+
+        }
+
+        SavedState(Parcel in) {
+            mAnchorPosition = in.readInt();
+            mAnchorOffset = in.readInt();
+            mAnchorLayoutFromEnd = in.readInt() == 1;
+        }
+
+        public SavedState(SavedState other) {
+            mAnchorPosition = other.mAnchorPosition;
+            mAnchorOffset = other.mAnchorOffset;
+            mAnchorLayoutFromEnd = other.mAnchorLayoutFromEnd;
+        }
+
+        boolean hasValidAnchor() {
+            return mAnchorPosition >= 0;
+        }
+
+        void invalidateAnchor() {
+            mAnchorPosition = NO_POSITION;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(mAnchorPosition);
+            dest.writeInt(mAnchorOffset);
+            dest.writeInt(mAnchorLayoutFromEnd ? 1 : 0);
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+                    @Override
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
+
+                    @Override
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
+    }
+
+    /**
+     * Simple data class to keep Anchor information
+     */
+    class AnchorInfo {
+        int mPosition;
+        int mCoordinate;
+        boolean mLayoutFromEnd;
+        boolean mValid;
+
+        AnchorInfo() {
+            reset();
+        }
+
+        void reset() {
+            mPosition = NO_POSITION;
+            mCoordinate = INVALID_OFFSET;
+            mLayoutFromEnd = false;
+            mValid = false;
+        }
+
+        /**
+         * assigns anchor coordinate from the RecyclerView's padding depending on current
+         * layoutFromEnd value
+         */
+        void assignCoordinateFromPadding() {
+            mCoordinate = mLayoutFromEnd
+                    ? mOrientationHelper.getEndAfterPadding()
+                    : mOrientationHelper.getStartAfterPadding();
+        }
+
+        @Override
+        public String toString() {
+            return "AnchorInfo{"
+                    + "mPosition=" + mPosition
+                    + ", mCoordinate=" + mCoordinate
+                    + ", mLayoutFromEnd=" + mLayoutFromEnd
+                    + ", mValid=" + mValid
+                    + '}';
+        }
+
+        boolean isViewValidAsAnchor(View child, RecyclerView.State state) {
+            LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            return !lp.isItemRemoved() && lp.getViewLayoutPosition() >= 0
+                    && lp.getViewLayoutPosition() < state.getItemCount();
+        }
+
+        public void assignFromViewAndKeepVisibleRect(View child) {
+            final int spaceChange = mOrientationHelper.getTotalSpaceChange();
+            if (spaceChange >= 0) {
+                assignFromView(child);
+                return;
+            }
+            mPosition = getPosition(child);
+            if (mLayoutFromEnd) {
+                final int prevLayoutEnd = mOrientationHelper.getEndAfterPadding() - spaceChange;
+                final int childEnd = mOrientationHelper.getDecoratedEnd(child);
+                final int previousEndMargin = prevLayoutEnd - childEnd;
+                mCoordinate = mOrientationHelper.getEndAfterPadding() - previousEndMargin;
+                // ensure we did not push child's top out of bounds because of this
+                if (previousEndMargin > 0) { // we have room to shift bottom if necessary
+                    final int childSize = mOrientationHelper.getDecoratedMeasurement(child);
+                    final int estimatedChildStart = mCoordinate - childSize;
+                    final int layoutStart = mOrientationHelper.getStartAfterPadding();
+                    final int previousStartMargin = mOrientationHelper.getDecoratedStart(child)
+                            - layoutStart;
+                    final int startReference = layoutStart + Math.min(previousStartMargin, 0);
+                    final int startMargin = estimatedChildStart - startReference;
+                    if (startMargin < 0) {
+                        // offset to make top visible but not too much
+                        mCoordinate += Math.min(previousEndMargin, -startMargin);
+                    }
+                }
+            } else {
+                final int childStart = mOrientationHelper.getDecoratedStart(child);
+                final int startMargin = childStart - mOrientationHelper.getStartAfterPadding();
+                mCoordinate = childStart;
+                if (startMargin > 0) { // we have room to fix end as well
+                    final int estimatedEnd = childStart
+                            + mOrientationHelper.getDecoratedMeasurement(child);
+                    final int previousLayoutEnd = mOrientationHelper.getEndAfterPadding()
+                            - spaceChange;
+                    final int previousEndMargin = previousLayoutEnd
+                            - mOrientationHelper.getDecoratedEnd(child);
+                    final int endReference = mOrientationHelper.getEndAfterPadding()
+                            - Math.min(0, previousEndMargin);
+                    final int endMargin = endReference - estimatedEnd;
+                    if (endMargin < 0) {
+                        mCoordinate -= Math.min(startMargin, -endMargin);
+                    }
+                }
+            }
+        }
+
+        public void assignFromView(View child) {
+            if (mLayoutFromEnd) {
+                mCoordinate = mOrientationHelper.getDecoratedEnd(child)
+                        + mOrientationHelper.getTotalSpaceChange();
+            } else {
+                mCoordinate = mOrientationHelper.getDecoratedStart(child);
+            }
+
+            mPosition = getPosition(child);
+        }
+    }
+
+    protected static class LayoutChunkResult {
+        public int mConsumed;
+        public boolean mFinished;
+        public boolean mIgnoreConsumed;
+        public boolean mFocusable;
+
+        void resetInternal() {
+            mConsumed = 0;
+            mFinished = false;
+            mIgnoreConsumed = false;
+            mFocusable = false;
+        }
+    }
+}
diff --git a/core/java/com/android/internal/widget/LinearSmoothScroller.java b/core/java/com/android/internal/widget/LinearSmoothScroller.java
new file mode 100644
index 0000000..d024f21
--- /dev/null
+++ b/core/java/com/android/internal/widget/LinearSmoothScroller.java
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.PointF;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.View;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.LinearInterpolator;
+
+/**
+ * {@link RecyclerView.SmoothScroller} implementation which uses a {@link LinearInterpolator} until
+ * the target position becomes a child of the RecyclerView and then uses a
+ * {@link DecelerateInterpolator} to slowly approach to target position.
+ * <p>
+ * If the {@link RecyclerView.LayoutManager} you are using does not implement the
+ * {@link RecyclerView.SmoothScroller.ScrollVectorProvider} interface, then you must override the
+ * {@link #computeScrollVectorForPosition(int)} method. All the LayoutManagers bundled with
+ * the support library implement this interface.
+ */
+public class LinearSmoothScroller extends RecyclerView.SmoothScroller {
+
+    private static final String TAG = "LinearSmoothScroller";
+
+    private static final boolean DEBUG = false;
+
+    private static final float MILLISECONDS_PER_INCH = 25f;
+
+    private static final int TARGET_SEEK_SCROLL_DISTANCE_PX = 10000;
+
+    /**
+     * Align child view's left or top with parent view's left or top
+     *
+     * @see #calculateDtToFit(int, int, int, int, int)
+     * @see #calculateDxToMakeVisible(android.view.View, int)
+     * @see #calculateDyToMakeVisible(android.view.View, int)
+     */
+    public static final int SNAP_TO_START = -1;
+
+    /**
+     * Align child view's right or bottom with parent view's right or bottom
+     *
+     * @see #calculateDtToFit(int, int, int, int, int)
+     * @see #calculateDxToMakeVisible(android.view.View, int)
+     * @see #calculateDyToMakeVisible(android.view.View, int)
+     */
+    public static final int SNAP_TO_END = 1;
+
+    /**
+     * <p>Decides if the child should be snapped from start or end, depending on where it
+     * currently is in relation to its parent.</p>
+     * <p>For instance, if the view is virtually on the left of RecyclerView, using
+     * {@code SNAP_TO_ANY} is the same as using {@code SNAP_TO_START}</p>
+     *
+     * @see #calculateDtToFit(int, int, int, int, int)
+     * @see #calculateDxToMakeVisible(android.view.View, int)
+     * @see #calculateDyToMakeVisible(android.view.View, int)
+     */
+    public static final int SNAP_TO_ANY = 0;
+
+    // Trigger a scroll to a further distance than TARGET_SEEK_SCROLL_DISTANCE_PX so that if target
+    // view is not laid out until interim target position is reached, we can detect the case before
+    // scrolling slows down and reschedule another interim target scroll
+    private static final float TARGET_SEEK_EXTRA_SCROLL_RATIO = 1.2f;
+
+    protected final LinearInterpolator mLinearInterpolator = new LinearInterpolator();
+
+    protected final DecelerateInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
+
+    protected PointF mTargetVector;
+
+    private final float MILLISECONDS_PER_PX;
+
+    // Temporary variables to keep track of the interim scroll target. These values do not
+    // point to a real item position, rather point to an estimated location pixels.
+    protected int mInterimTargetDx = 0, mInterimTargetDy = 0;
+
+    public LinearSmoothScroller(Context context) {
+        MILLISECONDS_PER_PX = calculateSpeedPerPixel(context.getResources().getDisplayMetrics());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onStart() {
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onTargetFound(View targetView, RecyclerView.State state, Action action) {
+        final int dx = calculateDxToMakeVisible(targetView, getHorizontalSnapPreference());
+        final int dy = calculateDyToMakeVisible(targetView, getVerticalSnapPreference());
+        final int distance = (int) Math.sqrt(dx * dx + dy * dy);
+        final int time = calculateTimeForDeceleration(distance);
+        if (time > 0) {
+            action.update(-dx, -dy, time, mDecelerateInterpolator);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onSeekTargetStep(int dx, int dy, RecyclerView.State state, Action action) {
+        if (getChildCount() == 0) {
+            stop();
+            return;
+        }
+        //noinspection PointlessBooleanExpression
+        if (DEBUG && mTargetVector != null
+                && ((mTargetVector.x * dx < 0 || mTargetVector.y * dy < 0))) {
+            throw new IllegalStateException("Scroll happened in the opposite direction"
+                    + " of the target. Some calculations are wrong");
+        }
+        mInterimTargetDx = clampApplyScroll(mInterimTargetDx, dx);
+        mInterimTargetDy = clampApplyScroll(mInterimTargetDy, dy);
+
+        if (mInterimTargetDx == 0 && mInterimTargetDy == 0) {
+            updateActionForInterimTarget(action);
+        } // everything is valid, keep going
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onStop() {
+        mInterimTargetDx = mInterimTargetDy = 0;
+        mTargetVector = null;
+    }
+
+    /**
+     * Calculates the scroll speed.
+     *
+     * @param displayMetrics DisplayMetrics to be used for real dimension calculations
+     * @return The time (in ms) it should take for each pixel. For instance, if returned value is
+     * 2 ms, it means scrolling 1000 pixels with LinearInterpolation should take 2 seconds.
+     */
+    protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
+        return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
+    }
+
+    /**
+     * <p>Calculates the time for deceleration so that transition from LinearInterpolator to
+     * DecelerateInterpolator looks smooth.</p>
+     *
+     * @param dx Distance to scroll
+     * @return Time for DecelerateInterpolator to smoothly traverse the distance when transitioning
+     * from LinearInterpolation
+     */
+    protected int calculateTimeForDeceleration(int dx) {
+        // we want to cover same area with the linear interpolator for the first 10% of the
+        // interpolation. After that, deceleration will take control.
+        // area under curve (1-(1-x)^2) can be calculated as (1 - x/3) * x * x
+        // which gives 0.100028 when x = .3356
+        // this is why we divide linear scrolling time with .3356
+        return  (int) Math.ceil(calculateTimeForScrolling(dx) / .3356);
+    }
+
+    /**
+     * Calculates the time it should take to scroll the given distance (in pixels)
+     *
+     * @param dx Distance in pixels that we want to scroll
+     * @return Time in milliseconds
+     * @see #calculateSpeedPerPixel(android.util.DisplayMetrics)
+     */
+    protected int calculateTimeForScrolling(int dx) {
+        // In a case where dx is very small, rounding may return 0 although dx > 0.
+        // To avoid that issue, ceil the result so that if dx > 0, we'll always return positive
+        // time.
+        return (int) Math.ceil(Math.abs(dx) * MILLISECONDS_PER_PX);
+    }
+
+    /**
+     * When scrolling towards a child view, this method defines whether we should align the left
+     * or the right edge of the child with the parent RecyclerView.
+     *
+     * @return SNAP_TO_START, SNAP_TO_END or SNAP_TO_ANY; depending on the current target vector
+     * @see #SNAP_TO_START
+     * @see #SNAP_TO_END
+     * @see #SNAP_TO_ANY
+     */
+    protected int getHorizontalSnapPreference() {
+        return mTargetVector == null || mTargetVector.x == 0 ? SNAP_TO_ANY :
+                mTargetVector.x > 0 ? SNAP_TO_END : SNAP_TO_START;
+    }
+
+    /**
+     * When scrolling towards a child view, this method defines whether we should align the top
+     * or the bottom edge of the child with the parent RecyclerView.
+     *
+     * @return SNAP_TO_START, SNAP_TO_END or SNAP_TO_ANY; depending on the current target vector
+     * @see #SNAP_TO_START
+     * @see #SNAP_TO_END
+     * @see #SNAP_TO_ANY
+     */
+    protected int getVerticalSnapPreference() {
+        return mTargetVector == null || mTargetVector.y == 0 ? SNAP_TO_ANY :
+                mTargetVector.y > 0 ? SNAP_TO_END : SNAP_TO_START;
+    }
+
+    /**
+     * When the target scroll position is not a child of the RecyclerView, this method calculates
+     * a direction vector towards that child and triggers a smooth scroll.
+     *
+     * @see #computeScrollVectorForPosition(int)
+     */
+    protected void updateActionForInterimTarget(Action action) {
+        // find an interim target position
+        PointF scrollVector = computeScrollVectorForPosition(getTargetPosition());
+        if (scrollVector == null || (scrollVector.x == 0 && scrollVector.y == 0)) {
+            final int target = getTargetPosition();
+            action.jumpTo(target);
+            stop();
+            return;
+        }
+        normalize(scrollVector);
+        mTargetVector = scrollVector;
+
+        mInterimTargetDx = (int) (TARGET_SEEK_SCROLL_DISTANCE_PX * scrollVector.x);
+        mInterimTargetDy = (int) (TARGET_SEEK_SCROLL_DISTANCE_PX * scrollVector.y);
+        final int time = calculateTimeForScrolling(TARGET_SEEK_SCROLL_DISTANCE_PX);
+        // To avoid UI hiccups, trigger a smooth scroll to a distance little further than the
+        // interim target. Since we track the distance travelled in onSeekTargetStep callback, it
+        // won't actually scroll more than what we need.
+        action.update((int) (mInterimTargetDx * TARGET_SEEK_EXTRA_SCROLL_RATIO),
+                (int) (mInterimTargetDy * TARGET_SEEK_EXTRA_SCROLL_RATIO),
+                (int) (time * TARGET_SEEK_EXTRA_SCROLL_RATIO), mLinearInterpolator);
+    }
+
+    private int clampApplyScroll(int tmpDt, int dt) {
+        final int before = tmpDt;
+        tmpDt -= dt;
+        if (before * tmpDt <= 0) { // changed sign, reached 0 or was 0, reset
+            return 0;
+        }
+        return tmpDt;
+    }
+
+    /**
+     * Helper method for {@link #calculateDxToMakeVisible(android.view.View, int)} and
+     * {@link #calculateDyToMakeVisible(android.view.View, int)}
+     */
+    public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int
+            snapPreference) {
+        switch (snapPreference) {
+            case SNAP_TO_START:
+                return boxStart - viewStart;
+            case SNAP_TO_END:
+                return boxEnd - viewEnd;
+            case SNAP_TO_ANY:
+                final int dtStart = boxStart - viewStart;
+                if (dtStart > 0) {
+                    return dtStart;
+                }
+                final int dtEnd = boxEnd - viewEnd;
+                if (dtEnd < 0) {
+                    return dtEnd;
+                }
+                break;
+            default:
+                throw new IllegalArgumentException("snap preference should be one of the"
+                        + " constants defined in SmoothScroller, starting with SNAP_");
+        }
+        return 0;
+    }
+
+    /**
+     * Calculates the vertical scroll amount necessary to make the given view fully visible
+     * inside the RecyclerView.
+     *
+     * @param view           The view which we want to make fully visible
+     * @param snapPreference The edge which the view should snap to when entering the visible
+     *                       area. One of {@link #SNAP_TO_START}, {@link #SNAP_TO_END} or
+     *                       {@link #SNAP_TO_ANY}.
+     * @return The vertical scroll amount necessary to make the view visible with the given
+     * snap preference.
+     */
+    public int calculateDyToMakeVisible(View view, int snapPreference) {
+        final RecyclerView.LayoutManager layoutManager = getLayoutManager();
+        if (layoutManager == null || !layoutManager.canScrollVertically()) {
+            return 0;
+        }
+        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                view.getLayoutParams();
+        final int top = layoutManager.getDecoratedTop(view) - params.topMargin;
+        final int bottom = layoutManager.getDecoratedBottom(view) + params.bottomMargin;
+        final int start = layoutManager.getPaddingTop();
+        final int end = layoutManager.getHeight() - layoutManager.getPaddingBottom();
+        return calculateDtToFit(top, bottom, start, end, snapPreference);
+    }
+
+    /**
+     * Calculates the horizontal scroll amount necessary to make the given view fully visible
+     * inside the RecyclerView.
+     *
+     * @param view           The view which we want to make fully visible
+     * @param snapPreference The edge which the view should snap to when entering the visible
+     *                       area. One of {@link #SNAP_TO_START}, {@link #SNAP_TO_END} or
+     *                       {@link #SNAP_TO_END}
+     * @return The vertical scroll amount necessary to make the view visible with the given
+     * snap preference.
+     */
+    public int calculateDxToMakeVisible(View view, int snapPreference) {
+        final RecyclerView.LayoutManager layoutManager = getLayoutManager();
+        if (layoutManager == null || !layoutManager.canScrollHorizontally()) {
+            return 0;
+        }
+        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                view.getLayoutParams();
+        final int left = layoutManager.getDecoratedLeft(view) - params.leftMargin;
+        final int right = layoutManager.getDecoratedRight(view) + params.rightMargin;
+        final int start = layoutManager.getPaddingLeft();
+        final int end = layoutManager.getWidth() - layoutManager.getPaddingRight();
+        return calculateDtToFit(left, right, start, end, snapPreference);
+    }
+
+    /**
+     * Compute the scroll vector for a given target position.
+     * <p>
+     * This method can return null if the layout manager cannot calculate a scroll vector
+     * for the given position (e.g. it has no current scroll position).
+     *
+     * @param targetPosition the position to which the scroller is scrolling
+     *
+     * @return the scroll vector for a given target position
+     */
+    @Nullable
+    public PointF computeScrollVectorForPosition(int targetPosition) {
+        RecyclerView.LayoutManager layoutManager = getLayoutManager();
+        if (layoutManager instanceof ScrollVectorProvider) {
+            return ((ScrollVectorProvider) layoutManager)
+                    .computeScrollVectorForPosition(targetPosition);
+        }
+        Log.w(TAG, "You should override computeScrollVectorForPosition when the LayoutManager"
+                + " does not implement " + ScrollVectorProvider.class.getCanonicalName());
+        return null;
+    }
+}
diff --git a/core/java/com/android/internal/widget/NestedScrollingChild.java b/core/java/com/android/internal/widget/NestedScrollingChild.java
new file mode 100644
index 0000000..20285b5
--- /dev/null
+++ b/core/java/com/android/internal/widget/NestedScrollingChild.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewParent;
+
+/**
+ * This interface should be implemented by {@link android.view.View View} subclasses that wish
+ * to support dispatching nested scrolling operations to a cooperating parent
+ * {@link android.view.ViewGroup ViewGroup}.
+ *
+ * <p>Classes implementing this interface should create a final instance of a
+ * {@link NestedScrollingChildHelper} as a field and delegate any View methods to the
+ * <code>NestedScrollingChildHelper</code> methods of the same signature.</p>
+ *
+ * <p>Views invoking nested scrolling functionality should always do so from the relevant
+ * {@link ViewCompat}, {@link ViewGroupCompat} or {@link ViewParentCompat} compatibility
+ * shim static methods. This ensures interoperability with nested scrolling views on Android
+ * 5.0 Lollipop and newer.</p>
+ */
+public interface NestedScrollingChild {
+    /**
+     * Enable or disable nested scrolling for this view.
+     *
+     * <p>If this property is set to true the view will be permitted to initiate nested
+     * scrolling operations with a compatible parent view in the current hierarchy. If this
+     * view does not implement nested scrolling this will have no effect. Disabling nested scrolling
+     * while a nested scroll is in progress has the effect of {@link #stopNestedScroll() stopping}
+     * the nested scroll.</p>
+     *
+     * @param enabled true to enable nested scrolling, false to disable
+     *
+     * @see #isNestedScrollingEnabled()
+     */
+    void setNestedScrollingEnabled(boolean enabled);
+
+    /**
+     * Returns true if nested scrolling is enabled for this view.
+     *
+     * <p>If nested scrolling is enabled and this View class implementation supports it,
+     * this view will act as a nested scrolling child view when applicable, forwarding data
+     * about the scroll operation in progress to a compatible and cooperating nested scrolling
+     * parent.</p>
+     *
+     * @return true if nested scrolling is enabled
+     *
+     * @see #setNestedScrollingEnabled(boolean)
+     */
+    boolean isNestedScrollingEnabled();
+
+    /**
+     * Begin a nestable scroll operation along the given axes.
+     *
+     * <p>A view starting a nested scroll promises to abide by the following contract:</p>
+     *
+     * <p>The view will call startNestedScroll upon initiating a scroll operation. In the case
+     * of a touch scroll this corresponds to the initial {@link MotionEvent#ACTION_DOWN}.
+     * In the case of touch scrolling the nested scroll will be terminated automatically in
+     * the same manner as {@link ViewParent#requestDisallowInterceptTouchEvent(boolean)}.
+     * In the event of programmatic scrolling the caller must explicitly call
+     * {@link #stopNestedScroll()} to indicate the end of the nested scroll.</p>
+     *
+     * <p>If <code>startNestedScroll</code> returns true, a cooperative parent was found.
+     * If it returns false the caller may ignore the rest of this contract until the next scroll.
+     * Calling startNestedScroll while a nested scroll is already in progress will return true.</p>
+     *
+     * <p>At each incremental step of the scroll the caller should invoke
+     * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll}
+     * once it has calculated the requested scrolling delta. If it returns true the nested scrolling
+     * parent at least partially consumed the scroll and the caller should adjust the amount it
+     * scrolls by.</p>
+     *
+     * <p>After applying the remainder of the scroll delta the caller should invoke
+     * {@link #dispatchNestedScroll(int, int, int, int, int[]) dispatchNestedScroll}, passing
+     * both the delta consumed and the delta unconsumed. A nested scrolling parent may treat
+     * these values differently. See
+     * {@link NestedScrollingParent#onNestedScroll(View, int, int, int, int)}.
+     * </p>
+     *
+     * @param axes Flags consisting of a combination of {@link ViewCompat#SCROLL_AXIS_HORIZONTAL}
+     *             and/or {@link ViewCompat#SCROLL_AXIS_VERTICAL}.
+     * @return true if a cooperative parent was found and nested scrolling has been enabled for
+     *         the current gesture.
+     *
+     * @see #stopNestedScroll()
+     * @see #dispatchNestedPreScroll(int, int, int[], int[])
+     * @see #dispatchNestedScroll(int, int, int, int, int[])
+     */
+    boolean startNestedScroll(int axes);
+
+    /**
+     * Stop a nested scroll in progress.
+     *
+     * <p>Calling this method when a nested scroll is not currently in progress is harmless.</p>
+     *
+     * @see #startNestedScroll(int)
+     */
+    void stopNestedScroll();
+
+    /**
+     * Returns true if this view has a nested scrolling parent.
+     *
+     * <p>The presence of a nested scrolling parent indicates that this view has initiated
+     * a nested scroll and it was accepted by an ancestor view further up the view hierarchy.</p>
+     *
+     * @return whether this view has a nested scrolling parent
+     */
+    boolean hasNestedScrollingParent();
+
+    /**
+     * Dispatch one step of a nested scroll in progress.
+     *
+     * <p>Implementations of views that support nested scrolling should call this to report
+     * info about a scroll in progress to the current nested scrolling parent. If a nested scroll
+     * is not currently in progress or nested scrolling is not
+     * {@link #isNestedScrollingEnabled() enabled} for this view this method does nothing.</p>
+     *
+     * <p>Compatible View implementations should also call
+     * {@link #dispatchNestedPreScroll(int, int, int[], int[]) dispatchNestedPreScroll} before
+     * consuming a component of the scroll event themselves.</p>
+     *
+     * @param dxConsumed Horizontal distance in pixels consumed by this view during this scroll step
+     * @param dyConsumed Vertical distance in pixels consumed by this view during this scroll step
+     * @param dxUnconsumed Horizontal scroll distance in pixels not consumed by this view
+     * @param dyUnconsumed Horizontal scroll distance in pixels not consumed by this view
+     * @param offsetInWindow Optional. If not null, on return this will contain the offset
+     *                       in local view coordinates of this view from before this operation
+     *                       to after it completes. View implementations may use this to adjust
+     *                       expected input coordinate tracking.
+     * @return true if the event was dispatched, false if it could not be dispatched.
+     * @see #dispatchNestedPreScroll(int, int, int[], int[])
+     */
+    boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
+            int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);
+
+    /**
+     * Dispatch one step of a nested scroll in progress before this view consumes any portion of it.
+     *
+     * <p>Nested pre-scroll events are to nested scroll events what touch intercept is to touch.
+     * <code>dispatchNestedPreScroll</code> offers an opportunity for the parent view in a nested
+     * scrolling operation to consume some or all of the scroll operation before the child view
+     * consumes it.</p>
+     *
+     * @param dx Horizontal scroll distance in pixels
+     * @param dy Vertical scroll distance in pixels
+     * @param consumed Output. If not null, consumed[0] will contain the consumed component of dx
+     *                 and consumed[1] the consumed dy.
+     * @param offsetInWindow Optional. If not null, on return this will contain the offset
+     *                       in local view coordinates of this view from before this operation
+     *                       to after it completes. View implementations may use this to adjust
+     *                       expected input coordinate tracking.
+     * @return true if the parent consumed some or all of the scroll delta
+     * @see #dispatchNestedScroll(int, int, int, int, int[])
+     */
+    boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);
+
+    /**
+     * Dispatch a fling to a nested scrolling parent.
+     *
+     * <p>This method should be used to indicate that a nested scrolling child has detected
+     * suitable conditions for a fling. Generally this means that a touch scroll has ended with a
+     * {@link VelocityTracker velocity} in the direction of scrolling that meets or exceeds
+     * the {@link ViewConfiguration#getScaledMinimumFlingVelocity() minimum fling velocity}
+     * along a scrollable axis.</p>
+     *
+     * <p>If a nested scrolling child view would normally fling but it is at the edge of
+     * its own content, it can use this method to delegate the fling to its nested scrolling
+     * parent instead. The parent may optionally consume the fling or observe a child fling.</p>
+     *
+     * @param velocityX Horizontal fling velocity in pixels per second
+     * @param velocityY Vertical fling velocity in pixels per second
+     * @param consumed true if the child consumed the fling, false otherwise
+     * @return true if the nested scrolling parent consumed or otherwise reacted to the fling
+     */
+    boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);
+
+    /**
+     * Dispatch a fling to a nested scrolling parent before it is processed by this view.
+     *
+     * <p>Nested pre-fling events are to nested fling events what touch intercept is to touch
+     * and what nested pre-scroll is to nested scroll. <code>dispatchNestedPreFling</code>
+     * offsets an opportunity for the parent view in a nested fling to fully consume the fling
+     * before the child view consumes it. If this method returns <code>true</code>, a nested
+     * parent view consumed the fling and this view should not scroll as a result.</p>
+     *
+     * <p>For a better user experience, only one view in a nested scrolling chain should consume
+     * the fling at a time. If a parent view consumed the fling this method will return false.
+     * Custom view implementations should account for this in two ways:</p>
+     *
+     * <ul>
+     *     <li>If a custom view is paged and needs to settle to a fixed page-point, do not
+     *     call <code>dispatchNestedPreFling</code>; consume the fling and settle to a valid
+     *     position regardless.</li>
+     *     <li>If a nested parent does consume the fling, this view should not scroll at all,
+     *     even to settle back to a valid idle position.</li>
+     * </ul>
+     *
+     * <p>Views should also not offer fling velocities to nested parent views along an axis
+     * where scrolling is not currently supported; a {@link android.widget.ScrollView ScrollView}
+     * should not offer a horizontal fling velocity to its parents since scrolling along that
+     * axis is not permitted and carrying velocity along that motion does not make sense.</p>
+     *
+     * @param velocityX Horizontal fling velocity in pixels per second
+     * @param velocityY Vertical fling velocity in pixels per second
+     * @return true if a nested scrolling parent consumed the fling
+     */
+    boolean dispatchNestedPreFling(float velocityX, float velocityY);
+}
diff --git a/core/java/com/android/internal/widget/OpReorderer.java b/core/java/com/android/internal/widget/OpReorderer.java
new file mode 100644
index 0000000..babb087
--- /dev/null
+++ b/core/java/com/android/internal/widget/OpReorderer.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import static com.android.internal.widget.AdapterHelper.UpdateOp.ADD;
+import static com.android.internal.widget.AdapterHelper.UpdateOp.MOVE;
+import static com.android.internal.widget.AdapterHelper.UpdateOp.REMOVE;
+import static com.android.internal.widget.AdapterHelper.UpdateOp.UPDATE;
+
+import com.android.internal.widget.AdapterHelper.UpdateOp;
+
+import java.util.List;
+
+class OpReorderer {
+
+    final Callback mCallback;
+
+    OpReorderer(Callback callback) {
+        mCallback = callback;
+    }
+
+    void reorderOps(List<UpdateOp> ops) {
+        // since move operations breaks continuity, their effects on ADD/RM are hard to handle.
+        // we push them to the end of the list so that they can be handled easily.
+        int badMove;
+        while ((badMove = getLastMoveOutOfOrder(ops)) != -1) {
+            swapMoveOp(ops, badMove, badMove + 1);
+        }
+    }
+
+    private void swapMoveOp(List<UpdateOp> list, int badMove, int next) {
+        final UpdateOp moveOp = list.get(badMove);
+        final UpdateOp nextOp = list.get(next);
+        switch (nextOp.cmd) {
+            case REMOVE:
+                swapMoveRemove(list, badMove, moveOp, next, nextOp);
+                break;
+            case ADD:
+                swapMoveAdd(list, badMove, moveOp, next, nextOp);
+                break;
+            case UPDATE:
+                swapMoveUpdate(list, badMove, moveOp, next, nextOp);
+                break;
+        }
+    }
+
+    void swapMoveRemove(List<UpdateOp> list, int movePos, UpdateOp moveOp,
+            int removePos, UpdateOp removeOp) {
+        UpdateOp extraRm = null;
+        // check if move is nulled out by remove
+        boolean revertedMove = false;
+        final boolean moveIsBackwards;
+
+        if (moveOp.positionStart < moveOp.itemCount) {
+            moveIsBackwards = false;
+            if (removeOp.positionStart == moveOp.positionStart
+                    && removeOp.itemCount == moveOp.itemCount - moveOp.positionStart) {
+                revertedMove = true;
+            }
+        } else {
+            moveIsBackwards = true;
+            if (removeOp.positionStart == moveOp.itemCount + 1
+                    && removeOp.itemCount == moveOp.positionStart - moveOp.itemCount) {
+                revertedMove = true;
+            }
+        }
+
+        // going in reverse, first revert the effect of add
+        if (moveOp.itemCount < removeOp.positionStart) {
+            removeOp.positionStart--;
+        } else if (moveOp.itemCount < removeOp.positionStart + removeOp.itemCount) {
+            // move is removed.
+            removeOp.itemCount--;
+            moveOp.cmd = REMOVE;
+            moveOp.itemCount = 1;
+            if (removeOp.itemCount == 0) {
+                list.remove(removePos);
+                mCallback.recycleUpdateOp(removeOp);
+            }
+            // no need to swap, it is already a remove
+            return;
+        }
+
+        // now affect of add is consumed. now apply effect of first remove
+        if (moveOp.positionStart <= removeOp.positionStart) {
+            removeOp.positionStart++;
+        } else if (moveOp.positionStart < removeOp.positionStart + removeOp.itemCount) {
+            final int remaining = removeOp.positionStart + removeOp.itemCount
+                    - moveOp.positionStart;
+            extraRm = mCallback.obtainUpdateOp(REMOVE, moveOp.positionStart + 1, remaining, null);
+            removeOp.itemCount = moveOp.positionStart - removeOp.positionStart;
+        }
+
+        // if effects of move is reverted by remove, we are done.
+        if (revertedMove) {
+            list.set(movePos, removeOp);
+            list.remove(removePos);
+            mCallback.recycleUpdateOp(moveOp);
+            return;
+        }
+
+        // now find out the new locations for move actions
+        if (moveIsBackwards) {
+            if (extraRm != null) {
+                if (moveOp.positionStart > extraRm.positionStart) {
+                    moveOp.positionStart -= extraRm.itemCount;
+                }
+                if (moveOp.itemCount > extraRm.positionStart) {
+                    moveOp.itemCount -= extraRm.itemCount;
+                }
+            }
+            if (moveOp.positionStart > removeOp.positionStart) {
+                moveOp.positionStart -= removeOp.itemCount;
+            }
+            if (moveOp.itemCount > removeOp.positionStart) {
+                moveOp.itemCount -= removeOp.itemCount;
+            }
+        } else {
+            if (extraRm != null) {
+                if (moveOp.positionStart >= extraRm.positionStart) {
+                    moveOp.positionStart -= extraRm.itemCount;
+                }
+                if (moveOp.itemCount >= extraRm.positionStart) {
+                    moveOp.itemCount -= extraRm.itemCount;
+                }
+            }
+            if (moveOp.positionStart >= removeOp.positionStart) {
+                moveOp.positionStart -= removeOp.itemCount;
+            }
+            if (moveOp.itemCount >= removeOp.positionStart) {
+                moveOp.itemCount -= removeOp.itemCount;
+            }
+        }
+
+        list.set(movePos, removeOp);
+        if (moveOp.positionStart != moveOp.itemCount) {
+            list.set(removePos, moveOp);
+        } else {
+            list.remove(removePos);
+        }
+        if (extraRm != null) {
+            list.add(movePos, extraRm);
+        }
+    }
+
+    private void swapMoveAdd(List<UpdateOp> list, int move, UpdateOp moveOp, int add,
+            UpdateOp addOp) {
+        int offset = 0;
+        // going in reverse, first revert the effect of add
+        if (moveOp.itemCount < addOp.positionStart) {
+            offset--;
+        }
+        if (moveOp.positionStart < addOp.positionStart) {
+            offset++;
+        }
+        if (addOp.positionStart <= moveOp.positionStart) {
+            moveOp.positionStart += addOp.itemCount;
+        }
+        if (addOp.positionStart <= moveOp.itemCount) {
+            moveOp.itemCount += addOp.itemCount;
+        }
+        addOp.positionStart += offset;
+        list.set(move, addOp);
+        list.set(add, moveOp);
+    }
+
+    void swapMoveUpdate(List<UpdateOp> list, int move, UpdateOp moveOp, int update,
+            UpdateOp updateOp) {
+        UpdateOp extraUp1 = null;
+        UpdateOp extraUp2 = null;
+        // going in reverse, first revert the effect of add
+        if (moveOp.itemCount < updateOp.positionStart) {
+            updateOp.positionStart--;
+        } else if (moveOp.itemCount < updateOp.positionStart + updateOp.itemCount) {
+            // moved item is updated. add an update for it
+            updateOp.itemCount--;
+            extraUp1 = mCallback.obtainUpdateOp(UPDATE, moveOp.positionStart, 1, updateOp.payload);
+        }
+        // now affect of add is consumed. now apply effect of first remove
+        if (moveOp.positionStart <= updateOp.positionStart) {
+            updateOp.positionStart++;
+        } else if (moveOp.positionStart < updateOp.positionStart + updateOp.itemCount) {
+            final int remaining = updateOp.positionStart + updateOp.itemCount
+                    - moveOp.positionStart;
+            extraUp2 = mCallback.obtainUpdateOp(UPDATE, moveOp.positionStart + 1, remaining,
+                    updateOp.payload);
+            updateOp.itemCount -= remaining;
+        }
+        list.set(update, moveOp);
+        if (updateOp.itemCount > 0) {
+            list.set(move, updateOp);
+        } else {
+            list.remove(move);
+            mCallback.recycleUpdateOp(updateOp);
+        }
+        if (extraUp1 != null) {
+            list.add(move, extraUp1);
+        }
+        if (extraUp2 != null) {
+            list.add(move, extraUp2);
+        }
+    }
+
+    private int getLastMoveOutOfOrder(List<UpdateOp> list) {
+        boolean foundNonMove = false;
+        for (int i = list.size() - 1; i >= 0; i--) {
+            final UpdateOp op1 = list.get(i);
+            if (op1.cmd == MOVE) {
+                if (foundNonMove) {
+                    return i;
+                }
+            } else {
+                foundNonMove = true;
+            }
+        }
+        return -1;
+    }
+
+    interface Callback {
+
+        UpdateOp obtainUpdateOp(int cmd, int startPosition, int itemCount, Object payload);
+
+        void recycleUpdateOp(UpdateOp op);
+    }
+}
diff --git a/core/java/com/android/internal/widget/OrientationHelper.java b/core/java/com/android/internal/widget/OrientationHelper.java
new file mode 100644
index 0000000..1b02c88
--- /dev/null
+++ b/core/java/com/android/internal/widget/OrientationHelper.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.graphics.Rect;
+import android.view.View;
+import android.widget.LinearLayout;
+
+/**
+ * Helper class for LayoutManagers to abstract measurements depending on the View's orientation.
+ * <p>
+ * It is developed to easily support vertical and horizontal orientations in a LayoutManager but
+ * can also be used to abstract calls around view bounds and child measurements with margins and
+ * decorations.
+ *
+ * @see #createHorizontalHelper(RecyclerView.LayoutManager)
+ * @see #createVerticalHelper(RecyclerView.LayoutManager)
+ */
+public abstract class OrientationHelper {
+
+    private static final int INVALID_SIZE = Integer.MIN_VALUE;
+
+    protected final RecyclerView.LayoutManager mLayoutManager;
+
+    public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
+
+    public static final int VERTICAL = LinearLayout.VERTICAL;
+
+    private int mLastTotalSpace = INVALID_SIZE;
+
+    final Rect mTmpRect = new Rect();
+
+    private OrientationHelper(RecyclerView.LayoutManager layoutManager) {
+        mLayoutManager = layoutManager;
+    }
+
+    /**
+     * Call this method after onLayout method is complete if state is NOT pre-layout.
+     * This method records information like layout bounds that might be useful in the next layout
+     * calculations.
+     */
+    public void onLayoutComplete() {
+        mLastTotalSpace = getTotalSpace();
+    }
+
+    /**
+     * Returns the layout space change between the previous layout pass and current layout pass.
+     * <p>
+     * Make sure you call {@link #onLayoutComplete()} at the end of your LayoutManager's
+     * {@link RecyclerView.LayoutManager#onLayoutChildren(RecyclerView.Recycler,
+     * RecyclerView.State)} method.
+     *
+     * @return The difference between the current total space and previous layout's total space.
+     * @see #onLayoutComplete()
+     */
+    public int getTotalSpaceChange() {
+        return INVALID_SIZE == mLastTotalSpace ? 0 : getTotalSpace() - mLastTotalSpace;
+    }
+
+    /**
+     * Returns the start of the view including its decoration and margin.
+     * <p>
+     * For example, for the horizontal helper, if a View's left is at pixel 20, has 2px left
+     * decoration and 3px left margin, returned value will be 15px.
+     *
+     * @param view The view element to check
+     * @return The first pixel of the element
+     * @see #getDecoratedEnd(android.view.View)
+     */
+    public abstract int getDecoratedStart(View view);
+
+    /**
+     * Returns the end of the view including its decoration and margin.
+     * <p>
+     * For example, for the horizontal helper, if a View's right is at pixel 200, has 2px right
+     * decoration and 3px right margin, returned value will be 205.
+     *
+     * @param view The view element to check
+     * @return The last pixel of the element
+     * @see #getDecoratedStart(android.view.View)
+     */
+    public abstract int getDecoratedEnd(View view);
+
+    /**
+     * Returns the end of the View after its matrix transformations are applied to its layout
+     * position.
+     * <p>
+     * This method is useful when trying to detect the visible edge of a View.
+     * <p>
+     * It includes the decorations but does not include the margins.
+     *
+     * @param view The view whose transformed end will be returned
+     * @return The end of the View after its decor insets and transformation matrix is applied to
+     * its position
+     *
+     * @see RecyclerView.LayoutManager#getTransformedBoundingBox(View, boolean, Rect)
+     */
+    public abstract int getTransformedEndWithDecoration(View view);
+
+    /**
+     * Returns the start of the View after its matrix transformations are applied to its layout
+     * position.
+     * <p>
+     * This method is useful when trying to detect the visible edge of a View.
+     * <p>
+     * It includes the decorations but does not include the margins.
+     *
+     * @param view The view whose transformed start will be returned
+     * @return The start of the View after its decor insets and transformation matrix is applied to
+     * its position
+     *
+     * @see RecyclerView.LayoutManager#getTransformedBoundingBox(View, boolean, Rect)
+     */
+    public abstract int getTransformedStartWithDecoration(View view);
+
+    /**
+     * Returns the space occupied by this View in the current orientation including decorations and
+     * margins.
+     *
+     * @param view The view element to check
+     * @return Total space occupied by this view
+     * @see #getDecoratedMeasurementInOther(View)
+     */
+    public abstract int getDecoratedMeasurement(View view);
+
+    /**
+     * Returns the space occupied by this View in the perpendicular orientation including
+     * decorations and margins.
+     *
+     * @param view The view element to check
+     * @return Total space occupied by this view in the perpendicular orientation to current one
+     * @see #getDecoratedMeasurement(View)
+     */
+    public abstract int getDecoratedMeasurementInOther(View view);
+
+    /**
+     * Returns the start position of the layout after the start padding is added.
+     *
+     * @return The very first pixel we can draw.
+     */
+    public abstract int getStartAfterPadding();
+
+    /**
+     * Returns the end position of the layout after the end padding is removed.
+     *
+     * @return The end boundary for this layout.
+     */
+    public abstract int getEndAfterPadding();
+
+    /**
+     * Returns the end position of the layout without taking padding into account.
+     *
+     * @return The end boundary for this layout without considering padding.
+     */
+    public abstract int getEnd();
+
+    /**
+     * Offsets all children's positions by the given amount.
+     *
+     * @param amount Value to add to each child's layout parameters
+     */
+    public abstract void offsetChildren(int amount);
+
+    /**
+     * Returns the total space to layout. This number is the difference between
+     * {@link #getEndAfterPadding()} and {@link #getStartAfterPadding()}.
+     *
+     * @return Total space to layout children
+     */
+    public abstract int getTotalSpace();
+
+    /**
+     * Offsets the child in this orientation.
+     *
+     * @param view   View to offset
+     * @param offset offset amount
+     */
+    public abstract void offsetChild(View view, int offset);
+
+    /**
+     * Returns the padding at the end of the layout. For horizontal helper, this is the right
+     * padding and for vertical helper, this is the bottom padding. This method does not check
+     * whether the layout is RTL or not.
+     *
+     * @return The padding at the end of the layout.
+     */
+    public abstract int getEndPadding();
+
+    /**
+     * Returns the MeasureSpec mode for the current orientation from the LayoutManager.
+     *
+     * @return The current measure spec mode.
+     *
+     * @see View.MeasureSpec
+     * @see RecyclerView.LayoutManager#getWidthMode()
+     * @see RecyclerView.LayoutManager#getHeightMode()
+     */
+    public abstract int getMode();
+
+    /**
+     * Returns the MeasureSpec mode for the perpendicular orientation from the LayoutManager.
+     *
+     * @return The current measure spec mode.
+     *
+     * @see View.MeasureSpec
+     * @see RecyclerView.LayoutManager#getWidthMode()
+     * @see RecyclerView.LayoutManager#getHeightMode()
+     */
+    public abstract int getModeInOther();
+
+    /**
+     * Creates an OrientationHelper for the given LayoutManager and orientation.
+     *
+     * @param layoutManager LayoutManager to attach to
+     * @param orientation   Desired orientation. Should be {@link #HORIZONTAL} or {@link #VERTICAL}
+     * @return A new OrientationHelper
+     */
+    public static OrientationHelper createOrientationHelper(
+            RecyclerView.LayoutManager layoutManager, int orientation) {
+        switch (orientation) {
+            case HORIZONTAL:
+                return createHorizontalHelper(layoutManager);
+            case VERTICAL:
+                return createVerticalHelper(layoutManager);
+        }
+        throw new IllegalArgumentException("invalid orientation");
+    }
+
+    /**
+     * Creates a horizontal OrientationHelper for the given LayoutManager.
+     *
+     * @param layoutManager The LayoutManager to attach to.
+     * @return A new OrientationHelper
+     */
+    public static OrientationHelper createHorizontalHelper(
+            RecyclerView.LayoutManager layoutManager) {
+        return new OrientationHelper(layoutManager) {
+            @Override
+            public int getEndAfterPadding() {
+                return mLayoutManager.getWidth() - mLayoutManager.getPaddingRight();
+            }
+
+            @Override
+            public int getEnd() {
+                return mLayoutManager.getWidth();
+            }
+
+            @Override
+            public void offsetChildren(int amount) {
+                mLayoutManager.offsetChildrenHorizontal(amount);
+            }
+
+            @Override
+            public int getStartAfterPadding() {
+                return mLayoutManager.getPaddingLeft();
+            }
+
+            @Override
+            public int getDecoratedMeasurement(View view) {
+                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                        view.getLayoutParams();
+                return mLayoutManager.getDecoratedMeasuredWidth(view) + params.leftMargin
+                        + params.rightMargin;
+            }
+
+            @Override
+            public int getDecoratedMeasurementInOther(View view) {
+                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                        view.getLayoutParams();
+                return mLayoutManager.getDecoratedMeasuredHeight(view) + params.topMargin
+                        + params.bottomMargin;
+            }
+
+            @Override
+            public int getDecoratedEnd(View view) {
+                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                        view.getLayoutParams();
+                return mLayoutManager.getDecoratedRight(view) + params.rightMargin;
+            }
+
+            @Override
+            public int getDecoratedStart(View view) {
+                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                        view.getLayoutParams();
+                return mLayoutManager.getDecoratedLeft(view) - params.leftMargin;
+            }
+
+            @Override
+            public int getTransformedEndWithDecoration(View view) {
+                mLayoutManager.getTransformedBoundingBox(view, true, mTmpRect);
+                return mTmpRect.right;
+            }
+
+            @Override
+            public int getTransformedStartWithDecoration(View view) {
+                mLayoutManager.getTransformedBoundingBox(view, true, mTmpRect);
+                return mTmpRect.left;
+            }
+
+            @Override
+            public int getTotalSpace() {
+                return mLayoutManager.getWidth() - mLayoutManager.getPaddingLeft()
+                        - mLayoutManager.getPaddingRight();
+            }
+
+            @Override
+            public void offsetChild(View view, int offset) {
+                view.offsetLeftAndRight(offset);
+            }
+
+            @Override
+            public int getEndPadding() {
+                return mLayoutManager.getPaddingRight();
+            }
+
+            @Override
+            public int getMode() {
+                return mLayoutManager.getWidthMode();
+            }
+
+            @Override
+            public int getModeInOther() {
+                return mLayoutManager.getHeightMode();
+            }
+        };
+    }
+
+    /**
+     * Creates a vertical OrientationHelper for the given LayoutManager.
+     *
+     * @param layoutManager The LayoutManager to attach to.
+     * @return A new OrientationHelper
+     */
+    public static OrientationHelper createVerticalHelper(RecyclerView.LayoutManager layoutManager) {
+        return new OrientationHelper(layoutManager) {
+            @Override
+            public int getEndAfterPadding() {
+                return mLayoutManager.getHeight() - mLayoutManager.getPaddingBottom();
+            }
+
+            @Override
+            public int getEnd() {
+                return mLayoutManager.getHeight();
+            }
+
+            @Override
+            public void offsetChildren(int amount) {
+                mLayoutManager.offsetChildrenVertical(amount);
+            }
+
+            @Override
+            public int getStartAfterPadding() {
+                return mLayoutManager.getPaddingTop();
+            }
+
+            @Override
+            public int getDecoratedMeasurement(View view) {
+                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                        view.getLayoutParams();
+                return mLayoutManager.getDecoratedMeasuredHeight(view) + params.topMargin
+                        + params.bottomMargin;
+            }
+
+            @Override
+            public int getDecoratedMeasurementInOther(View view) {
+                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                        view.getLayoutParams();
+                return mLayoutManager.getDecoratedMeasuredWidth(view) + params.leftMargin
+                        + params.rightMargin;
+            }
+
+            @Override
+            public int getDecoratedEnd(View view) {
+                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                        view.getLayoutParams();
+                return mLayoutManager.getDecoratedBottom(view) + params.bottomMargin;
+            }
+
+            @Override
+            public int getDecoratedStart(View view) {
+                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams)
+                        view.getLayoutParams();
+                return mLayoutManager.getDecoratedTop(view) - params.topMargin;
+            }
+
+            @Override
+            public int getTransformedEndWithDecoration(View view) {
+                mLayoutManager.getTransformedBoundingBox(view, true, mTmpRect);
+                return mTmpRect.bottom;
+            }
+
+            @Override
+            public int getTransformedStartWithDecoration(View view) {
+                mLayoutManager.getTransformedBoundingBox(view, true, mTmpRect);
+                return mTmpRect.top;
+            }
+
+            @Override
+            public int getTotalSpace() {
+                return mLayoutManager.getHeight() - mLayoutManager.getPaddingTop()
+                        - mLayoutManager.getPaddingBottom();
+            }
+
+            @Override
+            public void offsetChild(View view, int offset) {
+                view.offsetTopAndBottom(offset);
+            }
+
+            @Override
+            public int getEndPadding() {
+                return mLayoutManager.getPaddingBottom();
+            }
+
+            @Override
+            public int getMode() {
+                return mLayoutManager.getHeightMode();
+            }
+
+            @Override
+            public int getModeInOther() {
+                return mLayoutManager.getWidthMode();
+            }
+        };
+    }
+}
diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java
new file mode 100644
index 0000000..0cf3164
--- /dev/null
+++ b/core/java/com/android/internal/widget/RecyclerView.java
@@ -0,0 +1,12255 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.annotation.CallSuper;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.database.Observable;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.AbsSavedState;
+import android.view.Display;
+import android.view.FocusFinder;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.Interpolator;
+import android.widget.EdgeEffect;
+import android.widget.OverScroller;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.widget.RecyclerView.ItemAnimator.ItemHolderInfo;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A flexible view for providing a limited window into a large data set.
+ *
+ * <h3>Glossary of terms:</h3>
+ *
+ * <ul>
+ *     <li><em>Adapter:</em> A subclass of {@link Adapter} responsible for providing views
+ *     that represent items in a data set.</li>
+ *     <li><em>Position:</em> The position of a data item within an <em>Adapter</em>.</li>
+ *     <li><em>Index:</em> The index of an attached child view as used in a call to
+ *     {@link ViewGroup#getChildAt}. Contrast with <em>Position.</em></li>
+ *     <li><em>Binding:</em> The process of preparing a child view to display data corresponding
+ *     to a <em>position</em> within the adapter.</li>
+ *     <li><em>Recycle (view):</em> A view previously used to display data for a specific adapter
+ *     position may be placed in a cache for later reuse to display the same type of data again
+ *     later. This can drastically improve performance by skipping initial layout inflation
+ *     or construction.</li>
+ *     <li><em>Scrap (view):</em> A child view that has entered into a temporarily detached
+ *     state during layout. Scrap views may be reused without becoming fully detached
+ *     from the parent RecyclerView, either unmodified if no rebinding is required or modified
+ *     by the adapter if the view was considered <em>dirty</em>.</li>
+ *     <li><em>Dirty (view):</em> A child view that must be rebound by the adapter before
+ *     being displayed.</li>
+ * </ul>
+ *
+ * <h4>Positions in RecyclerView:</h4>
+ * <p>
+ * RecyclerView introduces an additional level of abstraction between the {@link Adapter} and
+ * {@link LayoutManager} to be able to detect data set changes in batches during a layout
+ * calculation. This saves LayoutManager from tracking adapter changes to calculate animations.
+ * It also helps with performance because all view bindings happen at the same time and unnecessary
+ * bindings are avoided.
+ * <p>
+ * For this reason, there are two types of <code>position</code> related methods in RecyclerView:
+ * <ul>
+ *     <li>layout position: Position of an item in the latest layout calculation. This is the
+ *     position from the LayoutManager's perspective.</li>
+ *     <li>adapter position: Position of an item in the adapter. This is the position from
+ *     the Adapter's perspective.</li>
+ * </ul>
+ * <p>
+ * These two positions are the same except the time between dispatching <code>adapter.notify*
+ * </code> events and calculating the updated layout.
+ * <p>
+ * Methods that return or receive <code>*LayoutPosition*</code> use position as of the latest
+ * layout calculation (e.g. {@link ViewHolder#getLayoutPosition()},
+ * {@link #findViewHolderForLayoutPosition(int)}). These positions include all changes until the
+ * last layout calculation. You can rely on these positions to be consistent with what user is
+ * currently seeing on the screen. For example, if you have a list of items on the screen and user
+ * asks for the 5<sup>th</sup> element, you should use these methods as they'll match what user
+ * is seeing.
+ * <p>
+ * The other set of position related methods are in the form of
+ * <code>*AdapterPosition*</code>. (e.g. {@link ViewHolder#getAdapterPosition()},
+ * {@link #findViewHolderForAdapterPosition(int)}) You should use these methods when you need to
+ * work with up-to-date adapter positions even if they may not have been reflected to layout yet.
+ * For example, if you want to access the item in the adapter on a ViewHolder click, you should use
+ * {@link ViewHolder#getAdapterPosition()}. Beware that these methods may not be able to calculate
+ * adapter positions if {@link Adapter#notifyDataSetChanged()} has been called and new layout has
+ * not yet been calculated. For this reasons, you should carefully handle {@link #NO_POSITION} or
+ * <code>null</code> results from these methods.
+ * <p>
+ * When writing a {@link LayoutManager} you almost always want to use layout positions whereas when
+ * writing an {@link Adapter}, you probably want to use adapter positions.
+ *
+ * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_layoutManager
+ */
+public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild {
+
+    static final String TAG = "RecyclerView";
+
+    static final boolean DEBUG = false;
+
+    private static final int[]  NESTED_SCROLLING_ATTRS = { android.R.attr.nestedScrollingEnabled };
+
+    private static final int[] CLIP_TO_PADDING_ATTR = {android.R.attr.clipToPadding};
+
+    /**
+     * On Kitkat and JB MR2, there is a bug which prevents DisplayList from being invalidated if
+     * a View is two levels deep(wrt to ViewHolder.itemView). DisplayList can be invalidated by
+     * setting View's visibility to INVISIBLE when View is detached. On Kitkat and JB MR2, Recycler
+     * recursively traverses itemView and invalidates display list for each ViewGroup that matches
+     * this criteria.
+     */
+    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,
+     * this value might be garbage. To save LayoutManagers from it, RecyclerView sets the size to
+     * 0 when mode is unspecified.
+     */
+    static final boolean ALLOW_SIZE_IN_UNSPECIFIED_SPEC = Build.VERSION.SDK_INT >= 23;
+
+    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_THREAD_GAP_WORK = Build.VERSION.SDK_INT >= 21;
+
+    /**
+     * FocusFinder#findNextFocus is broken on ICS MR1 and older for View.FOCUS_BACKWARD direction.
+     * We convert it to an absolute direction such as FOCUS_DOWN or FOCUS_LEFT.
+     */
+    private static final boolean FORCE_ABS_FOCUS_SEARCH_DIRECTION = Build.VERSION.SDK_INT <= 15;
+
+    /**
+     * on API 15-, a focused child can still be considered a focused child of RV even after
+     * it's being removed or its focusable flag is set to false. This is because when this focused
+     * child is detached, the reference to this child is not removed in clearFocus. API 16 and above
+     * properly handle this case by calling ensureInputFocusOnFirstFocusable or rootViewRequestFocus
+     * to request focus on a new child, which will clear the focus on the old (detached) child as a
+     * side-effect.
+     */
+    private static final boolean IGNORE_DETACHED_FOCUSED_CHILD = Build.VERSION.SDK_INT <= 15;
+
+    static final boolean DISPATCH_TEMP_DETACH = false;
+    public static final int HORIZONTAL = 0;
+    public static final int VERTICAL = 1;
+
+    public static final int NO_POSITION = -1;
+    public static final long NO_ID = -1;
+    public static final int INVALID_TYPE = -1;
+
+    /**
+     * Constant for use with {@link #setScrollingTouchSlop(int)}. Indicates
+     * that the RecyclerView should use the standard touch slop for smooth,
+     * continuous scrolling.
+     */
+    public static final int TOUCH_SLOP_DEFAULT = 0;
+
+    /**
+     * Constant for use with {@link #setScrollingTouchSlop(int)}. Indicates
+     * that the RecyclerView should use the standard touch slop for scrolling
+     * widgets that snap to a page or other coarse-grained barrier.
+     */
+    public static final int TOUCH_SLOP_PAGING = 1;
+
+    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.
+     */
+    static final String TRACE_SCROLL_TAG = "RV Scroll";
+
+    /**
+     * OnLayout has been called by the View system.
+     * If this shows up too many times in Systrace, make sure the children of RecyclerView do not
+     * update themselves directly. This will cause a full re-layout but when it happens via the
+     * Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.
+     */
+    private static final String TRACE_ON_LAYOUT_TAG = "RV OnLayout";
+
+    /**
+     * NotifyDataSetChanged or equal has been called.
+     * If this is taking a long time, try sending granular notify adapter changes instead of just
+     * calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter
+     * might help.
+     */
+    private static final String TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG = "RV FullInvalidate";
+
+    /**
+     * RecyclerView is doing a layout for partial adapter updates (we know what has changed)
+     * If this is taking a long time, you may have dispatched too many Adapter updates causing too
+     * many Views being rebind. Make sure all are necessary and also prefer using notify*Range
+     * methods.
+     */
+    private static final String TRACE_HANDLE_ADAPTER_UPDATES_TAG = "RV PartialInvalidate";
+
+    /**
+     * RecyclerView is rebinding a View.
+     * If this is taking a lot of time, consider optimizing your layout or make sure you are not
+     * doing extra operations in onBindViewHolder call.
+     */
+    static final String TRACE_BIND_VIEW_TAG = "RV OnBindView";
+
+    /**
+     * RecyclerView is attempting to pre-populate off screen views.
+     */
+    static final String TRACE_PREFETCH_TAG = "RV Prefetch";
+
+    /**
+     * RecyclerView is attempting to pre-populate off screen itemviews within an off screen
+     * RecyclerView.
+     */
+    static final String TRACE_NESTED_PREFETCH_TAG = "RV Nested Prefetch";
+
+    /**
+     * RecyclerView is creating a new View.
+     * If too many of these present in Systrace:
+     * - There might be a problem in Recycling (e.g. custom Animations that set transient state and
+     * prevent recycling or ItemAnimator not implementing the contract properly. ({@link
+     * > Adapter#onFailedToRecycleView(ViewHolder)})
+     *
+     * - There might be too many item view types.
+     * > Try merging them
+     *
+     * - There might be too many itemChange animations and not enough space in RecyclerPool.
+     * >Try increasing your pool size and item cache size.
+     */
+    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};
+
+    private final RecyclerViewDataObserver mObserver = new RecyclerViewDataObserver();
+
+    final Recycler mRecycler = new Recycler();
+
+    private SavedState mPendingSavedState;
+
+    /**
+     * Handles adapter updates
+     */
+    AdapterHelper mAdapterHelper;
+
+    /**
+     * Handles abstraction between LayoutManager children and RecyclerView children
+     */
+    ChildHelper mChildHelper;
+
+    /**
+     * Keeps data about views to be used for animations
+     */
+    final ViewInfoStore mViewInfoStore = new ViewInfoStore();
+
+    /**
+     * Prior to L, there is no way to query this variable which is why we override the setter and
+     * track it here.
+     */
+    boolean mClipToPadding;
+
+    /**
+     * Note: this Runnable is only ever posted if:
+     * 1) We've been through first layout
+     * 2) We know we have a fixed size (mHasFixedSize)
+     * 3) We're attached
+     */
+    final Runnable mUpdateChildViewsRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (!mFirstLayoutComplete || isLayoutRequested()) {
+                // a layout request will happen, we should not do layout here.
+                return;
+            }
+            if (!mIsAttached) {
+                requestLayout();
+                // if we are not attached yet, mark us as requiring layout and skip
+                return;
+            }
+            if (mLayoutFrozen) {
+                mLayoutRequestEaten = true;
+                return; //we'll process updates when ice age ends.
+            }
+            consumePendingUpdateOperations();
+        }
+    };
+
+    final Rect mTempRect = new Rect();
+    private final Rect mTempRect2 = new Rect();
+    final RectF mTempRectF = new RectF();
+    Adapter mAdapter;
+    @VisibleForTesting LayoutManager mLayout;
+    RecyclerListener mRecyclerListener;
+    final ArrayList<ItemDecoration> mItemDecorations = new ArrayList<>();
+    private final ArrayList<OnItemTouchListener> mOnItemTouchListeners =
+            new ArrayList<>();
+    private OnItemTouchListener mActiveOnItemTouchListener;
+    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;
+
+    boolean mLayoutRequestEaten;
+    boolean mLayoutFrozen;
+    private boolean mIgnoreMotionEventTillDown;
+
+    // binary OR of change events that were eaten during a layout or scroll.
+    private int mEatenAccessibilityChangeFlags;
+    boolean mAdapterUpdateDuringMeasure;
+
+    private final AccessibilityManager mAccessibilityManager;
+    private List<OnChildAttachStateChangeListener> mOnChildAttachStateListeners;
+
+    /**
+     * 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 until layout.
+     *
+     * Attached items are invalid until next layout, at which point layout will animate/replace
+     * items as necessary, building up content from the (effectively) new adapter from scratch.
+     *
+     * Cached items must be discarded when setting this to true, so that the cache may be freely
+     * used by prefetching until the next layout occurs.
+     *
+     * @see #setDataSetChangedAfterLayout()
+     */
+    boolean mDataSetHasChangedAfterLayout = false;
+
+    /**
+     * This variable is incremented during a dispatchLayout and/or scroll.
+     * Some methods should not be called during these periods (e.g. adapter data change).
+     * Doing so will create hard to find bugs so we better check it and throw an exception.
+     *
+     * @see #assertInLayoutOrScroll(String)
+     * @see #assertNotInLayoutOrScroll(String)
+     */
+    private int mLayoutOrScrollCounter = 0;
+
+    /**
+     * Similar to mLayoutOrScrollCounter but logs a warning instead of throwing an exception
+     * (for API compatibility).
+     * <p>
+     * It is a bad practice for a developer to update the data in a scroll callback since it is
+     * potentially called during a layout.
+     */
+    private int mDispatchScrollCounter = 0;
+
+    private EdgeEffect mLeftGlow, mTopGlow, mRightGlow, mBottomGlow;
+
+    ItemAnimator mItemAnimator = new DefaultItemAnimator();
+
+    private static final int INVALID_POINTER = -1;
+
+    /**
+     * The RecyclerView is not currently scrolling.
+     * @see #getScrollState()
+     */
+    public static final int SCROLL_STATE_IDLE = 0;
+
+    /**
+     * The RecyclerView is currently being dragged by outside input such as user touch input.
+     * @see #getScrollState()
+     */
+    public static final int SCROLL_STATE_DRAGGING = 1;
+
+    /**
+     * The RecyclerView is currently animating to a final position while not under
+     * outside control.
+     * @see #getScrollState()
+     */
+    public static final int SCROLL_STATE_SETTLING = 2;
+
+    static final long FOREVER_NS = Long.MAX_VALUE;
+
+    // Touch/scrolling handling
+
+    private int mScrollState = SCROLL_STATE_IDLE;
+    private int mScrollPointerId = INVALID_POINTER;
+    private VelocityTracker mVelocityTracker;
+    private int mInitialTouchX;
+    private int mInitialTouchY;
+    private int mLastTouchX;
+    private int mLastTouchY;
+    private int mTouchSlop;
+    private OnFlingListener mOnFlingListener;
+    private final int mMinFlingVelocity;
+    private final int mMaxFlingVelocity;
+    // This value is used when handling generic motion events.
+    private float mScrollFactor = Float.MIN_VALUE;
+    private boolean mPreserveFocusAfterLayout = true;
+
+    final ViewFlinger mViewFlinger = new ViewFlinger();
+
+    GapWorker mGapWorker;
+    GapWorker.LayoutPrefetchRegistryImpl mPrefetchRegistry =
+            ALLOW_THREAD_GAP_WORK ? new GapWorker.LayoutPrefetchRegistryImpl() : null;
+
+    final State mState = new State();
+
+    private OnScrollListener mScrollListener;
+    private List<OnScrollListener> mScrollListeners;
+
+    // For use in item animations
+    boolean mItemsAddedOrRemoved = false;
+    boolean mItemsChanged = false;
+    private ItemAnimator.ItemAnimatorListener mItemAnimatorListener =
+            new ItemAnimatorRestoreListener();
+    boolean mPostedAnimatorRunner = false;
+    RecyclerViewAccessibilityDelegate mAccessibilityDelegate;
+    private ChildDrawingOrderCallback mChildDrawingOrderCallback;
+
+    // simple array to keep min and max child position during a layout calculation
+    // preserved not to create a new one in each layout pass
+    private final int[] mMinMaxLayoutPositions = new int[2];
+
+    private final int[] mScrollOffset = new int[2];
+    private final int[] mScrollConsumed = new int[2];
+    private final int[] mNestedOffsets = new int[2];
+
+    /**
+     * These are views that had their a11y importance changed during a layout. We defer these events
+     * until the end of the layout because a11y service may make sync calls back to the RV while
+     * the View's state is undefined.
+     */
+    @VisibleForTesting
+    final List<ViewHolder> mPendingAccessibilityImportanceChange = new ArrayList();
+
+    private Runnable mItemAnimatorRunner = new Runnable() {
+        @Override
+        public void run() {
+            if (mItemAnimator != null) {
+                mItemAnimator.runPendingAnimations();
+            }
+            mPostedAnimatorRunner = false;
+        }
+    };
+
+    static final Interpolator sQuinticInterpolator = new Interpolator() {
+        @Override
+        public float getInterpolation(float t) {
+            t -= 1.0f;
+            return t * t * t * t * t + 1.0f;
+        }
+    };
+
+    /**
+     * The callback to convert view info diffs into animations.
+     */
+    private final ViewInfoStore.ProcessCallback mViewInfoProcessCallback =
+            new ViewInfoStore.ProcessCallback() {
+        @Override
+        public void processDisappeared(ViewHolder viewHolder, @NonNull ItemHolderInfo info,
+                @Nullable ItemHolderInfo postInfo) {
+            mRecycler.unscrapView(viewHolder);
+            animateDisappearance(viewHolder, info, postInfo);
+        }
+        @Override
+        public void processAppeared(ViewHolder viewHolder,
+                ItemHolderInfo preInfo, ItemHolderInfo info) {
+            animateAppearance(viewHolder, preInfo, info);
+        }
+
+        @Override
+        public void processPersistent(ViewHolder viewHolder,
+                @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
+            viewHolder.setIsRecyclable(false);
+            if (mDataSetHasChangedAfterLayout) {
+                // since it was rebound, use change instead as we'll be mapping them from
+                // stable ids. If stable ids were false, we would not be running any
+                // animations
+                if (mItemAnimator.animateChange(viewHolder, viewHolder, preInfo, postInfo)) {
+                    postAnimationRunner();
+                }
+            } else if (mItemAnimator.animatePersistence(viewHolder, preInfo, postInfo)) {
+                postAnimationRunner();
+            }
+        }
+        @Override
+        public void unused(ViewHolder viewHolder) {
+            mLayout.removeAndRecycleView(viewHolder.itemView, mRecycler);
+        }
+    };
+
+    public RecyclerView(Context context) {
+        this(context, null);
+    }
+
+    public RecyclerView(Context context, @Nullable AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public RecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        if (attrs != null) {
+            TypedArray a = context.obtainStyledAttributes(attrs, CLIP_TO_PADDING_ATTR, defStyle, 0);
+            mClipToPadding = a.getBoolean(0, true);
+            a.recycle();
+        } else {
+            mClipToPadding = true;
+        }
+        setScrollContainer(true);
+        setFocusableInTouchMode(true);
+
+        final ViewConfiguration vc = ViewConfiguration.get(context);
+        mTouchSlop = vc.getScaledTouchSlop();
+        mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
+        mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
+        setWillNotDraw(getOverScrollMode() == View.OVER_SCROLL_NEVER);
+
+        mItemAnimator.setListener(mItemAnimatorListener);
+        initAdapterManager();
+        initChildrenHelper();
+        // If not explicitly specified this view is important for accessibility.
+        if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+        }
+        mAccessibilityManager = (AccessibilityManager) getContext()
+                .getSystemService(Context.ACCESSIBILITY_SERVICE);
+        setAccessibilityDelegateCompat(new RecyclerViewAccessibilityDelegate(this));
+        // Create the layoutManager if specified.
+
+        boolean nestedScrollingEnabled = true;
+
+        if (attrs != null) {
+            int defStyleRes = 0;
+            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView,
+                    defStyle, defStyleRes);
+            String layoutManagerName = a.getString(R.styleable.RecyclerView_layoutManager);
+            int descendantFocusability = a.getInt(
+                    R.styleable.RecyclerView_descendantFocusability, -1);
+            if (descendantFocusability == -1) {
+                setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
+            }
+            a.recycle();
+            createLayoutManager(context, layoutManagerName, attrs, defStyle, defStyleRes);
+
+            if (Build.VERSION.SDK_INT >= 21) {
+                a = context.obtainStyledAttributes(attrs, NESTED_SCROLLING_ATTRS,
+                        defStyle, defStyleRes);
+                nestedScrollingEnabled = a.getBoolean(0, true);
+                a.recycle();
+            }
+        } else {
+            setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
+        }
+
+        // Re-set whether nested scrolling is enabled so that it is set on all API levels
+        setNestedScrollingEnabled(nestedScrollingEnabled);
+    }
+
+    /**
+     * Returns the accessibility delegate compatibility implementation used by the RecyclerView.
+     * @return An instance of AccessibilityDelegateCompat used by RecyclerView
+     */
+    public RecyclerViewAccessibilityDelegate getCompatAccessibilityDelegate() {
+        return mAccessibilityDelegate;
+    }
+
+    /**
+     * Sets the accessibility delegate compatibility implementation used by RecyclerView.
+     * @param accessibilityDelegate The accessibility delegate to be used by RecyclerView.
+     */
+    public void setAccessibilityDelegateCompat(
+            RecyclerViewAccessibilityDelegate accessibilityDelegate) {
+        mAccessibilityDelegate = accessibilityDelegate;
+        setAccessibilityDelegate(mAccessibilityDelegate);
+    }
+
+    /**
+     * Instantiate and set a LayoutManager, if specified in the attributes.
+     */
+    private void createLayoutManager(Context context, String className, AttributeSet attrs,
+            int defStyleAttr, int defStyleRes) {
+        if (className != null) {
+            className = className.trim();
+            if (className.length() != 0) {  // Can't use isEmpty since it was added in API 9.
+                className = getFullClassName(context, className);
+                try {
+                    ClassLoader classLoader;
+                    if (isInEditMode()) {
+                        // Stupid layoutlib cannot handle simple class loaders.
+                        classLoader = this.getClass().getClassLoader();
+                    } else {
+                        classLoader = context.getClassLoader();
+                    }
+                    Class<? extends LayoutManager> layoutManagerClass =
+                            classLoader.loadClass(className).asSubclass(LayoutManager.class);
+                    Constructor<? extends LayoutManager> constructor;
+                    Object[] constructorArgs = null;
+                    try {
+                        constructor = layoutManagerClass
+                                .getConstructor(LAYOUT_MANAGER_CONSTRUCTOR_SIGNATURE);
+                        constructorArgs = new Object[]{context, attrs, defStyleAttr, defStyleRes};
+                    } catch (NoSuchMethodException e) {
+                        try {
+                            constructor = layoutManagerClass.getConstructor();
+                        } catch (NoSuchMethodException e1) {
+                            e1.initCause(e);
+                            throw new IllegalStateException(attrs.getPositionDescription()
+                                    + ": Error creating LayoutManager " + className, e1);
+                        }
+                    }
+                    constructor.setAccessible(true);
+                    setLayoutManager(constructor.newInstance(constructorArgs));
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalStateException(attrs.getPositionDescription()
+                            + ": Unable to find LayoutManager " + className, e);
+                } catch (InvocationTargetException e) {
+                    throw new IllegalStateException(attrs.getPositionDescription()
+                            + ": Could not instantiate the LayoutManager: " + className, e);
+                } catch (InstantiationException e) {
+                    throw new IllegalStateException(attrs.getPositionDescription()
+                            + ": Could not instantiate the LayoutManager: " + className, e);
+                } catch (IllegalAccessException e) {
+                    throw new IllegalStateException(attrs.getPositionDescription()
+                            + ": Cannot access non-public constructor " + className, e);
+                } catch (ClassCastException e) {
+                    throw new IllegalStateException(attrs.getPositionDescription()
+                            + ": Class is not a LayoutManager " + className, e);
+                }
+            }
+        }
+    }
+
+    private String getFullClassName(Context context, String className) {
+        if (className.charAt(0) == '.') {
+            return context.getPackageName() + className;
+        }
+        if (className.contains(".")) {
+            return className;
+        }
+        return RecyclerView.class.getPackage().getName() + '.' + className;
+    }
+
+    private void initChildrenHelper() {
+        mChildHelper = new ChildHelper(new ChildHelper.Callback() {
+            @Override
+            public int getChildCount() {
+                return RecyclerView.this.getChildCount();
+            }
+
+            @Override
+            public void addView(View child, int index) {
+                RecyclerView.this.addView(child, index);
+                dispatchChildAttached(child);
+            }
+
+            @Override
+            public int indexOfChild(View view) {
+                return RecyclerView.this.indexOfChild(view);
+            }
+
+            @Override
+            public void removeViewAt(int index) {
+                final View child = RecyclerView.this.getChildAt(index);
+                if (child != null) {
+                    dispatchChildDetached(child);
+                }
+                RecyclerView.this.removeViewAt(index);
+            }
+
+            @Override
+            public View getChildAt(int offset) {
+                return RecyclerView.this.getChildAt(offset);
+            }
+
+            @Override
+            public void removeAllViews() {
+                final int count = getChildCount();
+                for (int i = 0; i < count; i++) {
+                    dispatchChildDetached(getChildAt(i));
+                }
+                RecyclerView.this.removeAllViews();
+            }
+
+            @Override
+            public ViewHolder getChildViewHolder(View view) {
+                return getChildViewHolderInt(view);
+            }
+
+            @Override
+            public void attachViewToParent(View child, int index,
+                    ViewGroup.LayoutParams layoutParams) {
+                final ViewHolder vh = getChildViewHolderInt(child);
+                if (vh != null) {
+                    if (!vh.isTmpDetached() && !vh.shouldIgnore()) {
+                        throw new IllegalArgumentException("Called attach on a child which is not"
+                                + " detached: " + vh);
+                    }
+                    if (DEBUG) {
+                        Log.d(TAG, "reAttach " + vh);
+                    }
+                    vh.clearTmpDetachFlag();
+                }
+                RecyclerView.this.attachViewToParent(child, index, layoutParams);
+            }
+
+            @Override
+            public void detachViewFromParent(int offset) {
+                final View view = getChildAt(offset);
+                if (view != null) {
+                    final ViewHolder vh = getChildViewHolderInt(view);
+                    if (vh != null) {
+                        if (vh.isTmpDetached() && !vh.shouldIgnore()) {
+                            throw new IllegalArgumentException("called detach on an already"
+                                    + " detached child " + vh);
+                        }
+                        if (DEBUG) {
+                            Log.d(TAG, "tmpDetach " + vh);
+                        }
+                        vh.addFlags(ViewHolder.FLAG_TMP_DETACHED);
+                    }
+                }
+                RecyclerView.this.detachViewFromParent(offset);
+            }
+
+            @Override
+            public void onEnteredHiddenState(View child) {
+                final ViewHolder vh = getChildViewHolderInt(child);
+                if (vh != null) {
+                    vh.onEnteredHiddenState(RecyclerView.this);
+                }
+            }
+
+            @Override
+            public void onLeftHiddenState(View child) {
+                final ViewHolder vh = getChildViewHolderInt(child);
+                if (vh != null) {
+                    vh.onLeftHiddenState(RecyclerView.this);
+                }
+            }
+        });
+    }
+
+    void initAdapterManager() {
+        mAdapterHelper = new AdapterHelper(new AdapterHelper.Callback() {
+            @Override
+            public ViewHolder findViewHolder(int position) {
+                final ViewHolder vh = findViewHolderForPosition(position, true);
+                if (vh == null) {
+                    return null;
+                }
+                // ensure it is not hidden because for adapter helper, the only thing matter is that
+                // LM thinks view is a child.
+                if (mChildHelper.isHidden(vh.itemView)) {
+                    if (DEBUG) {
+                        Log.d(TAG, "assuming view holder cannot be find because it is hidden");
+                    }
+                    return null;
+                }
+                return vh;
+            }
+
+            @Override
+            public void offsetPositionsForRemovingInvisible(int start, int count) {
+                offsetPositionRecordsForRemove(start, count, true);
+                mItemsAddedOrRemoved = true;
+                mState.mDeletedInvisibleItemCountSincePreviousLayout += count;
+            }
+
+            @Override
+            public void offsetPositionsForRemovingLaidOutOrNewView(
+                    int positionStart, int itemCount) {
+                offsetPositionRecordsForRemove(positionStart, itemCount, false);
+                mItemsAddedOrRemoved = true;
+            }
+
+            @Override
+            public void markViewHoldersUpdated(int positionStart, int itemCount, Object payload) {
+                viewRangeUpdate(positionStart, itemCount, payload);
+                mItemsChanged = true;
+            }
+
+            @Override
+            public void onDispatchFirstPass(AdapterHelper.UpdateOp op) {
+                dispatchUpdate(op);
+            }
+
+            void dispatchUpdate(AdapterHelper.UpdateOp op) {
+                switch (op.cmd) {
+                    case AdapterHelper.UpdateOp.ADD:
+                        mLayout.onItemsAdded(RecyclerView.this, op.positionStart, op.itemCount);
+                        break;
+                    case AdapterHelper.UpdateOp.REMOVE:
+                        mLayout.onItemsRemoved(RecyclerView.this, op.positionStart, op.itemCount);
+                        break;
+                    case AdapterHelper.UpdateOp.UPDATE:
+                        mLayout.onItemsUpdated(RecyclerView.this, op.positionStart, op.itemCount,
+                                op.payload);
+                        break;
+                    case AdapterHelper.UpdateOp.MOVE:
+                        mLayout.onItemsMoved(RecyclerView.this, op.positionStart, op.itemCount, 1);
+                        break;
+                }
+            }
+
+            @Override
+            public void onDispatchSecondPass(AdapterHelper.UpdateOp op) {
+                dispatchUpdate(op);
+            }
+
+            @Override
+            public void offsetPositionsForAdd(int positionStart, int itemCount) {
+                offsetPositionRecordsForInsert(positionStart, itemCount);
+                mItemsAddedOrRemoved = true;
+            }
+
+            @Override
+            public void offsetPositionsForMove(int from, int to) {
+                offsetPositionRecordsForMove(from, to);
+                // should we create mItemsMoved ?
+                mItemsAddedOrRemoved = true;
+            }
+        });
+    }
+
+    /**
+     * RecyclerView can perform several optimizations if it can know in advance that RecyclerView's
+     * size is not affected by the adapter contents. RecyclerView can still change its size based
+     * on other factors (e.g. its parent's size) but this size calculation cannot depend on the
+     * size of its children or contents of its adapter (except the number of items in the adapter).
+     * <p>
+     * If your use of RecyclerView falls into this category, set this to {@code true}. It will allow
+     * RecyclerView to avoid invalidating the whole layout when its adapter contents change.
+     *
+     * @param hasFixedSize true if adapter changes cannot affect the size of the RecyclerView.
+     */
+    public void setHasFixedSize(boolean hasFixedSize) {
+        mHasFixedSize = hasFixedSize;
+    }
+
+    /**
+     * @return true if the app has specified that changes in adapter content cannot change
+     * the size of the RecyclerView itself.
+     */
+    public boolean hasFixedSize() {
+        return mHasFixedSize;
+    }
+
+    @Override
+    public void setClipToPadding(boolean clipToPadding) {
+        if (clipToPadding != mClipToPadding) {
+            invalidateGlows();
+        }
+        mClipToPadding = clipToPadding;
+        super.setClipToPadding(clipToPadding);
+        if (mFirstLayoutComplete) {
+            requestLayout();
+        }
+    }
+
+    /**
+     * Returns whether this RecyclerView will clip its children to its padding, and resize (but
+     * not clip) any EdgeEffect to the padded region, if padding is present.
+     * <p>
+     * By default, children are clipped to the padding of their parent
+     * RecyclerView. This clipping behavior is only enabled if padding is non-zero.
+     *
+     * @return true if this RecyclerView clips children to its padding and resizes (but doesn't
+     *         clip) any EdgeEffect to the padded region, false otherwise.
+     *
+     * @attr name android:clipToPadding
+     */
+    @Override
+    public boolean getClipToPadding() {
+        return mClipToPadding;
+    }
+
+    /**
+     * Configure the scrolling touch slop for a specific use case.
+     *
+     * Set up the RecyclerView's scrolling motion threshold based on common usages.
+     * Valid arguments are {@link #TOUCH_SLOP_DEFAULT} and {@link #TOUCH_SLOP_PAGING}.
+     *
+     * @param slopConstant One of the <code>TOUCH_SLOP_</code> constants representing
+     *                     the intended usage of this RecyclerView
+     */
+    public void setScrollingTouchSlop(int slopConstant) {
+        final ViewConfiguration vc = ViewConfiguration.get(getContext());
+        switch (slopConstant) {
+            default:
+                Log.w(TAG, "setScrollingTouchSlop(): bad argument constant "
+                        + slopConstant + "; using default value");
+                // fall-through
+            case TOUCH_SLOP_DEFAULT:
+                mTouchSlop = vc.getScaledTouchSlop();
+                break;
+
+            case TOUCH_SLOP_PAGING:
+                mTouchSlop = vc.getScaledPagingTouchSlop();
+                break;
+        }
+    }
+
+    /**
+     * Swaps the current adapter with the provided one. It is similar to
+     * {@link #setAdapter(Adapter)} but assumes existing adapter and the new adapter uses the same
+     * {@link ViewHolder} and does not clear the RecycledViewPool.
+     * <p>
+     * Note that it still calls onAdapterChanged callbacks.
+     *
+     * @param adapter The new adapter to set, or null to set no adapter.
+     * @param removeAndRecycleExistingViews If set to true, RecyclerView will recycle all existing
+     *                                      Views. If adapters have stable ids and/or you want to
+     *                                      animate the disappearing views, you may prefer to set
+     *                                      this to false.
+     * @see #setAdapter(Adapter)
+     */
+    public void swapAdapter(Adapter adapter, boolean removeAndRecycleExistingViews) {
+        // bail out if layout is frozen
+        setLayoutFrozen(false);
+        setAdapterInternal(adapter, true, removeAndRecycleExistingViews);
+        setDataSetChangedAfterLayout();
+        requestLayout();
+    }
+    /**
+     * Set a new adapter to provide child views on demand.
+     * <p>
+     * When adapter is changed, all existing views are recycled back to the pool. If the pool has
+     * only one adapter, it will be cleared.
+     *
+     * @param adapter The new adapter to set, or null to set no adapter.
+     * @see #swapAdapter(Adapter, boolean)
+     */
+    public void setAdapter(Adapter adapter) {
+        // bail out if layout is frozen
+        setLayoutFrozen(false);
+        setAdapterInternal(adapter, false, true);
+        requestLayout();
+    }
+
+    /**
+     * Removes and recycles all views - both those currently attached, and those in the Recycler.
+     */
+    void removeAndRecycleViews() {
+        // end all running animations
+        if (mItemAnimator != null) {
+            mItemAnimator.endAnimations();
+        }
+        // Since animations are ended, mLayout.children should be equal to
+        // recyclerView.children. This may not be true if item animator's end does not work as
+        // expected. (e.g. not release children instantly). It is safer to use mLayout's child
+        // count.
+        if (mLayout != null) {
+            mLayout.removeAndRecycleAllViews(mRecycler);
+            mLayout.removeAndRecycleScrapInt(mRecycler);
+        }
+        // we should clear it here before adapters are swapped to ensure correct callbacks.
+        mRecycler.clear();
+    }
+
+    /**
+     * Replaces the current adapter with the new one and triggers listeners.
+     * @param adapter The new adapter
+     * @param compatibleWithPrevious If true, the new adapter is using the same View Holders and
+     *                               item types with the current adapter (helps us avoid cache
+     *                               invalidation).
+     * @param removeAndRecycleViews  If true, we'll remove and recycle all existing views. If
+     *                               compatibleWithPrevious is false, this parameter is ignored.
+     */
+    private void setAdapterInternal(Adapter adapter, boolean compatibleWithPrevious,
+            boolean removeAndRecycleViews) {
+        if (mAdapter != null) {
+            mAdapter.unregisterAdapterDataObserver(mObserver);
+            mAdapter.onDetachedFromRecyclerView(this);
+        }
+        if (!compatibleWithPrevious || removeAndRecycleViews) {
+            removeAndRecycleViews();
+        }
+        mAdapterHelper.reset();
+        final Adapter oldAdapter = mAdapter;
+        mAdapter = adapter;
+        if (adapter != null) {
+            adapter.registerAdapterDataObserver(mObserver);
+            adapter.onAttachedToRecyclerView(this);
+        }
+        if (mLayout != null) {
+            mLayout.onAdapterChanged(oldAdapter, mAdapter);
+        }
+        mRecycler.onAdapterChanged(oldAdapter, mAdapter, compatibleWithPrevious);
+        mState.mStructureChanged = true;
+        markKnownViewsInvalid();
+    }
+
+    /**
+     * Retrieves the previously set adapter or null if no adapter is set.
+     *
+     * @return The previously set adapter
+     * @see #setAdapter(Adapter)
+     */
+    public Adapter getAdapter() {
+        return mAdapter;
+    }
+
+    /**
+     * Register a listener that will be notified whenever a child view is recycled.
+     *
+     * <p>This listener will be called when a LayoutManager or the RecyclerView decides
+     * that a child view is no longer needed. If an application associates expensive
+     * or heavyweight data with item views, this may be a good place to release
+     * or free those resources.</p>
+     *
+     * @param listener Listener to register, or null to clear
+     */
+    public void setRecyclerListener(RecyclerListener listener) {
+        mRecyclerListener = listener;
+    }
+
+    /**
+     * <p>Return the offset of the RecyclerView's text baseline from the its top
+     * boundary. If the LayoutManager of this RecyclerView does not support baseline alignment,
+     * this method returns -1.</p>
+     *
+     * @return the offset of the baseline within the RecyclerView's bounds or -1
+     *         if baseline alignment is not supported
+     */
+    @Override
+    public int getBaseline() {
+        if (mLayout != null) {
+            return mLayout.getBaseline();
+        } else {
+            return super.getBaseline();
+        }
+    }
+
+    /**
+     * Register a listener that will be notified whenever a child view is attached to or detached
+     * from RecyclerView.
+     *
+     * <p>This listener will be called when a LayoutManager or the RecyclerView decides
+     * that a child view is no longer needed. If an application associates expensive
+     * or heavyweight data with item views, this may be a good place to release
+     * or free those resources.</p>
+     *
+     * @param listener Listener to register
+     */
+    public void addOnChildAttachStateChangeListener(OnChildAttachStateChangeListener listener) {
+        if (mOnChildAttachStateListeners == null) {
+            mOnChildAttachStateListeners = new ArrayList<>();
+        }
+        mOnChildAttachStateListeners.add(listener);
+    }
+
+    /**
+     * Removes the provided listener from child attached state listeners list.
+     *
+     * @param listener Listener to unregister
+     */
+    public void removeOnChildAttachStateChangeListener(OnChildAttachStateChangeListener listener) {
+        if (mOnChildAttachStateListeners == null) {
+            return;
+        }
+        mOnChildAttachStateListeners.remove(listener);
+    }
+
+    /**
+     * Removes all listeners that were added via
+     * {@link #addOnChildAttachStateChangeListener(OnChildAttachStateChangeListener)}.
+     */
+    public void clearOnChildAttachStateChangeListeners() {
+        if (mOnChildAttachStateListeners != null) {
+            mOnChildAttachStateListeners.clear();
+        }
+    }
+
+    /**
+     * Set the {@link LayoutManager} that this RecyclerView will use.
+     *
+     * <p>In contrast to other adapter-backed views such as {@link android.widget.ListView}
+     * or {@link android.widget.GridView}, RecyclerView allows client code to provide custom
+     * layout arrangements for child views. These arrangements are controlled by the
+     * {@link LayoutManager}. A LayoutManager must be provided for RecyclerView to function.</p>
+     *
+     * <p>Several default strategies are provided for common uses such as lists and grids.</p>
+     *
+     * @param layout LayoutManager to use
+     */
+    public void setLayoutManager(LayoutManager layout) {
+        if (layout == mLayout) {
+            return;
+        }
+        stopScroll();
+        // TODO We should do this switch a dispatchLayout pass and animate children. There is a good
+        // chance that LayoutManagers will re-use views.
+        if (mLayout != null) {
+            // end all running animations
+            if (mItemAnimator != null) {
+                mItemAnimator.endAnimations();
+            }
+            mLayout.removeAndRecycleAllViews(mRecycler);
+            mLayout.removeAndRecycleScrapInt(mRecycler);
+            mRecycler.clear();
+
+            if (mIsAttached) {
+                mLayout.dispatchDetachedFromWindow(this, mRecycler);
+            }
+            mLayout.setRecyclerView(null);
+            mLayout = null;
+        } else {
+            mRecycler.clear();
+        }
+        // this is just a defensive measure for faulty item animators.
+        mChildHelper.removeAllViewsUnfiltered();
+        mLayout = layout;
+        if (layout != null) {
+            if (layout.mRecyclerView != null) {
+                throw new IllegalArgumentException("LayoutManager " + layout
+                        + " is already attached to a RecyclerView: " + layout.mRecyclerView);
+            }
+            mLayout.setRecyclerView(this);
+            if (mIsAttached) {
+                mLayout.dispatchAttachedToWindow(this);
+            }
+        }
+        mRecycler.updateViewCacheSize();
+        requestLayout();
+    }
+
+    /**
+     * Set a {@link OnFlingListener} for this {@link RecyclerView}.
+     * <p>
+     * If the {@link OnFlingListener} is set then it will receive
+     * calls to {@link #fling(int,int)} and will be able to intercept them.
+     *
+     * @param onFlingListener The {@link OnFlingListener} instance.
+     */
+    public void setOnFlingListener(@Nullable OnFlingListener onFlingListener) {
+        mOnFlingListener = onFlingListener;
+    }
+
+    /**
+     * Get the current {@link OnFlingListener} from this {@link RecyclerView}.
+     *
+     * @return The {@link OnFlingListener} instance currently set (can be null).
+     */
+    @Nullable
+    public OnFlingListener getOnFlingListener() {
+        return mOnFlingListener;
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        SavedState state = new SavedState(super.onSaveInstanceState());
+        if (mPendingSavedState != null) {
+            state.copyFrom(mPendingSavedState);
+        } else if (mLayout != null) {
+            state.mLayoutState = mLayout.onSaveInstanceState();
+        } else {
+            state.mLayoutState = null;
+        }
+
+        return state;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (!(state instanceof SavedState)) {
+            super.onRestoreInstanceState(state);
+            return;
+        }
+
+        mPendingSavedState = (SavedState) state;
+        super.onRestoreInstanceState(mPendingSavedState.getSuperState());
+        if (mLayout != null && mPendingSavedState.mLayoutState != null) {
+            mLayout.onRestoreInstanceState(mPendingSavedState.mLayoutState);
+        }
+    }
+
+    /**
+     * Override to prevent freezing of any views created by the adapter.
+     */
+    @Override
+    protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
+        dispatchFreezeSelfOnly(container);
+    }
+
+    /**
+     * Override to prevent thawing of any views created by the adapter.
+     */
+    @Override
+    protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
+        dispatchThawSelfOnly(container);
+    }
+
+    /**
+     * Adds a view to the animatingViews list.
+     * mAnimatingViews holds the child views that are currently being kept around
+     * purely for the purpose of being animated out of view. They are drawn as a regular
+     * part of the child list of the RecyclerView, but they are invisible to the LayoutManager
+     * as they are managed separately from the regular child views.
+     * @param viewHolder The ViewHolder to be removed
+     */
+    private void addAnimatingView(ViewHolder viewHolder) {
+        final View view = viewHolder.itemView;
+        final boolean alreadyParented = view.getParent() == this;
+        mRecycler.unscrapView(getChildViewHolder(view));
+        if (viewHolder.isTmpDetached()) {
+            // re-attach
+            mChildHelper.attachViewToParent(view, -1, view.getLayoutParams(), true);
+        } else if (!alreadyParented) {
+            mChildHelper.addView(view, true);
+        } else {
+            mChildHelper.hide(view);
+        }
+    }
+
+    /**
+     * Removes a view from the animatingViews list.
+     * @param view The view to be removed
+     * @see #addAnimatingView(RecyclerView.ViewHolder)
+     * @return true if an animating view is removed
+     */
+    boolean removeAnimatingView(View view) {
+        eatRequestLayout();
+        final boolean removed = mChildHelper.removeViewIfHidden(view);
+        if (removed) {
+            final ViewHolder viewHolder = getChildViewHolderInt(view);
+            mRecycler.unscrapView(viewHolder);
+            mRecycler.recycleViewHolderInternal(viewHolder);
+            if (DEBUG) {
+                Log.d(TAG, "after removing animated view: " + view + ", " + this);
+            }
+        }
+        // only clear request eaten flag if we removed the view.
+        resumeRequestLayout(!removed);
+        return removed;
+    }
+
+    /**
+     * Return the {@link LayoutManager} currently responsible for
+     * layout policy for this RecyclerView.
+     *
+     * @return The currently bound LayoutManager
+     */
+    public LayoutManager getLayoutManager() {
+        return mLayout;
+    }
+
+    /**
+     * Retrieve this RecyclerView's {@link RecycledViewPool}. This method will never return null;
+     * if no pool is set for this view a new one will be created. See
+     * {@link #setRecycledViewPool(RecycledViewPool) setRecycledViewPool} for more information.
+     *
+     * @return The pool used to store recycled item views for reuse.
+     * @see #setRecycledViewPool(RecycledViewPool)
+     */
+    public RecycledViewPool getRecycledViewPool() {
+        return mRecycler.getRecycledViewPool();
+    }
+
+    /**
+     * Recycled view pools allow multiple RecyclerViews to share a common pool of scrap views.
+     * This can be useful if you have multiple RecyclerViews with adapters that use the same
+     * view types, for example if you have several data sets with the same kinds of item views
+     * displayed by a {@link android.support.v4.view.ViewPager ViewPager}.
+     *
+     * @param pool Pool to set. If this parameter is null a new pool will be created and used.
+     */
+    public void setRecycledViewPool(RecycledViewPool pool) {
+        mRecycler.setRecycledViewPool(pool);
+    }
+
+    /**
+     * Sets a new {@link ViewCacheExtension} to be used by the Recycler.
+     *
+     * @param extension ViewCacheExtension to be used or null if you want to clear the existing one.
+     *
+     * @see {@link ViewCacheExtension#getViewForPositionAndType(Recycler, int, int)}
+     */
+    public void setViewCacheExtension(ViewCacheExtension extension) {
+        mRecycler.setViewCacheExtension(extension);
+    }
+
+    /**
+     * Set the number of offscreen views to retain before adding them to the potentially shared
+     * {@link #getRecycledViewPool() recycled view pool}.
+     *
+     * <p>The offscreen view cache stays aware of changes in the attached adapter, allowing
+     * a LayoutManager to reuse those views unmodified without needing to return to the adapter
+     * to rebind them.</p>
+     *
+     * @param size Number of views to cache offscreen before returning them to the general
+     *             recycled view pool
+     */
+    public void setItemViewCacheSize(int size) {
+        mRecycler.setViewCacheSize(size);
+    }
+
+    /**
+     * Return the current scrolling state of the RecyclerView.
+     *
+     * @return {@link #SCROLL_STATE_IDLE}, {@link #SCROLL_STATE_DRAGGING} or
+     * {@link #SCROLL_STATE_SETTLING}
+     */
+    public int getScrollState() {
+        return mScrollState;
+    }
+
+    void setScrollState(int state) {
+        if (state == mScrollState) {
+            return;
+        }
+        if (DEBUG) {
+            Log.d(TAG, "setting scroll state to " + state + " from " + mScrollState,
+                    new Exception());
+        }
+        mScrollState = state;
+        if (state != SCROLL_STATE_SETTLING) {
+            stopScrollersInternal();
+        }
+        dispatchOnScrollStateChanged(state);
+    }
+
+    /**
+     * Add an {@link ItemDecoration} to this RecyclerView. Item decorations can
+     * affect both measurement and drawing of individual item views.
+     *
+     * <p>Item decorations are ordered. Decorations placed earlier in the list will
+     * be run/queried/drawn first for their effects on item views. Padding added to views
+     * will be nested; a padding added by an earlier decoration will mean further
+     * item decorations in the list will be asked to draw/pad within the previous decoration's
+     * given area.</p>
+     *
+     * @param decor Decoration to add
+     * @param index Position in the decoration chain to insert this decoration at. If this value
+     *              is negative the decoration will be added at the end.
+     */
+    public void addItemDecoration(ItemDecoration decor, int index) {
+        if (mLayout != null) {
+            mLayout.assertNotInLayoutOrScroll("Cannot add item decoration during a scroll  or"
+                    + " layout");
+        }
+        if (mItemDecorations.isEmpty()) {
+            setWillNotDraw(false);
+        }
+        if (index < 0) {
+            mItemDecorations.add(decor);
+        } else {
+            mItemDecorations.add(index, decor);
+        }
+        markItemDecorInsetsDirty();
+        requestLayout();
+    }
+
+    /**
+     * Add an {@link ItemDecoration} to this RecyclerView. Item decorations can
+     * affect both measurement and drawing of individual item views.
+     *
+     * <p>Item decorations are ordered. Decorations placed earlier in the list will
+     * be run/queried/drawn first for their effects on item views. Padding added to views
+     * will be nested; a padding added by an earlier decoration will mean further
+     * item decorations in the list will be asked to draw/pad within the previous decoration's
+     * given area.</p>
+     *
+     * @param decor Decoration to add
+     */
+    public void addItemDecoration(ItemDecoration decor) {
+        addItemDecoration(decor, -1);
+    }
+
+    /**
+     * Remove an {@link ItemDecoration} from this RecyclerView.
+     *
+     * <p>The given decoration will no longer impact the measurement and drawing of
+     * item views.</p>
+     *
+     * @param decor Decoration to remove
+     * @see #addItemDecoration(ItemDecoration)
+     */
+    public void removeItemDecoration(ItemDecoration decor) {
+        if (mLayout != null) {
+            mLayout.assertNotInLayoutOrScroll("Cannot remove item decoration during a scroll  or"
+                    + " layout");
+        }
+        mItemDecorations.remove(decor);
+        if (mItemDecorations.isEmpty()) {
+            setWillNotDraw(getOverScrollMode() == View.OVER_SCROLL_NEVER);
+        }
+        markItemDecorInsetsDirty();
+        requestLayout();
+    }
+
+    /**
+     * Sets the {@link ChildDrawingOrderCallback} to be used for drawing children.
+     * <p>
+     * See {@link ViewGroup#getChildDrawingOrder(int, int)} for details. Calling this method will
+     * always call {@link ViewGroup#setChildrenDrawingOrderEnabled(boolean)}. The parameter will be
+     * true if childDrawingOrderCallback is not null, false otherwise.
+     * <p>
+     * Note that child drawing order may be overridden by View's elevation.
+     *
+     * @param childDrawingOrderCallback The ChildDrawingOrderCallback to be used by the drawing
+     *                                  system.
+     */
+    public void setChildDrawingOrderCallback(ChildDrawingOrderCallback childDrawingOrderCallback) {
+        if (childDrawingOrderCallback == mChildDrawingOrderCallback) {
+            return;
+        }
+        mChildDrawingOrderCallback = childDrawingOrderCallback;
+        setChildrenDrawingOrderEnabled(mChildDrawingOrderCallback != null);
+    }
+
+    /**
+     * Set a listener that will be notified of any changes in scroll state or position.
+     *
+     * @param listener Listener to set or null to clear
+     *
+     * @deprecated Use {@link #addOnScrollListener(OnScrollListener)} and
+     *             {@link #removeOnScrollListener(OnScrollListener)}
+     */
+    @Deprecated
+    public void setOnScrollListener(OnScrollListener listener) {
+        mScrollListener = listener;
+    }
+
+    /**
+     * Add a listener that will be notified of any changes in scroll state or position.
+     *
+     * <p>Components that add a listener should take care to remove it when finished.
+     * Other components that take ownership of a view may call {@link #clearOnScrollListeners()}
+     * to remove all attached listeners.</p>
+     *
+     * @param listener listener to set or null to clear
+     */
+    public void addOnScrollListener(OnScrollListener listener) {
+        if (mScrollListeners == null) {
+            mScrollListeners = new ArrayList<>();
+        }
+        mScrollListeners.add(listener);
+    }
+
+    /**
+     * Remove a listener that was notified of any changes in scroll state or position.
+     *
+     * @param listener listener to set or null to clear
+     */
+    public void removeOnScrollListener(OnScrollListener listener) {
+        if (mScrollListeners != null) {
+            mScrollListeners.remove(listener);
+        }
+    }
+
+    /**
+     * Remove all secondary listener that were notified of any changes in scroll state or position.
+     */
+    public void clearOnScrollListeners() {
+        if (mScrollListeners != null) {
+            mScrollListeners.clear();
+        }
+    }
+
+    /**
+     * Convenience method to scroll to a certain position.
+     *
+     * RecyclerView does not implement scrolling logic, rather forwards the call to
+     * {@link com.android.internal.widget.RecyclerView.LayoutManager#scrollToPosition(int)}
+     * @param position Scroll to this adapter position
+     * @see com.android.internal.widget.RecyclerView.LayoutManager#scrollToPosition(int)
+     */
+    public void scrollToPosition(int position) {
+        if (mLayoutFrozen) {
+            return;
+        }
+        stopScroll();
+        if (mLayout == null) {
+            Log.e(TAG, "Cannot scroll to position a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
+            return;
+        }
+        mLayout.scrollToPosition(position);
+        awakenScrollBars();
+    }
+
+    void jumpToPositionForSmoothScroller(int position) {
+        if (mLayout == null) {
+            return;
+        }
+        mLayout.scrollToPosition(position);
+        awakenScrollBars();
+    }
+
+    /**
+     * Starts a smooth scroll to an adapter position.
+     * <p>
+     * To support smooth scrolling, you must override
+     * {@link LayoutManager#smoothScrollToPosition(RecyclerView, State, int)} and create a
+     * {@link SmoothScroller}.
+     * <p>
+     * {@link LayoutManager} is responsible for creating the actual scroll action. If you want to
+     * provide a custom smooth scroll logic, override
+     * {@link LayoutManager#smoothScrollToPosition(RecyclerView, State, int)} in your
+     * LayoutManager.
+     *
+     * @param position The adapter position to scroll to
+     * @see LayoutManager#smoothScrollToPosition(RecyclerView, State, int)
+     */
+    public void smoothScrollToPosition(int position) {
+        if (mLayoutFrozen) {
+            return;
+        }
+        if (mLayout == null) {
+            Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
+            return;
+        }
+        mLayout.smoothScrollToPosition(this, mState, position);
+    }
+
+    @Override
+    public void scrollTo(int x, int y) {
+        Log.w(TAG, "RecyclerView does not support scrolling to an absolute position. "
+                + "Use scrollToPosition instead");
+    }
+
+    @Override
+    public void scrollBy(int x, int y) {
+        if (mLayout == null) {
+            Log.e(TAG, "Cannot scroll without a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
+            return;
+        }
+        if (mLayoutFrozen) {
+            return;
+        }
+        final boolean canScrollHorizontal = mLayout.canScrollHorizontally();
+        final boolean canScrollVertical = mLayout.canScrollVertically();
+        if (canScrollHorizontal || canScrollVertical) {
+            scrollByInternal(canScrollHorizontal ? x : 0, canScrollVertical ? y : 0, null);
+        }
+    }
+
+    /**
+     * Helper method reflect data changes to the state.
+     * <p>
+     * Adapter changes during a scroll may trigger a crash because scroll assumes no data change
+     * but data actually changed.
+     * <p>
+     * This method consumes all deferred changes to avoid that case.
+     */
+    void consumePendingUpdateOperations() {
+        if (!mFirstLayoutComplete || mDataSetHasChangedAfterLayout) {
+            Trace.beginSection(TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG);
+            dispatchLayout();
+            Trace.endSection();
+            return;
+        }
+        if (!mAdapterHelper.hasPendingUpdates()) {
+            return;
+        }
+
+        // if it is only an item change (no add-remove-notifyDataSetChanged) we can check if any
+        // of the visible items is affected and if not, just ignore the change.
+        if (mAdapterHelper.hasAnyUpdateTypes(AdapterHelper.UpdateOp.UPDATE) && !mAdapterHelper
+                .hasAnyUpdateTypes(AdapterHelper.UpdateOp.ADD | AdapterHelper.UpdateOp.REMOVE
+                        | AdapterHelper.UpdateOp.MOVE)) {
+            Trace.beginSection(TRACE_HANDLE_ADAPTER_UPDATES_TAG);
+            eatRequestLayout();
+            onEnterLayoutOrScroll();
+            mAdapterHelper.preProcess();
+            if (!mLayoutRequestEaten) {
+                if (hasUpdatedView()) {
+                    dispatchLayout();
+                } else {
+                    // no need to layout, clean state
+                    mAdapterHelper.consumePostponedUpdates();
+                }
+            }
+            resumeRequestLayout(true);
+            onExitLayoutOrScroll();
+            Trace.endSection();
+        } else if (mAdapterHelper.hasPendingUpdates()) {
+            Trace.beginSection(TRACE_ON_DATA_SET_CHANGE_LAYOUT_TAG);
+            dispatchLayout();
+            Trace.endSection();
+        }
+    }
+
+    /**
+     * @return True if an existing view holder needs to be updated
+     */
+    private boolean hasUpdatedView() {
+        final int childCount = mChildHelper.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i));
+            if (holder == null || holder.shouldIgnore()) {
+                continue;
+            }
+            if (holder.isUpdated()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Does not perform bounds checking. Used by internal methods that have already validated input.
+     * <p>
+     * It also reports any unused scroll request to the related EdgeEffect.
+     *
+     * @param x The amount of horizontal scroll request
+     * @param y The amount of vertical scroll request
+     * @param ev The originating MotionEvent, or null if not from a touch event.
+     *
+     * @return Whether any scroll was consumed in either direction.
+     */
+    boolean scrollByInternal(int x, int y, MotionEvent ev) {
+        int unconsumedX = 0, unconsumedY = 0;
+        int consumedX = 0, consumedY = 0;
+
+        consumePendingUpdateOperations();
+        if (mAdapter != null) {
+            eatRequestLayout();
+            onEnterLayoutOrScroll();
+            Trace.beginSection(TRACE_SCROLL_TAG);
+            if (x != 0) {
+                consumedX = mLayout.scrollHorizontallyBy(x, mRecycler, mState);
+                unconsumedX = x - consumedX;
+            }
+            if (y != 0) {
+                consumedY = mLayout.scrollVerticallyBy(y, mRecycler, mState);
+                unconsumedY = y - consumedY;
+            }
+            Trace.endSection();
+            repositionShadowingViews();
+            onExitLayoutOrScroll();
+            resumeRequestLayout(false);
+        }
+        if (!mItemDecorations.isEmpty()) {
+            invalidate();
+        }
+
+        if (dispatchNestedScroll(consumedX, consumedY, unconsumedX, unconsumedY, mScrollOffset)) {
+            // Update the last touch co-ords, taking any scroll offset into account
+            mLastTouchX -= mScrollOffset[0];
+            mLastTouchY -= mScrollOffset[1];
+            if (ev != null) {
+                ev.offsetLocation(mScrollOffset[0], mScrollOffset[1]);
+            }
+            mNestedOffsets[0] += mScrollOffset[0];
+            mNestedOffsets[1] += mScrollOffset[1];
+        } else if (getOverScrollMode() != View.OVER_SCROLL_NEVER) {
+            if (ev != null) {
+                pullGlows(ev.getX(), unconsumedX, ev.getY(), unconsumedY);
+            }
+            considerReleasingGlowsOnScroll(x, y);
+        }
+        if (consumedX != 0 || consumedY != 0) {
+            dispatchOnScrolled(consumedX, consumedY);
+        }
+        if (!awakenScrollBars()) {
+            invalidate();
+        }
+        return consumedX != 0 || consumedY != 0;
+    }
+
+    /**
+     * <p>Compute the horizontal offset of the horizontal scrollbar's thumb within the horizontal
+     * range. This value is used to compute the length of the thumb within the scrollbar's track.
+     * </p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the units used by
+     * {@link #computeHorizontalScrollRange()} and {@link #computeHorizontalScrollExtent()}.</p>
+     *
+     * <p>Default implementation returns 0.</p>
+     *
+     * <p>If you want to support scroll bars, override
+     * {@link RecyclerView.LayoutManager#computeHorizontalScrollOffset(RecyclerView.State)} in your
+     * LayoutManager. </p>
+     *
+     * @return The horizontal offset of the scrollbar's thumb
+     * @see com.android.internal.widget.RecyclerView.LayoutManager#computeHorizontalScrollOffset
+     * (RecyclerView.State)
+     */
+    @Override
+    public int computeHorizontalScrollOffset() {
+        if (mLayout == null) {
+            return 0;
+        }
+        return mLayout.canScrollHorizontally() ? mLayout.computeHorizontalScrollOffset(mState) : 0;
+    }
+
+    /**
+     * <p>Compute the horizontal extent of the horizontal scrollbar's thumb within the
+     * horizontal range. This value is used to compute the length of the thumb within the
+     * scrollbar's track.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the units used by
+     * {@link #computeHorizontalScrollRange()} and {@link #computeHorizontalScrollOffset()}.</p>
+     *
+     * <p>Default implementation returns 0.</p>
+     *
+     * <p>If you want to support scroll bars, override
+     * {@link RecyclerView.LayoutManager#computeHorizontalScrollExtent(RecyclerView.State)} in your
+     * LayoutManager.</p>
+     *
+     * @return The horizontal extent of the scrollbar's thumb
+     * @see RecyclerView.LayoutManager#computeHorizontalScrollExtent(RecyclerView.State)
+     */
+    @Override
+    public int computeHorizontalScrollExtent() {
+        if (mLayout == null) {
+            return 0;
+        }
+        return mLayout.canScrollHorizontally() ? mLayout.computeHorizontalScrollExtent(mState) : 0;
+    }
+
+    /**
+     * <p>Compute the horizontal range that the horizontal scrollbar represents.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the units used by
+     * {@link #computeHorizontalScrollExtent()} and {@link #computeHorizontalScrollOffset()}.</p>
+     *
+     * <p>Default implementation returns 0.</p>
+     *
+     * <p>If you want to support scroll bars, override
+     * {@link RecyclerView.LayoutManager#computeHorizontalScrollRange(RecyclerView.State)} in your
+     * LayoutManager.</p>
+     *
+     * @return The total horizontal range represented by the vertical scrollbar
+     * @see RecyclerView.LayoutManager#computeHorizontalScrollRange(RecyclerView.State)
+     */
+    @Override
+    public int computeHorizontalScrollRange() {
+        if (mLayout == null) {
+            return 0;
+        }
+        return mLayout.canScrollHorizontally() ? mLayout.computeHorizontalScrollRange(mState) : 0;
+    }
+
+    /**
+     * <p>Compute the vertical offset of the vertical scrollbar's thumb within the vertical range.
+     * This value is used to compute the length of the thumb within the scrollbar's track. </p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the units used by
+     * {@link #computeVerticalScrollRange()} and {@link #computeVerticalScrollExtent()}.</p>
+     *
+     * <p>Default implementation returns 0.</p>
+     *
+     * <p>If you want to support scroll bars, override
+     * {@link RecyclerView.LayoutManager#computeVerticalScrollOffset(RecyclerView.State)} in your
+     * LayoutManager.</p>
+     *
+     * @return The vertical offset of the scrollbar's thumb
+     * @see com.android.internal.widget.RecyclerView.LayoutManager#computeVerticalScrollOffset
+     * (RecyclerView.State)
+     */
+    @Override
+    public int computeVerticalScrollOffset() {
+        if (mLayout == null) {
+            return 0;
+        }
+        return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollOffset(mState) : 0;
+    }
+
+    /**
+     * <p>Compute the vertical extent of the vertical scrollbar's thumb within the vertical range.
+     * This value is used to compute the length of the thumb within the scrollbar's track.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the units used by
+     * {@link #computeVerticalScrollRange()} and {@link #computeVerticalScrollOffset()}.</p>
+     *
+     * <p>Default implementation returns 0.</p>
+     *
+     * <p>If you want to support scroll bars, override
+     * {@link RecyclerView.LayoutManager#computeVerticalScrollExtent(RecyclerView.State)} in your
+     * LayoutManager.</p>
+     *
+     * @return The vertical extent of the scrollbar's thumb
+     * @see RecyclerView.LayoutManager#computeVerticalScrollExtent(RecyclerView.State)
+     */
+    @Override
+    public int computeVerticalScrollExtent() {
+        if (mLayout == null) {
+            return 0;
+        }
+        return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollExtent(mState) : 0;
+    }
+
+    /**
+     * <p>Compute the vertical range that the vertical scrollbar represents.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the units used by
+     * {@link #computeVerticalScrollExtent()} and {@link #computeVerticalScrollOffset()}.</p>
+     *
+     * <p>Default implementation returns 0.</p>
+     *
+     * <p>If you want to support scroll bars, override
+     * {@link RecyclerView.LayoutManager#computeVerticalScrollRange(RecyclerView.State)} in your
+     * LayoutManager.</p>
+     *
+     * @return The total vertical range represented by the vertical scrollbar
+     * @see RecyclerView.LayoutManager#computeVerticalScrollRange(RecyclerView.State)
+     */
+    @Override
+    public int computeVerticalScrollRange() {
+        if (mLayout == null) {
+            return 0;
+        }
+        return mLayout.canScrollVertically() ? mLayout.computeVerticalScrollRange(mState) : 0;
+    }
+
+
+    void eatRequestLayout() {
+        mEatRequestLayout++;
+        if (mEatRequestLayout == 1 && !mLayoutFrozen) {
+            mLayoutRequestEaten = false;
+        }
+    }
+
+    void resumeRequestLayout(boolean performLayoutChildren) {
+        if (mEatRequestLayout < 1) {
+            //noinspection PointlessBooleanExpression
+            if (DEBUG) {
+                throw new IllegalStateException("invalid eat request layout count");
+            }
+            mEatRequestLayout = 1;
+        }
+        if (!performLayoutChildren) {
+            // Reset the layout request eaten counter.
+            // This is necessary since eatRequest calls can be nested in which case the other
+            // call will override the inner one.
+            // for instance:
+            // eat layout for process adapter updates
+            //   eat layout for dispatchLayout
+            //     a bunch of req layout calls arrive
+
+            mLayoutRequestEaten = false;
+        }
+        if (mEatRequestLayout == 1) {
+            // when layout is frozen we should delay dispatchLayout()
+            if (performLayoutChildren && mLayoutRequestEaten && !mLayoutFrozen
+                    && mLayout != null && mAdapter != null) {
+                dispatchLayout();
+            }
+            if (!mLayoutFrozen) {
+                mLayoutRequestEaten = false;
+            }
+        }
+        mEatRequestLayout--;
+    }
+
+    /**
+     * Enable or disable layout and scroll.  After <code>setLayoutFrozen(true)</code> is called,
+     * Layout requests will be postponed until <code>setLayoutFrozen(false)</code> is called;
+     * child views are not updated when RecyclerView is frozen, {@link #smoothScrollBy(int, int)},
+     * {@link #scrollBy(int, int)}, {@link #scrollToPosition(int)} and
+     * {@link #smoothScrollToPosition(int)} are dropped; TouchEvents and GenericMotionEvents are
+     * dropped; {@link LayoutManager#onFocusSearchFailed(View, int, Recycler, State)} will not be
+     * called.
+     *
+     * <p>
+     * <code>setLayoutFrozen(true)</code> does not prevent app from directly calling {@link
+     * LayoutManager#scrollToPosition(int)}, {@link LayoutManager#smoothScrollToPosition(
+     * RecyclerView, State, int)}.
+     * <p>
+     * {@link #setAdapter(Adapter)} and {@link #swapAdapter(Adapter, boolean)} will automatically
+     * stop frozen.
+     * <p>
+     * Note: Running ItemAnimator is not stopped automatically,  it's caller's
+     * responsibility to call ItemAnimator.end().
+     *
+     * @param frozen   true to freeze layout and scroll, false to re-enable.
+     */
+    public void setLayoutFrozen(boolean frozen) {
+        if (frozen != mLayoutFrozen) {
+            assertNotInLayoutOrScroll("Do not setLayoutFrozen in layout or scroll");
+            if (!frozen) {
+                mLayoutFrozen = false;
+                if (mLayoutRequestEaten && mLayout != null && mAdapter != null) {
+                    requestLayout();
+                }
+                mLayoutRequestEaten = false;
+            } else {
+                final long now = SystemClock.uptimeMillis();
+                MotionEvent cancelEvent = MotionEvent.obtain(now, now,
+                        MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
+                onTouchEvent(cancelEvent);
+                mLayoutFrozen = true;
+                mIgnoreMotionEventTillDown = true;
+                stopScroll();
+            }
+        }
+    }
+
+    /**
+     * Returns true if layout and scroll are frozen.
+     *
+     * @return true if layout and scroll are frozen
+     * @see #setLayoutFrozen(boolean)
+     */
+    public boolean isLayoutFrozen() {
+        return mLayoutFrozen;
+    }
+
+    /**
+     * Animate a scroll by the given amount of pixels along either axis.
+     *
+     * @param dx Pixels to scroll horizontally
+     * @param dy Pixels to scroll vertically
+     */
+    public void smoothScrollBy(int dx, int dy) {
+        smoothScrollBy(dx, dy, null);
+    }
+
+    /**
+     * Animate a scroll by the given amount of pixels along either axis.
+     *
+     * @param dx Pixels to scroll horizontally
+     * @param dy Pixels to scroll vertically
+     * @param interpolator {@link Interpolator} to be used for scrolling. If it is
+     *                     {@code null}, RecyclerView is going to use the default interpolator.
+     */
+    public void smoothScrollBy(int dx, int dy, Interpolator interpolator) {
+        if (mLayout == null) {
+            Log.e(TAG, "Cannot smooth scroll without a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
+            return;
+        }
+        if (mLayoutFrozen) {
+            return;
+        }
+        if (!mLayout.canScrollHorizontally()) {
+            dx = 0;
+        }
+        if (!mLayout.canScrollVertically()) {
+            dy = 0;
+        }
+        if (dx != 0 || dy != 0) {
+            mViewFlinger.smoothScrollBy(dx, dy, interpolator);
+        }
+    }
+
+    /**
+     * Begin a standard fling with an initial velocity along each axis in pixels per second.
+     * If the velocity given is below the system-defined minimum this method will return false
+     * and no fling will occur.
+     *
+     * @param velocityX Initial horizontal velocity in pixels per second
+     * @param velocityY Initial vertical velocity in pixels per second
+     * @return true if the fling was started, false if the velocity was too low to fling or
+     * LayoutManager does not support scrolling in the axis fling is issued.
+     *
+     * @see LayoutManager#canScrollVertically()
+     * @see LayoutManager#canScrollHorizontally()
+     */
+    public boolean fling(int velocityX, int velocityY) {
+        if (mLayout == null) {
+            Log.e(TAG, "Cannot fling without a LayoutManager set. "
+                    + "Call setLayoutManager with a non-null argument.");
+            return false;
+        }
+        if (mLayoutFrozen) {
+            return false;
+        }
+
+        final boolean canScrollHorizontal = mLayout.canScrollHorizontally();
+        final boolean canScrollVertical = mLayout.canScrollVertically();
+
+        if (!canScrollHorizontal || Math.abs(velocityX) < mMinFlingVelocity) {
+            velocityX = 0;
+        }
+        if (!canScrollVertical || Math.abs(velocityY) < mMinFlingVelocity) {
+            velocityY = 0;
+        }
+        if (velocityX == 0 && velocityY == 0) {
+            // If we don't have any velocity, return false
+            return false;
+        }
+
+        if (!dispatchNestedPreFling(velocityX, velocityY)) {
+            final boolean canScroll = canScrollHorizontal || canScrollVertical;
+            dispatchNestedFling(velocityX, velocityY, canScroll);
+
+            if (mOnFlingListener != null && mOnFlingListener.onFling(velocityX, velocityY)) {
+                return true;
+            }
+
+            if (canScroll) {
+                velocityX = Math.max(-mMaxFlingVelocity, Math.min(velocityX, mMaxFlingVelocity));
+                velocityY = Math.max(-mMaxFlingVelocity, Math.min(velocityY, mMaxFlingVelocity));
+                mViewFlinger.fling(velocityX, velocityY);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Stop any current scroll in progress, such as one started by
+     * {@link #smoothScrollBy(int, int)}, {@link #fling(int, int)} or a touch-initiated fling.
+     */
+    public void stopScroll() {
+        setScrollState(SCROLL_STATE_IDLE);
+        stopScrollersInternal();
+    }
+
+    /**
+     * Similar to {@link #stopScroll()} but does not set the state.
+     */
+    private void stopScrollersInternal() {
+        mViewFlinger.stop();
+        if (mLayout != null) {
+            mLayout.stopSmoothScroller();
+        }
+    }
+
+    /**
+     * Returns the minimum velocity to start a fling.
+     *
+     * @return The minimum velocity to start a fling
+     */
+    public int getMinFlingVelocity() {
+        return mMinFlingVelocity;
+    }
+
+
+    /**
+     * Returns the maximum fling velocity used by this RecyclerView.
+     *
+     * @return The maximum fling velocity used by this RecyclerView.
+     */
+    public int getMaxFlingVelocity() {
+        return mMaxFlingVelocity;
+    }
+
+    /**
+     * Apply a pull to relevant overscroll glow effects
+     */
+    private void pullGlows(float x, float overscrollX, float y, float overscrollY) {
+        boolean invalidate = false;
+        if (overscrollX < 0) {
+            ensureLeftGlow();
+            mLeftGlow.onPull(-overscrollX / getWidth(), 1f - y  / getHeight());
+            invalidate = true;
+        } else if (overscrollX > 0) {
+            ensureRightGlow();
+            mRightGlow.onPull(overscrollX / getWidth(), y / getHeight());
+            invalidate = true;
+        }
+
+        if (overscrollY < 0) {
+            ensureTopGlow();
+            mTopGlow.onPull(-overscrollY / getHeight(), x / getWidth());
+            invalidate = true;
+        } else if (overscrollY > 0) {
+            ensureBottomGlow();
+            mBottomGlow.onPull(overscrollY / getHeight(), 1f - x / getWidth());
+            invalidate = true;
+        }
+
+        if (invalidate || overscrollX != 0 || overscrollY != 0) {
+            postInvalidateOnAnimation();
+        }
+    }
+
+    private void releaseGlows() {
+        boolean needsInvalidate = false;
+        if (mLeftGlow != null) {
+            mLeftGlow.onRelease();
+            needsInvalidate = true;
+        }
+        if (mTopGlow != null) {
+            mTopGlow.onRelease();
+            needsInvalidate = true;
+        }
+        if (mRightGlow != null) {
+            mRightGlow.onRelease();
+            needsInvalidate = true;
+        }
+        if (mBottomGlow != null) {
+            mBottomGlow.onRelease();
+            needsInvalidate = true;
+        }
+        if (needsInvalidate) {
+            postInvalidateOnAnimation();
+        }
+    }
+
+    void considerReleasingGlowsOnScroll(int dx, int dy) {
+        boolean needsInvalidate = false;
+        if (mLeftGlow != null && !mLeftGlow.isFinished() && dx > 0) {
+            mLeftGlow.onRelease();
+            needsInvalidate = true;
+        }
+        if (mRightGlow != null && !mRightGlow.isFinished() && dx < 0) {
+            mRightGlow.onRelease();
+            needsInvalidate = true;
+        }
+        if (mTopGlow != null && !mTopGlow.isFinished() && dy > 0) {
+            mTopGlow.onRelease();
+            needsInvalidate = true;
+        }
+        if (mBottomGlow != null && !mBottomGlow.isFinished() && dy < 0) {
+            mBottomGlow.onRelease();
+            needsInvalidate = true;
+        }
+        if (needsInvalidate) {
+            postInvalidateOnAnimation();
+        }
+    }
+
+    void absorbGlows(int velocityX, int velocityY) {
+        if (velocityX < 0) {
+            ensureLeftGlow();
+            mLeftGlow.onAbsorb(-velocityX);
+        } else if (velocityX > 0) {
+            ensureRightGlow();
+            mRightGlow.onAbsorb(velocityX);
+        }
+
+        if (velocityY < 0) {
+            ensureTopGlow();
+            mTopGlow.onAbsorb(-velocityY);
+        } else if (velocityY > 0) {
+            ensureBottomGlow();
+            mBottomGlow.onAbsorb(velocityY);
+        }
+
+        if (velocityX != 0 || velocityY != 0) {
+            postInvalidateOnAnimation();
+        }
+    }
+
+    void ensureLeftGlow() {
+        if (mLeftGlow != null) {
+            return;
+        }
+        mLeftGlow = new EdgeEffect(getContext());
+        if (mClipToPadding) {
+            mLeftGlow.setSize(getMeasuredHeight() - getPaddingTop() - getPaddingBottom(),
+                    getMeasuredWidth() - getPaddingLeft() - getPaddingRight());
+        } else {
+            mLeftGlow.setSize(getMeasuredHeight(), getMeasuredWidth());
+        }
+    }
+
+    void ensureRightGlow() {
+        if (mRightGlow != null) {
+            return;
+        }
+        mRightGlow = new EdgeEffect(getContext());
+        if (mClipToPadding) {
+            mRightGlow.setSize(getMeasuredHeight() - getPaddingTop() - getPaddingBottom(),
+                    getMeasuredWidth() - getPaddingLeft() - getPaddingRight());
+        } else {
+            mRightGlow.setSize(getMeasuredHeight(), getMeasuredWidth());
+        }
+    }
+
+    void ensureTopGlow() {
+        if (mTopGlow != null) {
+            return;
+        }
+        mTopGlow = new EdgeEffect(getContext());
+        if (mClipToPadding) {
+            mTopGlow.setSize(getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
+                    getMeasuredHeight() - getPaddingTop() - getPaddingBottom());
+        } else {
+            mTopGlow.setSize(getMeasuredWidth(), getMeasuredHeight());
+        }
+
+    }
+
+    void ensureBottomGlow() {
+        if (mBottomGlow != null) {
+            return;
+        }
+        mBottomGlow = new EdgeEffect(getContext());
+        if (mClipToPadding) {
+            mBottomGlow.setSize(getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
+                    getMeasuredHeight() - getPaddingTop() - getPaddingBottom());
+        } else {
+            mBottomGlow.setSize(getMeasuredWidth(), getMeasuredHeight());
+        }
+    }
+
+    void invalidateGlows() {
+        mLeftGlow = mRightGlow = mTopGlow = mBottomGlow = null;
+    }
+
+    /**
+     * Since RecyclerView is a collection ViewGroup that includes virtual children (items that are
+     * in the Adapter but not visible in the UI), it employs a more involved focus search strategy
+     * that differs from other ViewGroups.
+     * <p>
+     * It first does a focus search within the RecyclerView. If this search finds a View that is in
+     * the focus direction with respect to the currently focused View, RecyclerView returns that
+     * child as the next focus target. When it cannot find such child, it calls
+     * {@link LayoutManager#onFocusSearchFailed(View, int, Recycler, State)} to layout more Views
+     * in the focus search direction. If LayoutManager adds a View that matches the
+     * focus search criteria, it will be returned as the focus search result. Otherwise,
+     * RecyclerView will call parent to handle the focus search like a regular ViewGroup.
+     * <p>
+     * When the direction is {@link View#FOCUS_FORWARD} or {@link View#FOCUS_BACKWARD}, a View that
+     * is not in the focus direction is still valid focus target which may not be the desired
+     * behavior if the Adapter has more children in the focus direction. To handle this case,
+     * RecyclerView converts the focus direction to an absolute direction and makes a preliminary
+     * focus search in that direction. If there are no Views to gain focus, it will call
+     * {@link LayoutManager#onFocusSearchFailed(View, int, Recycler, State)} before running a
+     * focus search with the original (relative) direction. This allows RecyclerView to provide
+     * better candidates to the focus search while still allowing the view system to take focus from
+     * the RecyclerView and give it to a more suitable child if such child exists.
+     *
+     * @param focused The view that currently has focus
+     * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
+     * {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT}, {@link View#FOCUS_FORWARD},
+     * {@link View#FOCUS_BACKWARD} or 0 for not applicable.
+     *
+     * @return A new View that can be the next focus after the focused View
+     */
+    @Override
+    public View focusSearch(View focused, int direction) {
+        View result = mLayout.onInterceptFocusSearch(focused, direction);
+        if (result != null) {
+            return result;
+        }
+        final boolean canRunFocusFailure = mAdapter != null && mLayout != null
+                && !isComputingLayout() && !mLayoutFrozen;
+
+        final FocusFinder ff = FocusFinder.getInstance();
+        if (canRunFocusFailure
+                && (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD)) {
+            // convert direction to absolute direction and see if we have a view there and if not
+            // tell LayoutManager to add if it can.
+            boolean needsFocusFailureLayout = false;
+            if (mLayout.canScrollVertically()) {
+                final int absDir =
+                        direction == View.FOCUS_FORWARD ? View.FOCUS_DOWN : View.FOCUS_UP;
+                final View found = ff.findNextFocus(this, focused, absDir);
+                needsFocusFailureLayout = found == null;
+                if (FORCE_ABS_FOCUS_SEARCH_DIRECTION) {
+                    // Workaround for broken FOCUS_BACKWARD in API 15 and older devices.
+                    direction = absDir;
+                }
+            }
+            if (!needsFocusFailureLayout && mLayout.canScrollHorizontally()) {
+                boolean rtl = mLayout.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+                final int absDir = (direction == View.FOCUS_FORWARD) ^ rtl
+                        ? View.FOCUS_RIGHT : View.FOCUS_LEFT;
+                final View found = ff.findNextFocus(this, focused, absDir);
+                needsFocusFailureLayout = found == null;
+                if (FORCE_ABS_FOCUS_SEARCH_DIRECTION) {
+                    // Workaround for broken FOCUS_BACKWARD in API 15 and older devices.
+                    direction = absDir;
+                }
+            }
+            if (needsFocusFailureLayout) {
+                consumePendingUpdateOperations();
+                final View focusedItemView = findContainingItemView(focused);
+                if (focusedItemView == null) {
+                    // panic, focused view is not a child anymore, cannot call super.
+                    return null;
+                }
+                eatRequestLayout();
+                mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
+                resumeRequestLayout(false);
+            }
+            result = ff.findNextFocus(this, focused, direction);
+        } else {
+            result = ff.findNextFocus(this, focused, direction);
+            if (result == null && canRunFocusFailure) {
+                consumePendingUpdateOperations();
+                final View focusedItemView = findContainingItemView(focused);
+                if (focusedItemView == null) {
+                    // panic, focused view is not a child anymore, cannot call super.
+                    return null;
+                }
+                eatRequestLayout();
+                result = mLayout.onFocusSearchFailed(focused, direction, mRecycler, mState);
+                resumeRequestLayout(false);
+            }
+        }
+        return isPreferredNextFocus(focused, result, direction)
+                ? result : super.focusSearch(focused, direction);
+    }
+
+    /**
+     * Checks if the new focus candidate is a good enough candidate such that RecyclerView will
+     * assign it as the next focus View instead of letting view hierarchy decide.
+     * A good candidate means a View that is aligned in the focus direction wrt the focused View
+     * and is not the RecyclerView itself.
+     * When this method returns false, RecyclerView will let the parent make the decision so the
+     * same View may still get the focus as a result of that search.
+     */
+    private boolean isPreferredNextFocus(View focused, View next, int direction) {
+        if (next == null || next == this) {
+            return false;
+        }
+        if (focused == null) {
+            return true;
+        }
+
+        if (direction == View.FOCUS_FORWARD || direction == View.FOCUS_BACKWARD) {
+            final boolean rtl = mLayout.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+            final int absHorizontal = (direction == View.FOCUS_FORWARD) ^ rtl
+                    ? View.FOCUS_RIGHT : View.FOCUS_LEFT;
+            if (isPreferredNextFocusAbsolute(focused, next, absHorizontal)) {
+                return true;
+            }
+            if (direction == View.FOCUS_FORWARD) {
+                return isPreferredNextFocusAbsolute(focused, next, View.FOCUS_DOWN);
+            } else {
+                return isPreferredNextFocusAbsolute(focused, next, View.FOCUS_UP);
+            }
+        } else {
+            return isPreferredNextFocusAbsolute(focused, next, direction);
+        }
+
+    }
+
+    /**
+     * Logic taken from FocusSearch#isCandidate
+     */
+    private boolean isPreferredNextFocusAbsolute(View focused, View next, int direction) {
+        mTempRect.set(0, 0, focused.getWidth(), focused.getHeight());
+        mTempRect2.set(0, 0, next.getWidth(), next.getHeight());
+        offsetDescendantRectToMyCoords(focused, mTempRect);
+        offsetDescendantRectToMyCoords(next, mTempRect2);
+        switch (direction) {
+            case View.FOCUS_LEFT:
+                return (mTempRect.right > mTempRect2.right
+                        || mTempRect.left >= mTempRect2.right)
+                        && mTempRect.left > mTempRect2.left;
+            case View.FOCUS_RIGHT:
+                return (mTempRect.left < mTempRect2.left
+                        || mTempRect.right <= mTempRect2.left)
+                        && mTempRect.right < mTempRect2.right;
+            case View.FOCUS_UP:
+                return (mTempRect.bottom > mTempRect2.bottom
+                        || mTempRect.top >= mTempRect2.bottom)
+                        && mTempRect.top > mTempRect2.top;
+            case View.FOCUS_DOWN:
+                return (mTempRect.top < mTempRect2.top
+                        || mTempRect.bottom <= mTempRect2.top)
+                        && mTempRect.bottom < mTempRect2.bottom;
+        }
+        throw new IllegalArgumentException("direction must be absolute. received:" + direction);
+    }
+
+    @Override
+    public void requestChildFocus(View child, View focused) {
+        if (!mLayout.onRequestChildFocus(this, mState, child, focused) && focused != null) {
+            mTempRect.set(0, 0, focused.getWidth(), focused.getHeight());
+
+            // get item decor offsets w/o refreshing. If they are invalid, there will be another
+            // layout pass to fix them, then it is LayoutManager's responsibility to keep focused
+            // View in viewport.
+            final ViewGroup.LayoutParams focusedLayoutParams = focused.getLayoutParams();
+            if (focusedLayoutParams instanceof LayoutParams) {
+                // if focused child has item decors, use them. Otherwise, ignore.
+                final LayoutParams lp = (LayoutParams) focusedLayoutParams;
+                if (!lp.mInsetsDirty) {
+                    final Rect insets = lp.mDecorInsets;
+                    mTempRect.left -= insets.left;
+                    mTempRect.right += insets.right;
+                    mTempRect.top -= insets.top;
+                    mTempRect.bottom += insets.bottom;
+                }
+            }
+
+            offsetDescendantRectToMyCoords(focused, mTempRect);
+            offsetRectIntoDescendantCoords(child, mTempRect);
+            requestChildRectangleOnScreen(child, mTempRect, !mFirstLayoutComplete);
+        }
+        super.requestChildFocus(child, focused);
+    }
+
+    @Override
+    public boolean requestChildRectangleOnScreen(View child, Rect rect, boolean immediate) {
+        return mLayout.requestChildRectangleOnScreen(this, child, rect, immediate);
+    }
+
+    @Override
+    public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+        if (mLayout == null || !mLayout.onAddFocusables(this, views, direction, focusableMode)) {
+            super.addFocusables(views, direction, focusableMode);
+        }
+    }
+
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
+        if (isComputingLayout()) {
+            // if we are in the middle of a layout calculation, don't let any child take focus.
+            // RV will handle it after layout calculation is finished.
+            return false;
+        }
+        return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mLayoutOrScrollCounter = 0;
+        mIsAttached = true;
+        mFirstLayoutComplete = mFirstLayoutComplete && !isLayoutRequested();
+        if (mLayout != null) {
+            mLayout.dispatchAttachedToWindow(this);
+        }
+        mPostedAnimatorRunner = false;
+
+        if (ALLOW_THREAD_GAP_WORK) {
+            // Register with gap worker
+            mGapWorker = GapWorker.sGapWorker.get();
+            if (mGapWorker == null) {
+                mGapWorker = new GapWorker();
+
+                // break 60 fps assumption if data from display appears valid
+                // NOTE: we only do this query once, statically, because it's very expensive (> 1ms)
+                Display display = getDisplay();
+                float refreshRate = 60.0f;
+                if (!isInEditMode() && display != null) {
+                    float displayRefreshRate = display.getRefreshRate();
+                    if (displayRefreshRate >= 30.0f) {
+                        refreshRate = displayRefreshRate;
+                    }
+                }
+                mGapWorker.mFrameIntervalNs = (long) (1000000000 / refreshRate);
+                GapWorker.sGapWorker.set(mGapWorker);
+            }
+            mGapWorker.add(this);
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (mItemAnimator != null) {
+            mItemAnimator.endAnimations();
+        }
+        stopScroll();
+        mIsAttached = false;
+        if (mLayout != null) {
+            mLayout.dispatchDetachedFromWindow(this, mRecycler);
+        }
+        mPendingAccessibilityImportanceChange.clear();
+        removeCallbacks(mItemAnimatorRunner);
+        mViewInfoStore.onDetach();
+
+        if (ALLOW_THREAD_GAP_WORK) {
+            // Unregister with gap worker
+            mGapWorker.remove(this);
+            mGapWorker = null;
+        }
+    }
+
+    /**
+     * Returns true if RecyclerView is attached to window.
+     */
+    // @override
+    public boolean isAttachedToWindow() {
+        return mIsAttached;
+    }
+
+    /**
+     * Checks if RecyclerView is in the middle of a layout or scroll and throws an
+     * {@link IllegalStateException} if it <b>is not</b>.
+     *
+     * @param message The message for the exception. Can be null.
+     * @see #assertNotInLayoutOrScroll(String)
+     */
+    void assertInLayoutOrScroll(String message) {
+        if (!isComputingLayout()) {
+            if (message == null) {
+                throw new IllegalStateException("Cannot call this method unless RecyclerView is "
+                        + "computing a layout or scrolling");
+            }
+            throw new IllegalStateException(message);
+
+        }
+    }
+
+    /**
+     * Checks if RecyclerView is in the middle of a layout or scroll and throws an
+     * {@link IllegalStateException} if it <b>is</b>.
+     *
+     * @param message The message for the exception. Can be null.
+     * @see #assertInLayoutOrScroll(String)
+     */
+    void assertNotInLayoutOrScroll(String message) {
+        if (isComputingLayout()) {
+            if (message == null) {
+                throw new IllegalStateException("Cannot call this method while RecyclerView is "
+                        + "computing a layout or scrolling");
+            }
+            throw new IllegalStateException(message);
+        }
+        if (mDispatchScrollCounter > 0) {
+            Log.w(TAG, "Cannot call this method in a scroll callback. Scroll callbacks might be run"
+                    + " during a measure & layout pass where you cannot change the RecyclerView"
+                    + " data. Any method call that might change the structure of the RecyclerView"
+                    + " or the adapter contents should be postponed to the next frame.",
+                    new IllegalStateException(""));
+        }
+    }
+
+    /**
+     * Add an {@link OnItemTouchListener} to intercept touch events before they are dispatched
+     * to child views or this view's standard scrolling behavior.
+     *
+     * <p>Client code may use listeners to implement item manipulation behavior. Once a listener
+     * returns true from
+     * {@link OnItemTouchListener#onInterceptTouchEvent(RecyclerView, MotionEvent)} its
+     * {@link OnItemTouchListener#onTouchEvent(RecyclerView, MotionEvent)} method will be called
+     * for each incoming MotionEvent until the end of the gesture.</p>
+     *
+     * @param listener Listener to add
+     * @see SimpleOnItemTouchListener
+     */
+    public void addOnItemTouchListener(OnItemTouchListener listener) {
+        mOnItemTouchListeners.add(listener);
+    }
+
+    /**
+     * Remove an {@link OnItemTouchListener}. It will no longer be able to intercept touch events.
+     *
+     * @param listener Listener to remove
+     */
+    public void removeOnItemTouchListener(OnItemTouchListener listener) {
+        mOnItemTouchListeners.remove(listener);
+        if (mActiveOnItemTouchListener == listener) {
+            mActiveOnItemTouchListener = null;
+        }
+    }
+
+    private boolean dispatchOnItemTouchIntercept(MotionEvent e) {
+        final int action = e.getAction();
+        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_DOWN) {
+            mActiveOnItemTouchListener = null;
+        }
+
+        final int listenerCount = mOnItemTouchListeners.size();
+        for (int i = 0; i < listenerCount; i++) {
+            final OnItemTouchListener listener = mOnItemTouchListeners.get(i);
+            if (listener.onInterceptTouchEvent(this, e) && action != MotionEvent.ACTION_CANCEL) {
+                mActiveOnItemTouchListener = listener;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean dispatchOnItemTouch(MotionEvent e) {
+        final int action = e.getAction();
+        if (mActiveOnItemTouchListener != null) {
+            if (action == MotionEvent.ACTION_DOWN) {
+                // Stale state from a previous gesture, we're starting a new one. Clear it.
+                mActiveOnItemTouchListener = null;
+            } else {
+                mActiveOnItemTouchListener.onTouchEvent(this, e);
+                if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+                    // Clean up for the next gesture.
+                    mActiveOnItemTouchListener = null;
+                }
+                return true;
+            }
+        }
+
+        // Listeners will have already received the ACTION_DOWN via dispatchOnItemTouchIntercept
+        // as called from onInterceptTouchEvent; skip it.
+        if (action != MotionEvent.ACTION_DOWN) {
+            final int listenerCount = mOnItemTouchListeners.size();
+            for (int i = 0; i < listenerCount; i++) {
+                final OnItemTouchListener listener = mOnItemTouchListeners.get(i);
+                if (listener.onInterceptTouchEvent(this, e)) {
+                    mActiveOnItemTouchListener = listener;
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent e) {
+        if (mLayoutFrozen) {
+            // When layout is frozen,  RV does not intercept the motion event.
+            // A child view e.g. a button may still get the click.
+            return false;
+        }
+        if (dispatchOnItemTouchIntercept(e)) {
+            cancelTouch();
+            return true;
+        }
+
+        if (mLayout == null) {
+            return false;
+        }
+
+        final boolean canScrollHorizontally = mLayout.canScrollHorizontally();
+        final boolean canScrollVertically = mLayout.canScrollVertically();
+
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        mVelocityTracker.addMovement(e);
+
+        final int action = e.getActionMasked();
+        final int actionIndex = e.getActionIndex();
+
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                if (mIgnoreMotionEventTillDown) {
+                    mIgnoreMotionEventTillDown = false;
+                }
+                mScrollPointerId = e.getPointerId(0);
+                mInitialTouchX = mLastTouchX = (int) (e.getX() + 0.5f);
+                mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f);
+
+                if (mScrollState == SCROLL_STATE_SETTLING) {
+                    getParent().requestDisallowInterceptTouchEvent(true);
+                    setScrollState(SCROLL_STATE_DRAGGING);
+                }
+
+                // Clear the nested offsets
+                mNestedOffsets[0] = mNestedOffsets[1] = 0;
+
+                int nestedScrollAxis = View.SCROLL_AXIS_NONE;
+                if (canScrollHorizontally) {
+                    nestedScrollAxis |= View.SCROLL_AXIS_HORIZONTAL;
+                }
+                if (canScrollVertically) {
+                    nestedScrollAxis |= View.SCROLL_AXIS_VERTICAL;
+                }
+                startNestedScroll(nestedScrollAxis);
+                break;
+
+            case MotionEvent.ACTION_POINTER_DOWN:
+                mScrollPointerId = e.getPointerId(actionIndex);
+                mInitialTouchX = mLastTouchX = (int) (e.getX(actionIndex) + 0.5f);
+                mInitialTouchY = mLastTouchY = (int) (e.getY(actionIndex) + 0.5f);
+                break;
+
+            case MotionEvent.ACTION_MOVE: {
+                final int index = e.findPointerIndex(mScrollPointerId);
+                if (index < 0) {
+                    Log.e(TAG, "Error processing scroll; pointer index for id "
+                            + mScrollPointerId + " not found. Did any MotionEvents get skipped?");
+                    return false;
+                }
+
+                final int x = (int) (e.getX(index) + 0.5f);
+                final int y = (int) (e.getY(index) + 0.5f);
+                if (mScrollState != SCROLL_STATE_DRAGGING) {
+                    final int dx = x - mInitialTouchX;
+                    final int dy = y - mInitialTouchY;
+                    boolean startScroll = false;
+                    if (canScrollHorizontally && Math.abs(dx) > mTouchSlop) {
+                        mLastTouchX = mInitialTouchX + mTouchSlop * (dx < 0 ? -1 : 1);
+                        startScroll = true;
+                    }
+                    if (canScrollVertically && Math.abs(dy) > mTouchSlop) {
+                        mLastTouchY = mInitialTouchY + mTouchSlop * (dy < 0 ? -1 : 1);
+                        startScroll = true;
+                    }
+                    if (startScroll) {
+                        setScrollState(SCROLL_STATE_DRAGGING);
+                    }
+                }
+            } break;
+
+            case MotionEvent.ACTION_POINTER_UP: {
+                onPointerUp(e);
+            } break;
+
+            case MotionEvent.ACTION_UP: {
+                mVelocityTracker.clear();
+                stopNestedScroll();
+            } break;
+
+            case MotionEvent.ACTION_CANCEL: {
+                cancelTouch();
+            }
+        }
+        return mScrollState == SCROLL_STATE_DRAGGING;
+    }
+
+    @Override
+    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        final int listenerCount = mOnItemTouchListeners.size();
+        for (int i = 0; i < listenerCount; i++) {
+            final OnItemTouchListener listener = mOnItemTouchListeners.get(i);
+            listener.onRequestDisallowInterceptTouchEvent(disallowIntercept);
+        }
+        super.requestDisallowInterceptTouchEvent(disallowIntercept);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent e) {
+        if (mLayoutFrozen || mIgnoreMotionEventTillDown) {
+            return false;
+        }
+        if (dispatchOnItemTouch(e)) {
+            cancelTouch();
+            return true;
+        }
+
+        if (mLayout == null) {
+            return false;
+        }
+
+        final boolean canScrollHorizontally = mLayout.canScrollHorizontally();
+        final boolean canScrollVertically = mLayout.canScrollVertically();
+
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        boolean eventAddedToVelocityTracker = false;
+
+        final MotionEvent vtev = MotionEvent.obtain(e);
+        final int action = e.getActionMasked();
+        final int actionIndex = e.getActionIndex();
+
+        if (action == MotionEvent.ACTION_DOWN) {
+            mNestedOffsets[0] = mNestedOffsets[1] = 0;
+        }
+        vtev.offsetLocation(mNestedOffsets[0], mNestedOffsets[1]);
+
+        switch (action) {
+            case MotionEvent.ACTION_DOWN: {
+                mScrollPointerId = e.getPointerId(0);
+                mInitialTouchX = mLastTouchX = (int) (e.getX() + 0.5f);
+                mInitialTouchY = mLastTouchY = (int) (e.getY() + 0.5f);
+
+                int nestedScrollAxis = View.SCROLL_AXIS_NONE;
+                if (canScrollHorizontally) {
+                    nestedScrollAxis |= View.SCROLL_AXIS_HORIZONTAL;
+                }
+                if (canScrollVertically) {
+                    nestedScrollAxis |= View.SCROLL_AXIS_VERTICAL;
+                }
+                startNestedScroll(nestedScrollAxis);
+            } break;
+
+            case MotionEvent.ACTION_POINTER_DOWN: {
+                mScrollPointerId = e.getPointerId(actionIndex);
+                mInitialTouchX = mLastTouchX = (int) (e.getX(actionIndex) + 0.5f);
+                mInitialTouchY = mLastTouchY = (int) (e.getY(actionIndex) + 0.5f);
+            } break;
+
+            case MotionEvent.ACTION_MOVE: {
+                final int index = e.findPointerIndex(mScrollPointerId);
+                if (index < 0) {
+                    Log.e(TAG, "Error processing scroll; pointer index for id "
+                            + mScrollPointerId + " not found. Did any MotionEvents get skipped?");
+                    return false;
+                }
+
+                final int x = (int) (e.getX(index) + 0.5f);
+                final int y = (int) (e.getY(index) + 0.5f);
+                int dx = mLastTouchX - x;
+                int dy = mLastTouchY - y;
+
+                if (dispatchNestedPreScroll(dx, dy, mScrollConsumed, mScrollOffset)) {
+                    dx -= mScrollConsumed[0];
+                    dy -= mScrollConsumed[1];
+                    vtev.offsetLocation(mScrollOffset[0], mScrollOffset[1]);
+                    // Updated the nested offsets
+                    mNestedOffsets[0] += mScrollOffset[0];
+                    mNestedOffsets[1] += mScrollOffset[1];
+                }
+
+                if (mScrollState != SCROLL_STATE_DRAGGING) {
+                    boolean startScroll = false;
+                    if (canScrollHorizontally && Math.abs(dx) > mTouchSlop) {
+                        if (dx > 0) {
+                            dx -= mTouchSlop;
+                        } else {
+                            dx += mTouchSlop;
+                        }
+                        startScroll = true;
+                    }
+                    if (canScrollVertically && Math.abs(dy) > mTouchSlop) {
+                        if (dy > 0) {
+                            dy -= mTouchSlop;
+                        } else {
+                            dy += mTouchSlop;
+                        }
+                        startScroll = true;
+                    }
+                    if (startScroll) {
+                        setScrollState(SCROLL_STATE_DRAGGING);
+                    }
+                }
+
+                if (mScrollState == SCROLL_STATE_DRAGGING) {
+                    mLastTouchX = x - mScrollOffset[0];
+                    mLastTouchY = y - mScrollOffset[1];
+
+                    if (scrollByInternal(
+                            canScrollHorizontally ? dx : 0,
+                            canScrollVertically ? dy : 0,
+                            vtev)) {
+                        getParent().requestDisallowInterceptTouchEvent(true);
+                    }
+                    if (mGapWorker != null && (dx != 0 || dy != 0)) {
+                        mGapWorker.postFromTraversal(this, dx, dy);
+                    }
+                }
+            } break;
+
+            case MotionEvent.ACTION_POINTER_UP: {
+                onPointerUp(e);
+            } break;
+
+            case MotionEvent.ACTION_UP: {
+                mVelocityTracker.addMovement(vtev);
+                eventAddedToVelocityTracker = true;
+                mVelocityTracker.computeCurrentVelocity(1000, mMaxFlingVelocity);
+                final float xvel = canScrollHorizontally
+                        ? -mVelocityTracker.getXVelocity(mScrollPointerId) : 0;
+                final float yvel = canScrollVertically
+                        ? -mVelocityTracker.getYVelocity(mScrollPointerId) : 0;
+                if (!((xvel != 0 || yvel != 0) && fling((int) xvel, (int) yvel))) {
+                    setScrollState(SCROLL_STATE_IDLE);
+                }
+                resetTouch();
+            } break;
+
+            case MotionEvent.ACTION_CANCEL: {
+                cancelTouch();
+            } break;
+        }
+
+        if (!eventAddedToVelocityTracker) {
+            mVelocityTracker.addMovement(vtev);
+        }
+        vtev.recycle();
+
+        return true;
+    }
+
+    private void resetTouch() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.clear();
+        }
+        stopNestedScroll();
+        releaseGlows();
+    }
+
+    private void cancelTouch() {
+        resetTouch();
+        setScrollState(SCROLL_STATE_IDLE);
+    }
+
+    private void onPointerUp(MotionEvent e) {
+        final int actionIndex = e.getActionIndex();
+        if (e.getPointerId(actionIndex) == mScrollPointerId) {
+            // Pick a new pointer to pick up the slack.
+            final int newIndex = actionIndex == 0 ? 1 : 0;
+            mScrollPointerId = e.getPointerId(newIndex);
+            mInitialTouchX = mLastTouchX = (int) (e.getX(newIndex) + 0.5f);
+            mInitialTouchY = mLastTouchY = (int) (e.getY(newIndex) + 0.5f);
+        }
+    }
+
+    // @Override
+    public boolean onGenericMotionEvent(MotionEvent event) {
+        if (mLayout == null) {
+            return false;
+        }
+        if (mLayoutFrozen) {
+            return false;
+        }
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+            if (event.getAction() == MotionEvent.ACTION_SCROLL) {
+                final float vScroll, hScroll;
+                if (mLayout.canScrollVertically()) {
+                    // Inverse the sign of the vertical scroll to align the scroll orientation
+                    // with AbsListView.
+                    vScroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+                } else {
+                    vScroll = 0f;
+                }
+                if (mLayout.canScrollHorizontally()) {
+                    hScroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
+                } else {
+                    hScroll = 0f;
+                }
+
+                if (vScroll != 0 || hScroll != 0) {
+                    final float scrollFactor = getScrollFactor();
+                    scrollByInternal((int) (hScroll * scrollFactor),
+                            (int) (vScroll * scrollFactor), event);
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Ported from View.getVerticalScrollFactor.
+     */
+    private float getScrollFactor() {
+        if (mScrollFactor == Float.MIN_VALUE) {
+            TypedValue outValue = new TypedValue();
+            if (getContext().getTheme().resolveAttribute(
+                    android.R.attr.listPreferredItemHeight, outValue, true)) {
+                mScrollFactor = outValue.getDimension(
+                        getContext().getResources().getDisplayMetrics());
+            } else {
+                return 0; //listPreferredItemHeight is not defined, no generic scrolling
+            }
+        }
+        return mScrollFactor;
+    }
+
+    @Override
+    protected void onMeasure(int widthSpec, int heightSpec) {
+        if (mLayout == null) {
+            defaultOnMeasure(widthSpec, heightSpec);
+            return;
+        }
+        if (mLayout.mAutoMeasure) {
+            final int widthMode = MeasureSpec.getMode(widthSpec);
+            final int heightMode = MeasureSpec.getMode(heightSpec);
+            final boolean skipMeasure = widthMode == MeasureSpec.EXACTLY
+                    && heightMode == MeasureSpec.EXACTLY;
+            mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
+            if (skipMeasure || mAdapter == null) {
+                return;
+            }
+            if (mState.mLayoutStep == State.STEP_START) {
+                dispatchLayoutStep1();
+            }
+            // set dimensions in 2nd step. Pre-layout should happen with old dimensions for
+            // consistency
+            mLayout.setMeasureSpecs(widthSpec, heightSpec);
+            mState.mIsMeasuring = true;
+            dispatchLayoutStep2();
+
+            // now we can get the width and height from the children.
+            mLayout.setMeasuredDimensionFromChildren(widthSpec, heightSpec);
+
+            // if RecyclerView has non-exact width and height and if there is at least one child
+            // which also has non-exact width & height, we have to re-measure.
+            if (mLayout.shouldMeasureTwice()) {
+                mLayout.setMeasureSpecs(
+                        MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
+                mState.mIsMeasuring = true;
+                dispatchLayoutStep2();
+                // now we can get the width and height from the children.
+                mLayout.setMeasuredDimensionFromChildren(widthSpec, heightSpec);
+            }
+        } else {
+            if (mHasFixedSize) {
+                mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
+                return;
+            }
+            // custom onMeasure
+            if (mAdapterUpdateDuringMeasure) {
+                eatRequestLayout();
+                onEnterLayoutOrScroll();
+                processAdapterUpdatesAndSetAnimationFlags();
+                onExitLayoutOrScroll();
+
+                if (mState.mRunPredictiveAnimations) {
+                    mState.mInPreLayout = true;
+                } else {
+                    // consume remaining updates to provide a consistent state with the layout pass.
+                    mAdapterHelper.consumeUpdatesInOnePass();
+                    mState.mInPreLayout = false;
+                }
+                mAdapterUpdateDuringMeasure = false;
+                resumeRequestLayout(false);
+            }
+
+            if (mAdapter != null) {
+                mState.mItemCount = mAdapter.getItemCount();
+            } else {
+                mState.mItemCount = 0;
+            }
+            eatRequestLayout();
+            mLayout.onMeasure(mRecycler, mState, widthSpec, heightSpec);
+            resumeRequestLayout(false);
+            mState.mInPreLayout = false; // clear
+        }
+    }
+
+    /**
+     * Used when onMeasure is called before layout manager is set
+     */
+    void defaultOnMeasure(int widthSpec, int heightSpec) {
+        // calling LayoutManager here is not pretty but that API is already public and it is better
+        // than creating another method since this is internal.
+        final int width = LayoutManager.chooseSize(widthSpec,
+                getPaddingLeft() + getPaddingRight(),
+                getMinimumWidth());
+        final int height = LayoutManager.chooseSize(heightSpec,
+                getPaddingTop() + getPaddingBottom(),
+                getMinimumHeight());
+
+        setMeasuredDimension(width, height);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        if (w != oldw || h != oldh) {
+            invalidateGlows();
+            // layout's w/h are updated during measure/layout steps.
+        }
+    }
+
+    /**
+     * Sets the {@link ItemAnimator} that will handle animations involving changes
+     * to the items in this RecyclerView. By default, RecyclerView instantiates and
+     * uses an instance of {@link DefaultItemAnimator}. Whether item animations are
+     * enabled for the RecyclerView depends on the ItemAnimator and whether
+     * the LayoutManager {@link LayoutManager#supportsPredictiveItemAnimations()
+     * supports item animations}.
+     *
+     * @param animator The ItemAnimator being set. If null, no animations will occur
+     * when changes occur to the items in this RecyclerView.
+     */
+    public void setItemAnimator(ItemAnimator animator) {
+        if (mItemAnimator != null) {
+            mItemAnimator.endAnimations();
+            mItemAnimator.setListener(null);
+        }
+        mItemAnimator = animator;
+        if (mItemAnimator != null) {
+            mItemAnimator.setListener(mItemAnimatorListener);
+        }
+    }
+
+    void onEnterLayoutOrScroll() {
+        mLayoutOrScrollCounter++;
+    }
+
+    void onExitLayoutOrScroll() {
+        mLayoutOrScrollCounter--;
+        if (mLayoutOrScrollCounter < 1) {
+            if (DEBUG && mLayoutOrScrollCounter < 0) {
+                throw new IllegalStateException("layout or scroll counter cannot go below zero."
+                        + "Some calls are not matching");
+            }
+            mLayoutOrScrollCounter = 0;
+            dispatchContentChangedIfNecessary();
+            dispatchPendingImportantForAccessibilityChanges();
+        }
+    }
+
+    boolean isAccessibilityEnabled() {
+        return mAccessibilityManager != null && mAccessibilityManager.isEnabled();
+    }
+
+    private void dispatchContentChangedIfNecessary() {
+        final int flags = mEatenAccessibilityChangeFlags;
+        mEatenAccessibilityChangeFlags = 0;
+        if (flags != 0 && isAccessibilityEnabled()) {
+            final AccessibilityEvent event = AccessibilityEvent.obtain();
+            event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+            event.setContentChangeTypes(flags);
+            sendAccessibilityEventUnchecked(event);
+        }
+    }
+
+    /**
+     * Returns whether RecyclerView is currently computing a layout.
+     * <p>
+     * If this method returns true, it means that RecyclerView is in a lockdown state and any
+     * attempt to update adapter contents will result in an exception because adapter contents
+     * cannot be changed while RecyclerView is trying to compute the layout.
+     * <p>
+     * It is very unlikely that your code will be running during this state as it is
+     * called by the framework when a layout traversal happens or RecyclerView starts to scroll
+     * in response to system events (touch, accessibility etc).
+     * <p>
+     * This case may happen if you have some custom logic to change adapter contents in
+     * response to a View callback (e.g. focus change callback) which might be triggered during a
+     * layout calculation. In these cases, you should just postpone the change using a Handler or a
+     * similar mechanism.
+     *
+     * @return <code>true</code> if RecyclerView is currently computing a layout, <code>false</code>
+     *         otherwise
+     */
+    public boolean isComputingLayout() {
+        return mLayoutOrScrollCounter > 0;
+    }
+
+    /**
+     * Returns true if an accessibility event should not be dispatched now. This happens when an
+     * accessibility request arrives while RecyclerView does not have a stable state which is very
+     * hard to handle for a LayoutManager. Instead, this method records necessary information about
+     * the event and dispatches a window change event after the critical section is finished.
+     *
+     * @return True if the accessibility event should be postponed.
+     */
+    boolean shouldDeferAccessibilityEvent(AccessibilityEvent event) {
+        if (isComputingLayout()) {
+            int type = 0;
+            if (event != null) {
+                type = event.getContentChangeTypes();
+            }
+            if (type == 0) {
+                type = AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED;
+            }
+            mEatenAccessibilityChangeFlags |= type;
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
+        if (shouldDeferAccessibilityEvent(event)) {
+            return;
+        }
+        super.sendAccessibilityEventUnchecked(event);
+    }
+
+    /**
+     * Gets the current ItemAnimator for this RecyclerView. A null return value
+     * indicates that there is no animator and that item changes will happen without
+     * any animations. By default, RecyclerView instantiates and
+     * uses an instance of {@link DefaultItemAnimator}.
+     *
+     * @return ItemAnimator The current ItemAnimator. If null, no animations will occur
+     * when changes occur to the items in this RecyclerView.
+     */
+    public ItemAnimator getItemAnimator() {
+        return mItemAnimator;
+    }
+
+    /**
+     * 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.
+     */
+    void postAnimationRunner() {
+        if (!mPostedAnimatorRunner && mIsAttached) {
+            postOnAnimation(mItemAnimatorRunner);
+            mPostedAnimatorRunner = true;
+        }
+    }
+
+    private boolean predictiveItemAnimationsEnabled() {
+        return (mItemAnimator != null && mLayout.supportsPredictiveItemAnimations());
+    }
+
+    /**
+     * Consumes adapter updates and calculates which type of animations we want to run.
+     * Called in onMeasure and dispatchLayout.
+     * <p>
+     * This method may process only the pre-layout state of updates or all of them.
+     */
+    private void processAdapterUpdatesAndSetAnimationFlags() {
+        if (mDataSetHasChangedAfterLayout) {
+            // Processing these items have no value since data set changed unexpectedly.
+            // Instead, we just reset it.
+            mAdapterHelper.reset();
+            mLayout.onItemsChanged(this);
+        }
+        // simple animations are a subset of advanced animations (which will cause a
+        // pre-layout step)
+        // If layout supports predictive animations, pre-process to decide if we want to run them
+        if (predictiveItemAnimationsEnabled()) {
+            mAdapterHelper.preProcess();
+        } else {
+            mAdapterHelper.consumeUpdatesInOnePass();
+        }
+        boolean animationTypeSupported = mItemsAddedOrRemoved || mItemsChanged;
+        mState.mRunSimpleAnimations = mFirstLayoutComplete
+                && mItemAnimator != null
+                && (mDataSetHasChangedAfterLayout
+                        || animationTypeSupported
+                        || mLayout.mRequestedSimpleAnimations)
+                && (!mDataSetHasChangedAfterLayout
+                        || mAdapter.hasStableIds());
+        mState.mRunPredictiveAnimations = mState.mRunSimpleAnimations
+                && animationTypeSupported
+                && !mDataSetHasChangedAfterLayout
+                && predictiveItemAnimationsEnabled();
+    }
+
+    /**
+     * Wrapper around layoutChildren() that handles animating changes caused by layout.
+     * Animations work on the assumption that there are five different kinds of items
+     * in play:
+     * PERSISTENT: items are visible before and after layout
+     * REMOVED: items were visible before layout and were removed by the app
+     * ADDED: items did not exist before layout and were added by the app
+     * DISAPPEARING: items exist in the data set before/after, but changed from
+     * visible to non-visible in the process of layout (they were moved off
+     * screen as a side-effect of other changes)
+     * APPEARING: items exist in the data set before/after, but changed from
+     * non-visible to visible in the process of layout (they were moved on
+     * screen as a side-effect of other changes)
+     * The overall approach figures out what items exist before/after layout and
+     * infers one of the five above states for each of the items. Then the animations
+     * are set up accordingly:
+     * PERSISTENT views are animated via
+     * {@link ItemAnimator#animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo)}
+     * DISAPPEARING views are animated via
+     * {@link ItemAnimator#animateDisappearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)}
+     * APPEARING views are animated via
+     * {@link ItemAnimator#animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)}
+     * and changed views are animated via
+     * {@link ItemAnimator#animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)}.
+     */
+    void dispatchLayout() {
+        if (mAdapter == null) {
+            Log.e(TAG, "No adapter attached; skipping layout");
+            // leave the state in START
+            return;
+        }
+        if (mLayout == null) {
+            Log.e(TAG, "No layout manager attached; skipping layout");
+            // leave the state in START
+            return;
+        }
+        mState.mIsMeasuring = false;
+        if (mState.mLayoutStep == State.STEP_START) {
+            dispatchLayoutStep1();
+            mLayout.setExactMeasureSpecsFrom(this);
+            dispatchLayoutStep2();
+        } else if (mAdapterHelper.hasUpdates() || mLayout.getWidth() != getWidth()
+                || mLayout.getHeight() != getHeight()) {
+            // First 2 steps are done in onMeasure but looks like we have to run again due to
+            // changed size.
+            mLayout.setExactMeasureSpecsFrom(this);
+            dispatchLayoutStep2();
+        } else {
+            // always make sure we sync them (to ensure mode is exact)
+            mLayout.setExactMeasureSpecsFrom(this);
+        }
+        dispatchLayoutStep3();
+    }
+
+    private void saveFocusInfo() {
+        View child = null;
+        if (mPreserveFocusAfterLayout && hasFocus() && mAdapter != null) {
+            child = getFocusedChild();
+        }
+
+        final ViewHolder focusedVh = child == null ? null : findContainingViewHolder(child);
+        if (focusedVh == null) {
+            resetFocusInfo();
+        } else {
+            mState.mFocusedItemId = mAdapter.hasStableIds() ? focusedVh.getItemId() : NO_ID;
+            // mFocusedItemPosition should hold the current adapter position of the previously
+            // focused item. If the item is removed, we store the previous adapter position of the
+            // removed item.
+            mState.mFocusedItemPosition = mDataSetHasChangedAfterLayout ? NO_POSITION
+                    : (focusedVh.isRemoved() ? focusedVh.mOldPosition
+                            : focusedVh.getAdapterPosition());
+            mState.mFocusedSubChildId = getDeepestFocusedViewWithId(focusedVh.itemView);
+        }
+    }
+
+    private void resetFocusInfo() {
+        mState.mFocusedItemId = NO_ID;
+        mState.mFocusedItemPosition = NO_POSITION;
+        mState.mFocusedSubChildId = View.NO_ID;
+    }
+
+    /**
+     * Finds the best view candidate to request focus on using mFocusedItemPosition index of the
+     * previously focused item. It first traverses the adapter forward to find a focusable candidate
+     * and if no such candidate is found, it reverses the focus search direction for the items
+     * before the mFocusedItemPosition'th index;
+     * @return The best candidate to request focus on, or null if no such candidate exists. Null
+     * indicates all the existing adapter items are unfocusable.
+     */
+    @Nullable
+    private View findNextViewToFocus() {
+        int startFocusSearchIndex = mState.mFocusedItemPosition != -1 ? mState.mFocusedItemPosition
+                : 0;
+        ViewHolder nextFocus;
+        final int itemCount = mState.getItemCount();
+        for (int i = startFocusSearchIndex; i < itemCount; i++) {
+            nextFocus = findViewHolderForAdapterPosition(i);
+            if (nextFocus == null) {
+                break;
+            }
+            if (nextFocus.itemView.hasFocusable()) {
+                return nextFocus.itemView;
+            }
+        }
+        final int limit = Math.min(itemCount, startFocusSearchIndex);
+        for (int i = limit - 1; i >= 0; i--) {
+            nextFocus = findViewHolderForAdapterPosition(i);
+            if (nextFocus == null) {
+                return null;
+            }
+            if (nextFocus.itemView.hasFocusable()) {
+                return nextFocus.itemView;
+            }
+        }
+        return null;
+    }
+
+    private void recoverFocusFromState() {
+        if (!mPreserveFocusAfterLayout || mAdapter == null || !hasFocus()
+                || getDescendantFocusability() == FOCUS_BLOCK_DESCENDANTS
+                || (getDescendantFocusability() == FOCUS_BEFORE_DESCENDANTS && isFocused())) {
+            // No-op if either of these cases happens:
+            // 1. RV has no focus, or 2. RV blocks focus to its children, or 3. RV takes focus
+            // before its children and is focused (i.e. it already stole the focus away from its
+            // descendants).
+            return;
+        }
+        // only recover focus if RV itself has the focus or the focused view is hidden
+        if (!isFocused()) {
+            final View focusedChild = getFocusedChild();
+            if (IGNORE_DETACHED_FOCUSED_CHILD
+                    && (focusedChild.getParent() == null || !focusedChild.hasFocus())) {
+                // Special handling of API 15-. A focused child can be invalid because mFocus is not
+                // cleared when the child is detached (mParent = null),
+                // This happens because clearFocus on API 15- does not invalidate mFocus of its
+                // parent when this child is detached.
+                // For API 16+, this is not an issue because requestFocus takes care of clearing the
+                // prior detached focused child. For API 15- the problem happens in 2 cases because
+                // clearChild does not call clearChildFocus on RV: 1. setFocusable(false) is called
+                // for the current focused item which calls clearChild or 2. when the prior focused
+                // child is removed, removeDetachedView called in layout step 3 which calls
+                // clearChild. We should ignore this invalid focused child in all our calculations
+                // for the next view to receive focus, and apply the focus recovery logic instead.
+                if (mChildHelper.getChildCount() == 0) {
+                    // No children left. Request focus on the RV itself since one of its children
+                    // was holding focus previously.
+                    requestFocus();
+                    return;
+                }
+            } else if (!mChildHelper.isHidden(focusedChild)) {
+                // If the currently focused child is hidden, apply the focus recovery logic.
+                // Otherwise return, i.e. the currently (unhidden) focused child is good enough :/.
+                return;
+            }
+        }
+        ViewHolder focusTarget = null;
+        // RV first attempts to locate the previously focused item to request focus on using
+        // mFocusedItemId. If such an item no longer exists, it then makes a best-effort attempt to
+        // find the next best candidate to request focus on based on mFocusedItemPosition.
+        if (mState.mFocusedItemId != NO_ID && mAdapter.hasStableIds()) {
+            focusTarget = findViewHolderForItemId(mState.mFocusedItemId);
+        }
+        View viewToFocus = null;
+        if (focusTarget == null || mChildHelper.isHidden(focusTarget.itemView)
+                || !focusTarget.itemView.hasFocusable()) {
+            if (mChildHelper.getChildCount() > 0) {
+                // At this point, RV has focus and either of these conditions are true:
+                // 1. There's no previously focused item either because RV received focused before
+                // layout, or the previously focused item was removed, or RV doesn't have stable IDs
+                // 2. Previous focus child is hidden, or 3. Previous focused child is no longer
+                // focusable. In either of these cases, we make sure that RV still passes down the
+                // focus to one of its focusable children using a best-effort algorithm.
+                viewToFocus = findNextViewToFocus();
+            }
+        } else {
+            // looks like the focused item has been replaced with another view that represents the
+            // same item in the adapter. Request focus on that.
+            viewToFocus = focusTarget.itemView;
+        }
+
+        if (viewToFocus != null) {
+            if (mState.mFocusedSubChildId != NO_ID) {
+                View child = viewToFocus.findViewById(mState.mFocusedSubChildId);
+                if (child != null && child.isFocusable()) {
+                    viewToFocus = child;
+                }
+            }
+            viewToFocus.requestFocus();
+        }
+    }
+
+    private int getDeepestFocusedViewWithId(View view) {
+        int lastKnownId = view.getId();
+        while (!view.isFocused() && view instanceof ViewGroup && view.hasFocus()) {
+            view = ((ViewGroup) view).getFocusedChild();
+            final int id = view.getId();
+            if (id != View.NO_ID) {
+                lastKnownId = view.getId();
+            }
+        }
+        return lastKnownId;
+    }
+
+    /**
+     * The first step of a layout where we;
+     * - process adapter updates
+     * - decide which animation should run
+     * - save information about current views
+     * - If necessary, run predictive layout and save its information
+     */
+    private void dispatchLayoutStep1() {
+        mState.assertLayoutStep(State.STEP_START);
+        mState.mIsMeasuring = false;
+        eatRequestLayout();
+        mViewInfoStore.clear();
+        onEnterLayoutOrScroll();
+        processAdapterUpdatesAndSetAnimationFlags();
+        saveFocusInfo();
+        mState.mTrackOldChangeHolders = mState.mRunSimpleAnimations && mItemsChanged;
+        mItemsAddedOrRemoved = mItemsChanged = false;
+        mState.mInPreLayout = mState.mRunPredictiveAnimations;
+        mState.mItemCount = mAdapter.getItemCount();
+        findMinMaxChildLayoutPositions(mMinMaxLayoutPositions);
+
+        if (mState.mRunSimpleAnimations) {
+            // Step 0: Find out where all non-removed items are, pre-layout
+            int count = mChildHelper.getChildCount();
+            for (int i = 0; i < count; ++i) {
+                final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i));
+                if (holder.shouldIgnore() || (holder.isInvalid() && !mAdapter.hasStableIds())) {
+                    continue;
+                }
+                final ItemHolderInfo animationInfo = mItemAnimator
+                        .recordPreLayoutInformation(mState, holder,
+                                ItemAnimator.buildAdapterChangeFlagsForAnimations(holder),
+                                holder.getUnmodifiedPayloads());
+                mViewInfoStore.addToPreLayout(holder, animationInfo);
+                if (mState.mTrackOldChangeHolders && holder.isUpdated() && !holder.isRemoved()
+                        && !holder.shouldIgnore() && !holder.isInvalid()) {
+                    long key = getChangedHolderKey(holder);
+                    // This is NOT the only place where a ViewHolder is added to old change holders
+                    // list. There is another case where:
+                    //    * A VH is currently hidden but not deleted
+                    //    * The hidden item is changed in the adapter
+                    //    * Layout manager decides to layout the item in the pre-Layout pass (step1)
+                    // When this case is detected, RV will un-hide that view and add to the old
+                    // change holders list.
+                    mViewInfoStore.addToOldChangeHolders(key, holder);
+                }
+            }
+        }
+        if (mState.mRunPredictiveAnimations) {
+            // Step 1: run prelayout: This will use the old positions of items. The layout manager
+            // is expected to layout everything, even removed items (though not to add removed
+            // items back to the container). This gives the pre-layout position of APPEARING views
+            // which come into existence as part of the real layout.
+
+            // Save old positions so that LayoutManager can run its mapping logic.
+            saveOldPositions();
+            final boolean didStructureChange = mState.mStructureChanged;
+            mState.mStructureChanged = false;
+            // temporarily disable flag because we are asking for previous layout
+            mLayout.onLayoutChildren(mRecycler, mState);
+            mState.mStructureChanged = didStructureChange;
+
+            for (int i = 0; i < mChildHelper.getChildCount(); ++i) {
+                final View child = mChildHelper.getChildAt(i);
+                final ViewHolder viewHolder = getChildViewHolderInt(child);
+                if (viewHolder.shouldIgnore()) {
+                    continue;
+                }
+                if (!mViewInfoStore.isInPreLayout(viewHolder)) {
+                    int flags = ItemAnimator.buildAdapterChangeFlagsForAnimations(viewHolder);
+                    boolean wasHidden = viewHolder
+                            .hasAnyOfTheFlags(ViewHolder.FLAG_BOUNCED_FROM_HIDDEN_LIST);
+                    if (!wasHidden) {
+                        flags |= ItemAnimator.FLAG_APPEARED_IN_PRE_LAYOUT;
+                    }
+                    final ItemHolderInfo animationInfo = mItemAnimator.recordPreLayoutInformation(
+                            mState, viewHolder, flags, viewHolder.getUnmodifiedPayloads());
+                    if (wasHidden) {
+                        recordAnimationInfoIfBouncedHiddenView(viewHolder, animationInfo);
+                    } else {
+                        mViewInfoStore.addToAppearedInPreLayoutHolders(viewHolder, animationInfo);
+                    }
+                }
+            }
+            // we don't process disappearing list because they may re-appear in post layout pass.
+            clearOldPositions();
+        } else {
+            clearOldPositions();
+        }
+        onExitLayoutOrScroll();
+        resumeRequestLayout(false);
+        mState.mLayoutStep = State.STEP_LAYOUT;
+    }
+
+    /**
+     * The second layout step where we do the actual layout of the views for the final state.
+     * This step might be run multiple times if necessary (e.g. measure).
+     */
+    private void dispatchLayoutStep2() {
+        eatRequestLayout();
+        onEnterLayoutOrScroll();
+        mState.assertLayoutStep(State.STEP_LAYOUT | State.STEP_ANIMATIONS);
+        mAdapterHelper.consumeUpdatesInOnePass();
+        mState.mItemCount = mAdapter.getItemCount();
+        mState.mDeletedInvisibleItemCountSincePreviousLayout = 0;
+
+        // Step 2: Run layout
+        mState.mInPreLayout = false;
+        mLayout.onLayoutChildren(mRecycler, mState);
+
+        mState.mStructureChanged = false;
+        mPendingSavedState = null;
+
+        // onLayoutChildren may have caused client code to disable item animations; re-check
+        mState.mRunSimpleAnimations = mState.mRunSimpleAnimations && mItemAnimator != null;
+        mState.mLayoutStep = State.STEP_ANIMATIONS;
+        onExitLayoutOrScroll();
+        resumeRequestLayout(false);
+    }
+
+    /**
+     * The final step of the layout where we save the information about views for animations,
+     * trigger animations and do any necessary cleanup.
+     */
+    private void dispatchLayoutStep3() {
+        mState.assertLayoutStep(State.STEP_ANIMATIONS);
+        eatRequestLayout();
+        onEnterLayoutOrScroll();
+        mState.mLayoutStep = State.STEP_START;
+        if (mState.mRunSimpleAnimations) {
+            // Step 3: Find out where things are now, and process change animations.
+            // traverse list in reverse because we may call animateChange in the loop which may
+            // remove the target view holder.
+            for (int i = mChildHelper.getChildCount() - 1; i >= 0; i--) {
+                ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i));
+                if (holder.shouldIgnore()) {
+                    continue;
+                }
+                long key = getChangedHolderKey(holder);
+                final ItemHolderInfo animationInfo = mItemAnimator
+                        .recordPostLayoutInformation(mState, holder);
+                ViewHolder oldChangeViewHolder = mViewInfoStore.getFromOldChangeHolders(key);
+                if (oldChangeViewHolder != null && !oldChangeViewHolder.shouldIgnore()) {
+                    // run a change animation
+
+                    // If an Item is CHANGED but the updated version is disappearing, it creates
+                    // a conflicting case.
+                    // Since a view that is marked as disappearing is likely to be going out of
+                    // bounds, we run a change animation. Both views will be cleaned automatically
+                    // once their animations finish.
+                    // On the other hand, if it is the same view holder instance, we run a
+                    // disappearing animation instead because we are not going to rebind the updated
+                    // VH unless it is enforced by the layout manager.
+                    final boolean oldDisappearing = mViewInfoStore.isDisappearing(
+                            oldChangeViewHolder);
+                    final boolean newDisappearing = mViewInfoStore.isDisappearing(holder);
+                    if (oldDisappearing && oldChangeViewHolder == holder) {
+                        // run disappear animation instead of change
+                        mViewInfoStore.addToPostLayout(holder, animationInfo);
+                    } else {
+                        final ItemHolderInfo preInfo = mViewInfoStore.popFromPreLayout(
+                                oldChangeViewHolder);
+                        // we add and remove so that any post info is merged.
+                        mViewInfoStore.addToPostLayout(holder, animationInfo);
+                        ItemHolderInfo postInfo = mViewInfoStore.popFromPostLayout(holder);
+                        if (preInfo == null) {
+                            handleMissingPreInfoForChangeError(key, holder, oldChangeViewHolder);
+                        } else {
+                            animateChange(oldChangeViewHolder, holder, preInfo, postInfo,
+                                    oldDisappearing, newDisappearing);
+                        }
+                    }
+                } else {
+                    mViewInfoStore.addToPostLayout(holder, animationInfo);
+                }
+            }
+
+            // Step 4: Process view info lists and trigger animations
+            mViewInfoStore.process(mViewInfoProcessCallback);
+        }
+
+        mLayout.removeAndRecycleScrapInt(mRecycler);
+        mState.mPreviousLayoutItemCount = mState.mItemCount;
+        mDataSetHasChangedAfterLayout = false;
+        mState.mRunSimpleAnimations = false;
+
+        mState.mRunPredictiveAnimations = false;
+        mLayout.mRequestedSimpleAnimations = false;
+        if (mRecycler.mChangedScrap != null) {
+            mRecycler.mChangedScrap.clear();
+        }
+        if (mLayout.mPrefetchMaxObservedInInitialPrefetch) {
+            // Initial prefetch has expanded cache, so reset until next prefetch.
+            // This prevents initial prefetches from expanding the cache permanently.
+            mLayout.mPrefetchMaxCountObserved = 0;
+            mLayout.mPrefetchMaxObservedInInitialPrefetch = false;
+            mRecycler.updateViewCacheSize();
+        }
+
+        mLayout.onLayoutCompleted(mState);
+        onExitLayoutOrScroll();
+        resumeRequestLayout(false);
+        mViewInfoStore.clear();
+        if (didChildRangeChange(mMinMaxLayoutPositions[0], mMinMaxLayoutPositions[1])) {
+            dispatchOnScrolled(0, 0);
+        }
+        recoverFocusFromState();
+        resetFocusInfo();
+    }
+
+    /**
+     * This handles the case where there is an unexpected VH missing in the pre-layout map.
+     * <p>
+     * We might be able to detect the error in the application which will help the developer to
+     * resolve the issue.
+     * <p>
+     * If it is not an expected error, we at least print an error to notify the developer and ignore
+     * the animation.
+     *
+     * https://code.google.com/p/android/issues/detail?id=193958
+     *
+     * @param key The change key
+     * @param holder Current ViewHolder
+     * @param oldChangeViewHolder Changed ViewHolder
+     */
+    private void handleMissingPreInfoForChangeError(long key,
+            ViewHolder holder, ViewHolder oldChangeViewHolder) {
+        // check if two VH have the same key, if so, print that as an error
+        final int childCount = mChildHelper.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View view = mChildHelper.getChildAt(i);
+            ViewHolder other = getChildViewHolderInt(view);
+            if (other == holder) {
+                continue;
+            }
+            final long otherKey = getChangedHolderKey(other);
+            if (otherKey == key) {
+                if (mAdapter != null && mAdapter.hasStableIds()) {
+                    throw new IllegalStateException("Two different ViewHolders have the same stable"
+                            + " ID. Stable IDs in your adapter MUST BE unique and SHOULD NOT"
+                            + " change.\n ViewHolder 1:" + other + " \n View Holder 2:" + holder);
+                } else {
+                    throw new IllegalStateException("Two different ViewHolders have the same change"
+                            + " ID. This might happen due to inconsistent Adapter update events or"
+                            + " if the LayoutManager lays out the same View multiple times."
+                            + "\n ViewHolder 1:" + other + " \n View Holder 2:" + holder);
+                }
+            }
+        }
+        // Very unlikely to happen but if it does, notify the developer.
+        Log.e(TAG, "Problem while matching changed view holders with the new"
+                + "ones. The pre-layout information for the change holder " + oldChangeViewHolder
+                + " cannot be found but it is necessary for " + holder);
+    }
+
+    /**
+     * Records the animation information for a view holder that was bounced from hidden list. It
+     * also clears the bounce back flag.
+     */
+    void recordAnimationInfoIfBouncedHiddenView(ViewHolder viewHolder,
+            ItemHolderInfo animationInfo) {
+        // looks like this view bounced back from hidden list!
+        viewHolder.setFlags(0, ViewHolder.FLAG_BOUNCED_FROM_HIDDEN_LIST);
+        if (mState.mTrackOldChangeHolders && viewHolder.isUpdated()
+                && !viewHolder.isRemoved() && !viewHolder.shouldIgnore()) {
+            long key = getChangedHolderKey(viewHolder);
+            mViewInfoStore.addToOldChangeHolders(key, viewHolder);
+        }
+        mViewInfoStore.addToPreLayout(viewHolder, animationInfo);
+    }
+
+    private void findMinMaxChildLayoutPositions(int[] into) {
+        final int count = mChildHelper.getChildCount();
+        if (count == 0) {
+            into[0] = NO_POSITION;
+            into[1] = NO_POSITION;
+            return;
+        }
+        int minPositionPreLayout = Integer.MAX_VALUE;
+        int maxPositionPreLayout = Integer.MIN_VALUE;
+        for (int i = 0; i < count; ++i) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i));
+            if (holder.shouldIgnore()) {
+                continue;
+            }
+            final int pos = holder.getLayoutPosition();
+            if (pos < minPositionPreLayout) {
+                minPositionPreLayout = pos;
+            }
+            if (pos > maxPositionPreLayout) {
+                maxPositionPreLayout = pos;
+            }
+        }
+        into[0] = minPositionPreLayout;
+        into[1] = maxPositionPreLayout;
+    }
+
+    private boolean didChildRangeChange(int minPositionPreLayout, int maxPositionPreLayout) {
+        findMinMaxChildLayoutPositions(mMinMaxLayoutPositions);
+        return mMinMaxLayoutPositions[0] != minPositionPreLayout
+                || mMinMaxLayoutPositions[1] != maxPositionPreLayout;
+    }
+
+    @Override
+    protected void removeDetachedView(View child, boolean animate) {
+        ViewHolder vh = getChildViewHolderInt(child);
+        if (vh != null) {
+            if (vh.isTmpDetached()) {
+                vh.clearTmpDetachFlag();
+            } else if (!vh.shouldIgnore()) {
+                throw new IllegalArgumentException("Called removeDetachedView with a view which"
+                        + " is not flagged as tmp detached." + vh);
+            }
+        }
+        dispatchChildDetached(child);
+        super.removeDetachedView(child, animate);
+    }
+
+    /**
+     * Returns a unique key to be used while handling change animations.
+     * It might be child's position or stable id depending on the adapter type.
+     */
+    long getChangedHolderKey(ViewHolder holder) {
+        return mAdapter.hasStableIds() ? holder.getItemId() : holder.mPosition;
+    }
+
+    void animateAppearance(@NonNull ViewHolder itemHolder,
+            @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
+        itemHolder.setIsRecyclable(false);
+        if (mItemAnimator.animateAppearance(itemHolder, preLayoutInfo, postLayoutInfo)) {
+            postAnimationRunner();
+        }
+    }
+
+    void animateDisappearance(@NonNull ViewHolder holder,
+            @NonNull ItemHolderInfo preLayoutInfo, @Nullable ItemHolderInfo postLayoutInfo) {
+        addAnimatingView(holder);
+        holder.setIsRecyclable(false);
+        if (mItemAnimator.animateDisappearance(holder, preLayoutInfo, postLayoutInfo)) {
+            postAnimationRunner();
+        }
+    }
+
+    private void animateChange(@NonNull ViewHolder oldHolder, @NonNull ViewHolder newHolder,
+            @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo,
+            boolean oldHolderDisappearing, boolean newHolderDisappearing) {
+        oldHolder.setIsRecyclable(false);
+        if (oldHolderDisappearing) {
+            addAnimatingView(oldHolder);
+        }
+        if (oldHolder != newHolder) {
+            if (newHolderDisappearing) {
+                addAnimatingView(newHolder);
+            }
+            oldHolder.mShadowedHolder = newHolder;
+            // old holder should disappear after animation ends
+            addAnimatingView(oldHolder);
+            mRecycler.unscrapView(oldHolder);
+            newHolder.setIsRecyclable(false);
+            newHolder.mShadowingHolder = oldHolder;
+        }
+        if (mItemAnimator.animateChange(oldHolder, newHolder, preInfo, postInfo)) {
+            postAnimationRunner();
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        Trace.beginSection(TRACE_ON_LAYOUT_TAG);
+        dispatchLayout();
+        Trace.endSection();
+        mFirstLayoutComplete = true;
+    }
+
+    @Override
+    public void requestLayout() {
+        if (mEatRequestLayout == 0 && !mLayoutFrozen) {
+            super.requestLayout();
+        } else {
+            mLayoutRequestEaten = true;
+        }
+    }
+
+    void markItemDecorInsetsDirty() {
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final View child = mChildHelper.getUnfilteredChildAt(i);
+            ((LayoutParams) child.getLayoutParams()).mInsetsDirty = true;
+        }
+        mRecycler.markItemDecorInsetsDirty();
+    }
+
+    @Override
+    public void draw(Canvas c) {
+        super.draw(c);
+
+        final int count = mItemDecorations.size();
+        for (int i = 0; i < count; i++) {
+            mItemDecorations.get(i).onDrawOver(c, this, mState);
+        }
+        // TODO If padding is not 0 and clipChildrenToPadding is false, to draw glows properly, we
+        // need find children closest to edges. Not sure if it is worth the effort.
+        boolean needsInvalidate = false;
+        if (mLeftGlow != null && !mLeftGlow.isFinished()) {
+            final int restore = c.save();
+            final int padding = mClipToPadding ? getPaddingBottom() : 0;
+            c.rotate(270);
+            c.translate(-getHeight() + padding, 0);
+            needsInvalidate = mLeftGlow != null && mLeftGlow.draw(c);
+            c.restoreToCount(restore);
+        }
+        if (mTopGlow != null && !mTopGlow.isFinished()) {
+            final int restore = c.save();
+            if (mClipToPadding) {
+                c.translate(getPaddingLeft(), getPaddingTop());
+            }
+            needsInvalidate |= mTopGlow != null && mTopGlow.draw(c);
+            c.restoreToCount(restore);
+        }
+        if (mRightGlow != null && !mRightGlow.isFinished()) {
+            final int restore = c.save();
+            final int width = getWidth();
+            final int padding = mClipToPadding ? getPaddingTop() : 0;
+            c.rotate(90);
+            c.translate(-padding, -width);
+            needsInvalidate |= mRightGlow != null && mRightGlow.draw(c);
+            c.restoreToCount(restore);
+        }
+        if (mBottomGlow != null && !mBottomGlow.isFinished()) {
+            final int restore = c.save();
+            c.rotate(180);
+            if (mClipToPadding) {
+                c.translate(-getWidth() + getPaddingRight(), -getHeight() + getPaddingBottom());
+            } else {
+                c.translate(-getWidth(), -getHeight());
+            }
+            needsInvalidate |= mBottomGlow != null && mBottomGlow.draw(c);
+            c.restoreToCount(restore);
+        }
+
+        // If some views are animating, ItemDecorators are likely to move/change with them.
+        // Invalidate RecyclerView to re-draw decorators. This is still efficient because children's
+        // display lists are not invalidated.
+        if (!needsInvalidate && mItemAnimator != null && mItemDecorations.size() > 0
+                && mItemAnimator.isRunning()) {
+            needsInvalidate = true;
+        }
+
+        if (needsInvalidate) {
+            postInvalidateOnAnimation();
+        }
+    }
+
+    @Override
+    public void onDraw(Canvas c) {
+        super.onDraw(c);
+
+        final int count = mItemDecorations.size();
+        for (int i = 0; i < count; i++) {
+            mItemDecorations.get(i).onDraw(c, this, mState);
+        }
+    }
+
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams && mLayout.checkLayoutParams((LayoutParams) p);
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
+        if (mLayout == null) {
+            throw new IllegalStateException("RecyclerView has no LayoutManager");
+        }
+        return mLayout.generateDefaultLayoutParams();
+    }
+
+    @Override
+    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
+        if (mLayout == null) {
+            throw new IllegalStateException("RecyclerView has no LayoutManager");
+        }
+        return mLayout.generateLayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        if (mLayout == null) {
+            throw new IllegalStateException("RecyclerView has no LayoutManager");
+        }
+        return mLayout.generateLayoutParams(p);
+    }
+
+    /**
+     * Returns true if RecyclerView is currently running some animations.
+     * <p>
+     * If you want to be notified when animations are finished, use
+     * {@link ItemAnimator#isRunning(ItemAnimator.ItemAnimatorFinishedListener)}.
+     *
+     * @return True if there are some item animations currently running or waiting to be started.
+     */
+    public boolean isAnimating() {
+        return mItemAnimator != null && mItemAnimator.isRunning();
+    }
+
+    void saveOldPositions() {
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (DEBUG && holder.mPosition == -1 && !holder.isRemoved()) {
+                throw new IllegalStateException("view holder cannot have position -1 unless it"
+                        + " is removed");
+            }
+            if (!holder.shouldIgnore()) {
+                holder.saveOldPosition();
+            }
+        }
+    }
+
+    void clearOldPositions() {
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (!holder.shouldIgnore()) {
+                holder.clearOldPosition();
+            }
+        }
+        mRecycler.clearOldPositions();
+    }
+
+    void offsetPositionRecordsForMove(int from, int to) {
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        final int start, end, inBetweenOffset;
+        if (from < to) {
+            start = from;
+            end = to;
+            inBetweenOffset = -1;
+        } else {
+            start = to;
+            end = from;
+            inBetweenOffset = 1;
+        }
+
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (holder == null || holder.mPosition < start || holder.mPosition > end) {
+                continue;
+            }
+            if (DEBUG) {
+                Log.d(TAG, "offsetPositionRecordsForMove attached child " + i + " holder "
+                        + holder);
+            }
+            if (holder.mPosition == from) {
+                holder.offsetPosition(to - from, false);
+            } else {
+                holder.offsetPosition(inBetweenOffset, false);
+            }
+
+            mState.mStructureChanged = true;
+        }
+        mRecycler.offsetPositionRecordsForMove(from, to);
+        requestLayout();
+    }
+
+    void offsetPositionRecordsForInsert(int positionStart, int itemCount) {
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (holder != null && !holder.shouldIgnore() && holder.mPosition >= positionStart) {
+                if (DEBUG) {
+                    Log.d(TAG, "offsetPositionRecordsForInsert attached child " + i + " holder "
+                            + holder + " now at position " + (holder.mPosition + itemCount));
+                }
+                holder.offsetPosition(itemCount, false);
+                mState.mStructureChanged = true;
+            }
+        }
+        mRecycler.offsetPositionRecordsForInsert(positionStart, itemCount);
+        requestLayout();
+    }
+
+    void offsetPositionRecordsForRemove(int positionStart, int itemCount,
+            boolean applyToPreLayout) {
+        final int positionEnd = positionStart + itemCount;
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (holder != null && !holder.shouldIgnore()) {
+                if (holder.mPosition >= positionEnd) {
+                    if (DEBUG) {
+                        Log.d(TAG, "offsetPositionRecordsForRemove attached child " + i
+                                + " holder " + holder + " now at position "
+                                + (holder.mPosition - itemCount));
+                    }
+                    holder.offsetPosition(-itemCount, applyToPreLayout);
+                    mState.mStructureChanged = true;
+                } else if (holder.mPosition >= positionStart) {
+                    if (DEBUG) {
+                        Log.d(TAG, "offsetPositionRecordsForRemove attached child " + i
+                                + " holder " + holder + " now REMOVED");
+                    }
+                    holder.flagRemovedAndOffsetPosition(positionStart - 1, -itemCount,
+                            applyToPreLayout);
+                    mState.mStructureChanged = true;
+                }
+            }
+        }
+        mRecycler.offsetPositionRecordsForRemove(positionStart, itemCount, applyToPreLayout);
+        requestLayout();
+    }
+
+    /**
+     * Rebind existing views for the given range, or create as needed.
+     *
+     * @param positionStart Adapter position to start at
+     * @param itemCount Number of views that must explicitly be rebound
+     */
+    void viewRangeUpdate(int positionStart, int itemCount, Object payload) {
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        final int positionEnd = positionStart + itemCount;
+
+        for (int i = 0; i < childCount; i++) {
+            final View child = mChildHelper.getUnfilteredChildAt(i);
+            final ViewHolder holder = getChildViewHolderInt(child);
+            if (holder == null || holder.shouldIgnore()) {
+                continue;
+            }
+            if (holder.mPosition >= positionStart && holder.mPosition < positionEnd) {
+                // We re-bind these view holders after pre-processing is complete so that
+                // ViewHolders have their final positions assigned.
+                holder.addFlags(ViewHolder.FLAG_UPDATE);
+                holder.addChangePayload(payload);
+                // lp cannot be null since we get ViewHolder from it.
+                ((LayoutParams) child.getLayoutParams()).mInsetsDirty = true;
+            }
+        }
+        mRecycler.viewRangeUpdate(positionStart, itemCount);
+    }
+
+    boolean canReuseUpdatedViewHolder(ViewHolder viewHolder) {
+        return mItemAnimator == null || mItemAnimator.canReuseUpdatedViewHolder(viewHolder,
+                viewHolder.getUnmodifiedPayloads());
+    }
+
+
+    /**
+     * Call this method to signal that *all* adapter content has changed (generally, because of
+     * swapAdapter, or notifyDataSetChanged), and that once layout occurs, all attached items should
+     * be discarded or animated. Note that this work is deferred because RecyclerView requires a
+     * layout to resolve non-incremental changes to the data set.
+     *
+     * Attached items are labeled as position unknown, and may no longer be cached.
+     *
+     * It is still possible for items to be prefetched while mDataSetHasChangedAfterLayout == true,
+     * so calling this method *must* be associated with marking the cache invalid, so that the
+     * only valid items that remain in the cache, once layout occurs, are prefetched items.
+     */
+    void setDataSetChangedAfterLayout() {
+        if (mDataSetHasChangedAfterLayout) {
+            return;
+        }
+        mDataSetHasChangedAfterLayout = true;
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (holder != null && !holder.shouldIgnore()) {
+                holder.addFlags(ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN);
+            }
+        }
+        mRecycler.setAdapterPositionsAsUnknown();
+
+        // immediately mark all views as invalid, so prefetched views can be
+        // differentiated from views bound to previous data set - both in children, and cache
+        markKnownViewsInvalid();
+    }
+
+    /**
+     * Mark all known views as invalid. Used in response to a, "the whole world might have changed"
+     * data change event.
+     */
+    void markKnownViewsInvalid() {
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (holder != null && !holder.shouldIgnore()) {
+                holder.addFlags(ViewHolder.FLAG_UPDATE | ViewHolder.FLAG_INVALID);
+            }
+        }
+        markItemDecorInsetsDirty();
+        mRecycler.markKnownViewsInvalid();
+    }
+
+    /**
+     * Invalidates all ItemDecorations. If RecyclerView has item decorations, calling this method
+     * will trigger a {@link #requestLayout()} call.
+     */
+    public void invalidateItemDecorations() {
+        if (mItemDecorations.size() == 0) {
+            return;
+        }
+        if (mLayout != null) {
+            mLayout.assertNotInLayoutOrScroll("Cannot invalidate item decorations during a scroll"
+                    + " or layout");
+        }
+        markItemDecorInsetsDirty();
+        requestLayout();
+    }
+
+    /**
+     * Returns true if the RecyclerView should attempt to preserve currently focused Adapter Item's
+     * focus even if the View representing the Item is replaced during a layout calculation.
+     * <p>
+     * By default, this value is {@code true}.
+     *
+     * @return True if the RecyclerView will try to preserve focused Item after a layout if it loses
+     * focus.
+     *
+     * @see #setPreserveFocusAfterLayout(boolean)
+     */
+    public boolean getPreserveFocusAfterLayout() {
+        return mPreserveFocusAfterLayout;
+    }
+
+    /**
+     * Set whether the RecyclerView should try to keep the same Item focused after a layout
+     * calculation or not.
+     * <p>
+     * Usually, LayoutManagers keep focused views visible before and after layout but sometimes,
+     * views may lose focus during a layout calculation as their state changes or they are replaced
+     * with another view due to type change or animation. In these cases, RecyclerView can request
+     * focus on the new view automatically.
+     *
+     * @param preserveFocusAfterLayout Whether RecyclerView should preserve focused Item during a
+     *                                 layout calculations. Defaults to true.
+     *
+     * @see #getPreserveFocusAfterLayout()
+     */
+    public void setPreserveFocusAfterLayout(boolean preserveFocusAfterLayout) {
+        mPreserveFocusAfterLayout = preserveFocusAfterLayout;
+    }
+
+    /**
+     * Retrieve the {@link ViewHolder} for the given child view.
+     *
+     * @param child Child of this RecyclerView to query for its ViewHolder
+     * @return The child view's ViewHolder
+     */
+    public ViewHolder getChildViewHolder(View child) {
+        final ViewParent parent = child.getParent();
+        if (parent != null && parent != this) {
+            throw new IllegalArgumentException("View " + child + " is not a direct child of "
+                    + this);
+        }
+        return getChildViewHolderInt(child);
+    }
+
+    /**
+     * Traverses the ancestors of the given view and returns the item view that contains it and
+     * also a direct child of the RecyclerView. This returned view can be used to get the
+     * ViewHolder by calling {@link #getChildViewHolder(View)}.
+     *
+     * @param view The view that is a descendant of the RecyclerView.
+     *
+     * @return The direct child of the RecyclerView which contains the given view or null if the
+     * provided view is not a descendant of this RecyclerView.
+     *
+     * @see #getChildViewHolder(View)
+     * @see #findContainingViewHolder(View)
+     */
+    @Nullable
+    public View findContainingItemView(View view) {
+        ViewParent parent = view.getParent();
+        while (parent != null && parent != this && parent instanceof View) {
+            view = (View) parent;
+            parent = view.getParent();
+        }
+        return parent == this ? view : null;
+    }
+
+    /**
+     * Returns the ViewHolder that contains the given view.
+     *
+     * @param view The view that is a descendant of the RecyclerView.
+     *
+     * @return The ViewHolder that contains the given view or null if the provided view is not a
+     * descendant of this RecyclerView.
+     */
+    @Nullable
+    public ViewHolder findContainingViewHolder(View view) {
+        View itemView = findContainingItemView(view);
+        return itemView == null ? null : getChildViewHolder(itemView);
+    }
+
+
+    static ViewHolder getChildViewHolderInt(View child) {
+        if (child == null) {
+            return null;
+        }
+        return ((LayoutParams) child.getLayoutParams()).mViewHolder;
+    }
+
+    /**
+     * @deprecated use {@link #getChildAdapterPosition(View)} or
+     * {@link #getChildLayoutPosition(View)}.
+     */
+    @Deprecated
+    public int getChildPosition(View child) {
+        return getChildAdapterPosition(child);
+    }
+
+    /**
+     * Return the adapter position that the given child view corresponds to.
+     *
+     * @param child Child View to query
+     * @return Adapter position corresponding to the given view or {@link #NO_POSITION}
+     */
+    public int getChildAdapterPosition(View child) {
+        final ViewHolder holder = getChildViewHolderInt(child);
+        return holder != null ? holder.getAdapterPosition() : NO_POSITION;
+    }
+
+    /**
+     * Return the adapter position of the given child view as of the latest completed layout pass.
+     * <p>
+     * This position may not be equal to Item's adapter position if there are pending changes
+     * in the adapter which have not been reflected to the layout yet.
+     *
+     * @param child Child View to query
+     * @return Adapter position of the given View as of last layout pass or {@link #NO_POSITION} if
+     * the View is representing a removed item.
+     */
+    public int getChildLayoutPosition(View child) {
+        final ViewHolder holder = getChildViewHolderInt(child);
+        return holder != null ? holder.getLayoutPosition() : NO_POSITION;
+    }
+
+    /**
+     * Return the stable item id that the given child view corresponds to.
+     *
+     * @param child Child View to query
+     * @return Item id corresponding to the given view or {@link #NO_ID}
+     */
+    public long getChildItemId(View child) {
+        if (mAdapter == null || !mAdapter.hasStableIds()) {
+            return NO_ID;
+        }
+        final ViewHolder holder = getChildViewHolderInt(child);
+        return holder != null ? holder.getItemId() : NO_ID;
+    }
+
+    /**
+     * @deprecated use {@link #findViewHolderForLayoutPosition(int)} or
+     * {@link #findViewHolderForAdapterPosition(int)}
+     */
+    @Deprecated
+    public ViewHolder findViewHolderForPosition(int position) {
+        return findViewHolderForPosition(position, false);
+    }
+
+    /**
+     * Return the ViewHolder for the item in the given position of the data set as of the latest
+     * layout pass.
+     * <p>
+     * This method checks only the children of RecyclerView. If the item at the given
+     * <code>position</code> is not laid out, it <em>will not</em> create a new one.
+     * <p>
+     * Note that when Adapter contents change, ViewHolder positions are not updated until the
+     * next layout calculation. If there are pending adapter updates, the return value of this
+     * method may not match your adapter contents. You can use
+     * #{@link ViewHolder#getAdapterPosition()} to get the current adapter position of a ViewHolder.
+     * <p>
+     * When the ItemAnimator is running a change animation, there might be 2 ViewHolders
+     * with the same layout position representing the same Item. In this case, the updated
+     * ViewHolder will be returned.
+     *
+     * @param position The position of the item in the data set of the adapter
+     * @return The ViewHolder at <code>position</code> or null if there is no such item
+     */
+    public ViewHolder findViewHolderForLayoutPosition(int position) {
+        return findViewHolderForPosition(position, false);
+    }
+
+    /**
+     * Return the ViewHolder for the item in the given position of the data set. Unlike
+     * {@link #findViewHolderForLayoutPosition(int)} this method takes into account any pending
+     * adapter changes that may not be reflected to the layout yet. On the other hand, if
+     * {@link Adapter#notifyDataSetChanged()} has been called but the new layout has not been
+     * calculated yet, this method will return <code>null</code> since the new positions of views
+     * are unknown until the layout is calculated.
+     * <p>
+     * This method checks only the children of RecyclerView. If the item at the given
+     * <code>position</code> is not laid out, it <em>will not</em> create a new one.
+     * <p>
+     * When the ItemAnimator is running a change animation, there might be 2 ViewHolders
+     * representing the same Item. In this case, the updated ViewHolder will be returned.
+     *
+     * @param position The position of the item in the data set of the adapter
+     * @return The ViewHolder at <code>position</code> or null if there is no such item
+     */
+    public ViewHolder findViewHolderForAdapterPosition(int position) {
+        if (mDataSetHasChangedAfterLayout) {
+            return null;
+        }
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        // hidden VHs are not preferred but if that is the only one we find, we rather return it
+        ViewHolder hidden = null;
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (holder != null && !holder.isRemoved()
+                    && getAdapterPositionFor(holder) == position) {
+                if (mChildHelper.isHidden(holder.itemView)) {
+                    hidden = holder;
+                } else {
+                    return holder;
+                }
+            }
+        }
+        return hidden;
+    }
+
+    ViewHolder findViewHolderForPosition(int position, boolean checkNewPosition) {
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        ViewHolder hidden = null;
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (holder != null && !holder.isRemoved()) {
+                if (checkNewPosition) {
+                    if (holder.mPosition != position) {
+                        continue;
+                    }
+                } else if (holder.getLayoutPosition() != position) {
+                    continue;
+                }
+                if (mChildHelper.isHidden(holder.itemView)) {
+                    hidden = holder;
+                } else {
+                    return holder;
+                }
+            }
+        }
+        // This method should not query cached views. It creates a problem during adapter updates
+        // when we are dealing with already laid out views. Also, for the public method, it is more
+        // reasonable to return null if position is not laid out.
+        return hidden;
+    }
+
+    /**
+     * Return the ViewHolder for the item with the given id. The RecyclerView must
+     * use an Adapter with {@link Adapter#setHasStableIds(boolean) stableIds} to
+     * return a non-null value.
+     * <p>
+     * This method checks only the children of RecyclerView. If the item with the given
+     * <code>id</code> is not laid out, it <em>will not</em> create a new one.
+     *
+     * When the ItemAnimator is running a change animation, there might be 2 ViewHolders with the
+     * same id. In this case, the updated ViewHolder will be returned.
+     *
+     * @param id The id for the requested item
+     * @return The ViewHolder with the given <code>id</code> or null if there is no such item
+     */
+    public ViewHolder findViewHolderForItemId(long id) {
+        if (mAdapter == null || !mAdapter.hasStableIds()) {
+            return null;
+        }
+        final int childCount = mChildHelper.getUnfilteredChildCount();
+        ViewHolder hidden = null;
+        for (int i = 0; i < childCount; i++) {
+            final ViewHolder holder = getChildViewHolderInt(mChildHelper.getUnfilteredChildAt(i));
+            if (holder != null && !holder.isRemoved() && holder.getItemId() == id) {
+                if (mChildHelper.isHidden(holder.itemView)) {
+                    hidden = holder;
+                } else {
+                    return holder;
+                }
+            }
+        }
+        return hidden;
+    }
+
+    /**
+     * Find the topmost view under the given point.
+     *
+     * @param x Horizontal position in pixels to search
+     * @param y Vertical position in pixels to search
+     * @return The child view under (x, y) or null if no matching child is found
+     */
+    public View findChildViewUnder(float x, float y) {
+        final int count = mChildHelper.getChildCount();
+        for (int i = count - 1; i >= 0; i--) {
+            final View child = mChildHelper.getChildAt(i);
+            final float translationX = child.getTranslationX();
+            final float translationY = child.getTranslationY();
+            if (x >= child.getLeft() + translationX
+                    && x <= child.getRight() + translationX
+                    && y >= child.getTop() + translationY
+                    && y <= child.getBottom() + translationY) {
+                return child;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean drawChild(Canvas canvas, View child, long drawingTime) {
+        return super.drawChild(canvas, child, drawingTime);
+    }
+
+    /**
+     * Offset the bounds of all child views by <code>dy</code> pixels.
+     * Useful for implementing simple scrolling in {@link LayoutManager LayoutManagers}.
+     *
+     * @param dy Vertical pixel offset to apply to the bounds of all child views
+     */
+    public void offsetChildrenVertical(int dy) {
+        final int childCount = mChildHelper.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            mChildHelper.getChildAt(i).offsetTopAndBottom(dy);
+        }
+    }
+
+    /**
+     * Called when an item view is attached to this RecyclerView.
+     *
+     * <p>Subclasses of RecyclerView may want to perform extra bookkeeping or modifications
+     * of child views as they become attached. This will be called before a
+     * {@link LayoutManager} measures or lays out the view and is a good time to perform these
+     * changes.</p>
+     *
+     * @param child Child view that is now attached to this RecyclerView and its associated window
+     */
+    public void onChildAttachedToWindow(View child) {
+    }
+
+    /**
+     * Called when an item view is detached from this RecyclerView.
+     *
+     * <p>Subclasses of RecyclerView may want to perform extra bookkeeping or modifications
+     * of child views as they become detached. This will be called as a
+     * {@link LayoutManager} fully detaches the child view from the parent and its window.</p>
+     *
+     * @param child Child view that is now detached from this RecyclerView and its associated window
+     */
+    public void onChildDetachedFromWindow(View child) {
+    }
+
+    /**
+     * Offset the bounds of all child views by <code>dx</code> pixels.
+     * Useful for implementing simple scrolling in {@link LayoutManager LayoutManagers}.
+     *
+     * @param dx Horizontal pixel offset to apply to the bounds of all child views
+     */
+    public void offsetChildrenHorizontal(int dx) {
+        final int childCount = mChildHelper.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            mChildHelper.getChildAt(i).offsetLeftAndRight(dx);
+        }
+    }
+
+    /**
+     * Returns the bounds of the view including its decoration and margins.
+     *
+     * @param view The view element to check
+     * @param outBounds A rect that will receive the bounds of the element including its
+     *                  decoration and margins.
+     */
+    public void getDecoratedBoundsWithMargins(View view, Rect outBounds) {
+        getDecoratedBoundsWithMarginsInt(view, outBounds);
+    }
+
+    static void getDecoratedBoundsWithMarginsInt(View view, Rect outBounds) {
+        final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+        final Rect insets = lp.mDecorInsets;
+        outBounds.set(view.getLeft() - insets.left - lp.leftMargin,
+                view.getTop() - insets.top - lp.topMargin,
+                view.getRight() + insets.right + lp.rightMargin,
+                view.getBottom() + insets.bottom + lp.bottomMargin);
+    }
+
+    Rect getItemDecorInsetsForChild(View child) {
+        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+        if (!lp.mInsetsDirty) {
+            return lp.mDecorInsets;
+        }
+
+        if (mState.isPreLayout() && (lp.isItemChanged() || lp.isViewInvalid())) {
+            // changed/invalid items should not be updated until they are rebound.
+            return lp.mDecorInsets;
+        }
+        final Rect insets = lp.mDecorInsets;
+        insets.set(0, 0, 0, 0);
+        final int decorCount = mItemDecorations.size();
+        for (int i = 0; i < decorCount; i++) {
+            mTempRect.set(0, 0, 0, 0);
+            mItemDecorations.get(i).getItemOffsets(mTempRect, child, this, mState);
+            insets.left += mTempRect.left;
+            insets.top += mTempRect.top;
+            insets.right += mTempRect.right;
+            insets.bottom += mTempRect.bottom;
+        }
+        lp.mInsetsDirty = false;
+        return insets;
+    }
+
+    /**
+     * Called when the scroll position of this RecyclerView changes. Subclasses should use
+     * this method to respond to scrolling within the adapter's data set instead of an explicit
+     * listener.
+     *
+     * <p>This method will always be invoked before listeners. If a subclass needs to perform
+     * any additional upkeep or bookkeeping after scrolling but before listeners run,
+     * this is a good place to do so.</p>
+     *
+     * <p>This differs from {@link View#onScrollChanged(int, int, int, int)} in that it receives
+     * the distance scrolled in either direction within the adapter's data set instead of absolute
+     * scroll coordinates. Since RecyclerView cannot compute the absolute scroll position from
+     * any arbitrary point in the data set, <code>onScrollChanged</code> will always receive
+     * the current {@link View#getScrollX()} and {@link View#getScrollY()} values which
+     * do not correspond to the data set scroll position. However, some subclasses may choose
+     * to use these fields as special offsets.</p>
+     *
+     * @param dx horizontal distance scrolled in pixels
+     * @param dy vertical distance scrolled in pixels
+     */
+    public void onScrolled(int dx, int dy) {
+        // Do nothing
+    }
+
+    void dispatchOnScrolled(int hresult, int vresult) {
+        mDispatchScrollCounter++;
+        // Pass the current scrollX/scrollY values; no actual change in these properties occurred
+        // but some general-purpose code may choose to respond to changes this way.
+        final int scrollX = getScrollX();
+        final int scrollY = getScrollY();
+        onScrollChanged(scrollX, scrollY, scrollX, scrollY);
+
+        // Pass the real deltas to onScrolled, the RecyclerView-specific method.
+        onScrolled(hresult, vresult);
+
+        // Invoke listeners last. Subclassed view methods always handle the event first.
+        // All internal state is consistent by the time listeners are invoked.
+        if (mScrollListener != null) {
+            mScrollListener.onScrolled(this, hresult, vresult);
+        }
+        if (mScrollListeners != null) {
+            for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
+                mScrollListeners.get(i).onScrolled(this, hresult, vresult);
+            }
+        }
+        mDispatchScrollCounter--;
+    }
+
+    /**
+     * Called when the scroll state of this RecyclerView changes. Subclasses should use this
+     * method to respond to state changes instead of an explicit listener.
+     *
+     * <p>This method will always be invoked before listeners, but after the LayoutManager
+     * responds to the scroll state change.</p>
+     *
+     * @param state the new scroll state, one of {@link #SCROLL_STATE_IDLE},
+     *              {@link #SCROLL_STATE_DRAGGING} or {@link #SCROLL_STATE_SETTLING}
+     */
+    public void onScrollStateChanged(int state) {
+        // Do nothing
+    }
+
+    void dispatchOnScrollStateChanged(int state) {
+        // Let the LayoutManager go first; this allows it to bring any properties into
+        // a consistent state before the RecyclerView subclass responds.
+        if (mLayout != null) {
+            mLayout.onScrollStateChanged(state);
+        }
+
+        // Let the RecyclerView subclass handle this event next; any LayoutManager property
+        // changes will be reflected by this time.
+        onScrollStateChanged(state);
+
+        // Listeners go last. All other internal state is consistent by this point.
+        if (mScrollListener != null) {
+            mScrollListener.onScrollStateChanged(this, state);
+        }
+        if (mScrollListeners != null) {
+            for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
+                mScrollListeners.get(i).onScrollStateChanged(this, state);
+            }
+        }
+    }
+
+    /**
+     * Returns whether there are pending adapter updates which are not yet applied to the layout.
+     * <p>
+     * If this method returns <code>true</code>, it means that what user is currently seeing may not
+     * reflect them adapter contents (depending on what has changed).
+     * You may use this information to defer or cancel some operations.
+     * <p>
+     * This method returns true if RecyclerView has not yet calculated the first layout after it is
+     * attached to the Window or the Adapter has been replaced.
+     *
+     * @return True if there are some adapter updates which are not yet reflected to layout or false
+     * if layout is up to date.
+     */
+    public boolean hasPendingAdapterUpdates() {
+        return !mFirstLayoutComplete || mDataSetHasChangedAfterLayout
+                || mAdapterHelper.hasPendingUpdates();
+    }
+
+    class ViewFlinger implements Runnable {
+        private int mLastFlingX;
+        private int mLastFlingY;
+        private OverScroller mScroller;
+        Interpolator mInterpolator = sQuinticInterpolator;
+
+
+        // When set to true, postOnAnimation callbacks are delayed until the run method completes
+        private boolean mEatRunOnAnimationRequest = false;
+
+        // Tracks if postAnimationCallback should be re-attached when it is done
+        private boolean mReSchedulePostAnimationCallback = false;
+
+        ViewFlinger() {
+            mScroller = new OverScroller(getContext(), sQuinticInterpolator);
+        }
+
+        @Override
+        public void run() {
+            if (mLayout == null) {
+                stop();
+                return; // no layout, cannot scroll.
+            }
+            disableRunOnAnimationRequests();
+            consumePendingUpdateOperations();
+            // keep a local reference so that if it is changed during onAnimation method, it won't
+            // cause unexpected behaviors
+            final OverScroller scroller = mScroller;
+            final SmoothScroller smoothScroller = mLayout.mSmoothScroller;
+            if (scroller.computeScrollOffset()) {
+                final int x = scroller.getCurrX();
+                final int y = scroller.getCurrY();
+                final int dx = x - mLastFlingX;
+                final int dy = y - mLastFlingY;
+                int hresult = 0;
+                int vresult = 0;
+                mLastFlingX = x;
+                mLastFlingY = y;
+                int overscrollX = 0, overscrollY = 0;
+                if (mAdapter != null) {
+                    eatRequestLayout();
+                    onEnterLayoutOrScroll();
+                    Trace.beginSection(TRACE_SCROLL_TAG);
+                    if (dx != 0) {
+                        hresult = mLayout.scrollHorizontallyBy(dx, mRecycler, mState);
+                        overscrollX = dx - hresult;
+                    }
+                    if (dy != 0) {
+                        vresult = mLayout.scrollVerticallyBy(dy, mRecycler, mState);
+                        overscrollY = dy - vresult;
+                    }
+                    Trace.endSection();
+                    repositionShadowingViews();
+
+                    onExitLayoutOrScroll();
+                    resumeRequestLayout(false);
+
+                    if (smoothScroller != null && !smoothScroller.isPendingInitialRun()
+                            && smoothScroller.isRunning()) {
+                        final int adapterSize = mState.getItemCount();
+                        if (adapterSize == 0) {
+                            smoothScroller.stop();
+                        } else if (smoothScroller.getTargetPosition() >= adapterSize) {
+                            smoothScroller.setTargetPosition(adapterSize - 1);
+                            smoothScroller.onAnimation(dx - overscrollX, dy - overscrollY);
+                        } else {
+                            smoothScroller.onAnimation(dx - overscrollX, dy - overscrollY);
+                        }
+                    }
+                }
+                if (!mItemDecorations.isEmpty()) {
+                    invalidate();
+                }
+                if (getOverScrollMode() != View.OVER_SCROLL_NEVER) {
+                    considerReleasingGlowsOnScroll(dx, dy);
+                }
+                if (overscrollX != 0 || overscrollY != 0) {
+                    final int vel = (int) scroller.getCurrVelocity();
+
+                    int velX = 0;
+                    if (overscrollX != x) {
+                        velX = overscrollX < 0 ? -vel : overscrollX > 0 ? vel : 0;
+                    }
+
+                    int velY = 0;
+                    if (overscrollY != y) {
+                        velY = overscrollY < 0 ? -vel : overscrollY > 0 ? vel : 0;
+                    }
+
+                    if (getOverScrollMode() != View.OVER_SCROLL_NEVER) {
+                        absorbGlows(velX, velY);
+                    }
+                    if ((velX != 0 || overscrollX == x || scroller.getFinalX() == 0)
+                            && (velY != 0 || overscrollY == y || scroller.getFinalY() == 0)) {
+                        scroller.abortAnimation();
+                    }
+                }
+                if (hresult != 0 || vresult != 0) {
+                    dispatchOnScrolled(hresult, vresult);
+                }
+
+                if (!awakenScrollBars()) {
+                    invalidate();
+                }
+
+                final boolean fullyConsumedVertical = dy != 0 && mLayout.canScrollVertically()
+                        && vresult == dy;
+                final boolean fullyConsumedHorizontal = dx != 0 && mLayout.canScrollHorizontally()
+                        && hresult == dx;
+                final boolean fullyConsumedAny = (dx == 0 && dy == 0) || fullyConsumedHorizontal
+                        || fullyConsumedVertical;
+
+                if (scroller.isFinished() || !fullyConsumedAny) {
+                    setScrollState(SCROLL_STATE_IDLE); // setting state to idle will stop this.
+                    if (ALLOW_THREAD_GAP_WORK) {
+                        mPrefetchRegistry.clearPrefetchPositions();
+                    }
+                } else {
+                    postOnAnimation();
+                    if (mGapWorker != null) {
+                        mGapWorker.postFromTraversal(RecyclerView.this, dx, dy);
+                    }
+                }
+            }
+            // call this after the onAnimation is complete not to have inconsistent callbacks etc.
+            if (smoothScroller != null) {
+                if (smoothScroller.isPendingInitialRun()) {
+                    smoothScroller.onAnimation(0, 0);
+                }
+                if (!mReSchedulePostAnimationCallback) {
+                    smoothScroller.stop(); //stop if it does not trigger any scroll
+                }
+            }
+            enableRunOnAnimationRequests();
+        }
+
+        private void disableRunOnAnimationRequests() {
+            mReSchedulePostAnimationCallback = false;
+            mEatRunOnAnimationRequest = true;
+        }
+
+        private void enableRunOnAnimationRequests() {
+            mEatRunOnAnimationRequest = false;
+            if (mReSchedulePostAnimationCallback) {
+                postOnAnimation();
+            }
+        }
+
+        void postOnAnimation() {
+            if (mEatRunOnAnimationRequest) {
+                mReSchedulePostAnimationCallback = true;
+            } else {
+                removeCallbacks(this);
+                RecyclerView.this.postOnAnimation(this);
+            }
+        }
+
+        public void fling(int velocityX, int velocityY) {
+            setScrollState(SCROLL_STATE_SETTLING);
+            mLastFlingX = mLastFlingY = 0;
+            mScroller.fling(0, 0, velocityX, velocityY,
+                    Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE);
+            postOnAnimation();
+        }
+
+        public void smoothScrollBy(int dx, int dy) {
+            smoothScrollBy(dx, dy, 0, 0);
+        }
+
+        public void smoothScrollBy(int dx, int dy, int vx, int vy) {
+            smoothScrollBy(dx, dy, computeScrollDuration(dx, dy, vx, vy));
+        }
+
+        private float distanceInfluenceForSnapDuration(float f) {
+            f -= 0.5f; // center the values about 0.
+            f *= 0.3f * Math.PI / 2.0f;
+            return (float) Math.sin(f);
+        }
+
+        private int computeScrollDuration(int dx, int dy, int vx, int vy) {
+            final int absDx = Math.abs(dx);
+            final int absDy = Math.abs(dy);
+            final boolean horizontal = absDx > absDy;
+            final int velocity = (int) Math.sqrt(vx * vx + vy * vy);
+            final int delta = (int) Math.sqrt(dx * dx + dy * dy);
+            final int containerSize = horizontal ? getWidth() : getHeight();
+            final int halfContainerSize = containerSize / 2;
+            final float distanceRatio = Math.min(1.f, 1.f * delta / containerSize);
+            final float distance = halfContainerSize + halfContainerSize
+                    * distanceInfluenceForSnapDuration(distanceRatio);
+
+            final int duration;
+            if (velocity > 0) {
+                duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
+            } else {
+                float absDelta = (float) (horizontal ? absDx : absDy);
+                duration = (int) (((absDelta / containerSize) + 1) * 300);
+            }
+            return Math.min(duration, MAX_SCROLL_DURATION);
+        }
+
+        public void smoothScrollBy(int dx, int dy, int duration) {
+            smoothScrollBy(dx, dy, duration, sQuinticInterpolator);
+        }
+
+        public void smoothScrollBy(int dx, int dy, Interpolator interpolator) {
+            smoothScrollBy(dx, dy, computeScrollDuration(dx, dy, 0, 0),
+                    interpolator == null ? sQuinticInterpolator : interpolator);
+        }
+
+        public void smoothScrollBy(int dx, int dy, int duration, Interpolator interpolator) {
+            if (mInterpolator != interpolator) {
+                mInterpolator = interpolator;
+                mScroller = new OverScroller(getContext(), interpolator);
+            }
+            setScrollState(SCROLL_STATE_SETTLING);
+            mLastFlingX = mLastFlingY = 0;
+            mScroller.startScroll(0, 0, dx, dy, duration);
+            postOnAnimation();
+        }
+
+        public void stop() {
+            removeCallbacks(this);
+            mScroller.abortAnimation();
+        }
+
+    }
+
+    void repositionShadowingViews() {
+        // Fix up shadow views used by change animations
+        int count = mChildHelper.getChildCount();
+        for (int i = 0; i < count; i++) {
+            View view = mChildHelper.getChildAt(i);
+            ViewHolder holder = getChildViewHolder(view);
+            if (holder != null && holder.mShadowingHolder != null) {
+                View shadowingView = holder.mShadowingHolder.itemView;
+                int left = view.getLeft();
+                int top = view.getTop();
+                if (left != shadowingView.getLeft() ||  top != shadowingView.getTop()) {
+                    shadowingView.layout(left, top,
+                            left + shadowingView.getWidth(),
+                            top + shadowingView.getHeight());
+                }
+            }
+        }
+    }
+
+    private class RecyclerViewDataObserver extends AdapterDataObserver {
+        RecyclerViewDataObserver() {
+        }
+
+        @Override
+        public void onChanged() {
+            assertNotInLayoutOrScroll(null);
+            mState.mStructureChanged = true;
+
+            setDataSetChangedAfterLayout();
+            if (!mAdapterHelper.hasPendingUpdates()) {
+                requestLayout();
+            }
+        }
+
+        @Override
+        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
+            assertNotInLayoutOrScroll(null);
+            if (mAdapterHelper.onItemRangeChanged(positionStart, itemCount, payload)) {
+                triggerUpdateProcessor();
+            }
+        }
+
+        @Override
+        public void onItemRangeInserted(int positionStart, int itemCount) {
+            assertNotInLayoutOrScroll(null);
+            if (mAdapterHelper.onItemRangeInserted(positionStart, itemCount)) {
+                triggerUpdateProcessor();
+            }
+        }
+
+        @Override
+        public void onItemRangeRemoved(int positionStart, int itemCount) {
+            assertNotInLayoutOrScroll(null);
+            if (mAdapterHelper.onItemRangeRemoved(positionStart, itemCount)) {
+                triggerUpdateProcessor();
+            }
+        }
+
+        @Override
+        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+            assertNotInLayoutOrScroll(null);
+            if (mAdapterHelper.onItemRangeMoved(fromPosition, toPosition, itemCount)) {
+                triggerUpdateProcessor();
+            }
+        }
+
+        void triggerUpdateProcessor() {
+            if (POST_UPDATES_ON_ANIMATION && mHasFixedSize && mIsAttached) {
+                RecyclerView.this.postOnAnimation(mUpdateChildViewsRunnable);
+            } else {
+                mAdapterUpdateDuringMeasure = true;
+                requestLayout();
+            }
+        }
+    }
+
+    /**
+     * RecycledViewPool lets you share Views between multiple RecyclerViews.
+     * <p>
+     * If you want to recycle views across RecyclerViews, create an instance of RecycledViewPool
+     * and use {@link RecyclerView#setRecycledViewPool(RecycledViewPool)}.
+     * <p>
+     * RecyclerView automatically creates a pool for itself if you don't provide one.
+     *
+     */
+    public static class RecycledViewPool {
+        private static final int DEFAULT_MAX_SCRAP = 5;
+
+        /**
+         * Tracks both pooled holders, as well as create/bind timing metadata for the given type.
+         *
+         * Note that this tracks running averages of create/bind time across all RecyclerViews
+         * (and, indirectly, Adapters) that use this pool.
+         *
+         * 1) This enables us to track average create and bind times across multiple adapters. Even
+         * though create (and especially bind) may behave differently for different Adapter
+         * subclasses, sharing the pool is a strong signal that they'll perform similarly, per type.
+         *
+         * 2) If {@link #willBindInTime(int, long, long)} returns false for one view, it will return
+         * false for all other views of its type for the same deadline. This prevents items
+         * constructed by {@link GapWorker} prefetch from being bound to a lower priority prefetch.
+         */
+        static class ScrapData {
+            ArrayList<ViewHolder> mScrapHeap = new ArrayList<>();
+            int mMaxScrap = DEFAULT_MAX_SCRAP;
+            long mCreateRunningAverageNs = 0;
+            long mBindRunningAverageNs = 0;
+        }
+        SparseArray<ScrapData> mScrap = new SparseArray<>();
+
+        private int mAttachCount = 0;
+
+        public void clear() {
+            for (int i = 0; i < mScrap.size(); i++) {
+                ScrapData data = mScrap.valueAt(i);
+                data.mScrapHeap.clear();
+            }
+        }
+
+        public void setMaxRecycledViews(int viewType, int max) {
+            ScrapData scrapData = getScrapDataForType(viewType);
+            scrapData.mMaxScrap = max;
+            final ArrayList<ViewHolder> scrapHeap = scrapData.mScrapHeap;
+            if (scrapHeap != null) {
+                while (scrapHeap.size() > max) {
+                    scrapHeap.remove(scrapHeap.size() - 1);
+                }
+            }
+        }
+
+        /**
+         * Returns the current number of Views held by the RecycledViewPool of the given view type.
+         */
+        public int getRecycledViewCount(int viewType) {
+            return getScrapDataForType(viewType).mScrapHeap.size();
+        }
+
+        public ViewHolder getRecycledView(int viewType) {
+            final ScrapData scrapData = mScrap.get(viewType);
+            if (scrapData != null && !scrapData.mScrapHeap.isEmpty()) {
+                final ArrayList<ViewHolder> scrapHeap = scrapData.mScrapHeap;
+                return scrapHeap.remove(scrapHeap.size() - 1);
+            }
+            return null;
+        }
+
+        int size() {
+            int count = 0;
+            for (int i = 0; i < mScrap.size(); i++) {
+                ArrayList<ViewHolder> viewHolders = mScrap.valueAt(i).mScrapHeap;
+                if (viewHolders != null) {
+                    count += viewHolders.size();
+                }
+            }
+            return count;
+        }
+
+        public void putRecycledView(ViewHolder scrap) {
+            final int viewType = scrap.getItemViewType();
+            final ArrayList scrapHeap = getScrapDataForType(viewType).mScrapHeap;
+            if (mScrap.get(viewType).mMaxScrap <= scrapHeap.size()) {
+                return;
+            }
+            if (DEBUG && scrapHeap.contains(scrap)) {
+                throw new IllegalArgumentException("this scrap item already exists");
+            }
+            scrap.resetInternal();
+            scrapHeap.add(scrap);
+        }
+
+        long runningAverage(long oldAverage, long newValue) {
+            if (oldAverage == 0) {
+                return newValue;
+            }
+            return (oldAverage / 4 * 3) + (newValue / 4);
+        }
+
+        void factorInCreateTime(int viewType, long createTimeNs) {
+            ScrapData scrapData = getScrapDataForType(viewType);
+            scrapData.mCreateRunningAverageNs = runningAverage(
+                    scrapData.mCreateRunningAverageNs, createTimeNs);
+        }
+
+        void factorInBindTime(int viewType, long bindTimeNs) {
+            ScrapData scrapData = getScrapDataForType(viewType);
+            scrapData.mBindRunningAverageNs = runningAverage(
+                    scrapData.mBindRunningAverageNs, bindTimeNs);
+        }
+
+        boolean willCreateInTime(int viewType, long approxCurrentNs, long deadlineNs) {
+            long expectedDurationNs = getScrapDataForType(viewType).mCreateRunningAverageNs;
+            return expectedDurationNs == 0 || (approxCurrentNs + expectedDurationNs < deadlineNs);
+        }
+
+        boolean willBindInTime(int viewType, long approxCurrentNs, long deadlineNs) {
+            long expectedDurationNs = getScrapDataForType(viewType).mBindRunningAverageNs;
+            return expectedDurationNs == 0 || (approxCurrentNs + expectedDurationNs < deadlineNs);
+        }
+
+        void attach(Adapter adapter) {
+            mAttachCount++;
+        }
+
+        void detach() {
+            mAttachCount--;
+        }
+
+
+        /**
+         * Detaches the old adapter and attaches the new one.
+         * <p>
+         * RecycledViewPool will clear its cache if it has only one adapter attached and the new
+         * adapter uses a different ViewHolder than the oldAdapter.
+         *
+         * @param oldAdapter The previous adapter instance. Will be detached.
+         * @param newAdapter The new adapter instance. Will be attached.
+         * @param compatibleWithPrevious True if both oldAdapter and newAdapter are using the same
+         *                               ViewHolder and view types.
+         */
+        void onAdapterChanged(Adapter oldAdapter, Adapter newAdapter,
+                boolean compatibleWithPrevious) {
+            if (oldAdapter != null) {
+                detach();
+            }
+            if (!compatibleWithPrevious && mAttachCount == 0) {
+                clear();
+            }
+            if (newAdapter != null) {
+                attach(newAdapter);
+            }
+        }
+
+        private ScrapData getScrapDataForType(int viewType) {
+            ScrapData scrapData = mScrap.get(viewType);
+            if (scrapData == null) {
+                scrapData = new ScrapData();
+                mScrap.put(viewType, scrapData);
+            }
+            return scrapData;
+        }
+    }
+
+    /**
+     * Utility method for finding an internal RecyclerView, if present
+     */
+    @Nullable
+    static RecyclerView findNestedRecyclerView(@NonNull View view) {
+        if (!(view instanceof ViewGroup)) {
+            return null;
+        }
+        if (view instanceof RecyclerView) {
+            return (RecyclerView) view;
+        }
+        final ViewGroup parent = (ViewGroup) view;
+        final int count = parent.getChildCount();
+        for (int i = 0; i < count; i++) {
+            final View child = parent.getChildAt(i);
+            final RecyclerView descendant = findNestedRecyclerView(child);
+            if (descendant != null) {
+                return descendant;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Utility method for clearing holder's internal RecyclerView, if present
+     */
+    static void clearNestedRecyclerViewIfNotNested(@NonNull ViewHolder holder) {
+        if (holder.mNestedRecyclerView != null) {
+            View item = holder.mNestedRecyclerView.get();
+            while (item != null) {
+                if (item == holder.itemView) {
+                    return; // match found, don't need to clear
+                }
+
+                ViewParent parent = item.getParent();
+                if (parent instanceof View) {
+                    item = (View) parent;
+                } else {
+                    item = null;
+                }
+            }
+            holder.mNestedRecyclerView = null; // not nested
+        }
+    }
+
+    /**
+     * Time base for deadline-aware work scheduling. Overridable for testing.
+     *
+     * Will return 0 to avoid cost of System.nanoTime where deadline-aware work scheduling
+     * isn't relevant.
+     */
+    long getNanoTime() {
+        if (ALLOW_THREAD_GAP_WORK) {
+            return System.nanoTime();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * A Recycler is responsible for managing scrapped or detached item views for reuse.
+     *
+     * <p>A "scrapped" view is a view that is still attached to its parent RecyclerView but
+     * that has been marked for removal or reuse.</p>
+     *
+     * <p>Typical use of a Recycler by a {@link LayoutManager} will be to obtain views for
+     * an adapter's data set representing the data at a given position or item ID.
+     * If the view to be reused is considered "dirty" the adapter will be asked to rebind it.
+     * If not, the view can be quickly reused by the LayoutManager with no further work.
+     * Clean views that have not {@link android.view.View#isLayoutRequested() requested layout}
+     * may be repositioned by a LayoutManager without remeasurement.</p>
+     */
+    public final class Recycler {
+        final ArrayList<ViewHolder> mAttachedScrap = new ArrayList<>();
+        ArrayList<ViewHolder> mChangedScrap = null;
+
+        final ArrayList<ViewHolder> mCachedViews = new ArrayList<ViewHolder>();
+
+        private final List<ViewHolder>
+                mUnmodifiableAttachedScrap = Collections.unmodifiableList(mAttachedScrap);
+
+        private int mRequestedCacheMax = DEFAULT_CACHE_SIZE;
+        int mViewCacheMax = DEFAULT_CACHE_SIZE;
+
+        RecycledViewPool mRecyclerPool;
+
+        private ViewCacheExtension mViewCacheExtension;
+
+        static final int DEFAULT_CACHE_SIZE = 2;
+
+        /**
+         * Clear scrap views out of this recycler. Detached views contained within a
+         * recycled view pool will remain.
+         */
+        public void clear() {
+            mAttachedScrap.clear();
+            recycleAndClearCachedViews();
+        }
+
+        /**
+         * Set the maximum number of detached, valid views we should retain for later use.
+         *
+         * @param viewCount Number of views to keep before sending views to the shared pool
+         */
+        public void setViewCacheSize(int viewCount) {
+            mRequestedCacheMax = viewCount;
+            updateViewCacheSize();
+        }
+
+        void updateViewCacheSize() {
+            int extraCache = mLayout != null ? mLayout.mPrefetchMaxCountObserved : 0;
+            mViewCacheMax = mRequestedCacheMax + extraCache;
+
+            // first, try the views that can be recycled
+            for (int i = mCachedViews.size() - 1;
+                    i >= 0 && mCachedViews.size() > mViewCacheMax; i--) {
+                recycleCachedViewAt(i);
+            }
+        }
+
+        /**
+         * Returns an unmodifiable list of ViewHolders that are currently in the scrap list.
+         *
+         * @return List of ViewHolders in the scrap list.
+         */
+        public List<ViewHolder> getScrapList() {
+            return mUnmodifiableAttachedScrap;
+        }
+
+        /**
+         * Helper method for getViewForPosition.
+         * <p>
+         * Checks whether a given view holder can be used for the provided position.
+         *
+         * @param holder ViewHolder
+         * @return true if ViewHolder matches the provided position, false otherwise
+         */
+        boolean validateViewHolderForOffsetPosition(ViewHolder holder) {
+            // if it is a removed holder, nothing to verify since we cannot ask adapter anymore
+            // if it is not removed, verify the type and id.
+            if (holder.isRemoved()) {
+                if (DEBUG && !mState.isPreLayout()) {
+                    throw new IllegalStateException("should not receive a removed view unless it"
+                            + " is pre layout");
+                }
+                return mState.isPreLayout();
+            }
+            if (holder.mPosition < 0 || holder.mPosition >= mAdapter.getItemCount()) {
+                throw new IndexOutOfBoundsException("Inconsistency detected. Invalid view holder "
+                        + "adapter position" + holder);
+            }
+            if (!mState.isPreLayout()) {
+                // don't check type if it is pre-layout.
+                final int type = mAdapter.getItemViewType(holder.mPosition);
+                if (type != holder.getItemViewType()) {
+                    return false;
+                }
+            }
+            if (mAdapter.hasStableIds()) {
+                return holder.getItemId() == mAdapter.getItemId(holder.mPosition);
+            }
+            return true;
+        }
+
+        /**
+         * Attempts to bind view, and account for relevant timing information. If
+         * deadlineNs != FOREVER_NS, this method may fail to bind, and return false.
+         *
+         * @param holder Holder to be bound.
+         * @param offsetPosition Position of item to be bound.
+         * @param position Pre-layout position of item to be bound.
+         * @param deadlineNs Time, relative to getNanoTime(), by which bind/create work should
+         *                   complete. If FOREVER_NS is passed, this method will not fail to
+         *                   bind the holder.
+         * @return
+         */
+        private boolean tryBindViewHolderByDeadline(ViewHolder holder, int offsetPosition,
+                int position, long deadlineNs) {
+            holder.mOwnerRecyclerView = RecyclerView.this;
+            final int viewType = holder.getItemViewType();
+            long startBindNs = getNanoTime();
+            if (deadlineNs != FOREVER_NS
+                    && !mRecyclerPool.willBindInTime(viewType, startBindNs, deadlineNs)) {
+                // abort - we have a deadline we can't meet
+                return false;
+            }
+            mAdapter.bindViewHolder(holder, offsetPosition);
+            long endBindNs = getNanoTime();
+            mRecyclerPool.factorInBindTime(holder.getItemViewType(), endBindNs - startBindNs);
+            attachAccessibilityDelegate(holder.itemView);
+            if (mState.isPreLayout()) {
+                holder.mPreLayoutPosition = position;
+            }
+            return true;
+        }
+
+        /**
+         * Binds the given View to the position. The View can be a View previously retrieved via
+         * {@link #getViewForPosition(int)} or created by
+         * {@link Adapter#onCreateViewHolder(ViewGroup, int)}.
+         * <p>
+         * Generally, a LayoutManager should acquire its views via {@link #getViewForPosition(int)}
+         * and let the RecyclerView handle caching. This is a helper method for LayoutManager who
+         * wants to handle its own recycling logic.
+         * <p>
+         * Note that, {@link #getViewForPosition(int)} already binds the View to the position so
+         * you don't need to call this method unless you want to bind this View to another position.
+         *
+         * @param view The view to update.
+         * @param position The position of the item to bind to this View.
+         */
+        public void bindViewToPosition(View view, int position) {
+            ViewHolder holder = getChildViewHolderInt(view);
+            if (holder == null) {
+                throw new IllegalArgumentException("The view does not have a ViewHolder. You cannot"
+                        + " pass arbitrary views to this method, they should be created by the "
+                        + "Adapter");
+            }
+            final int offsetPosition = mAdapterHelper.findPositionOffset(position);
+            if (offsetPosition < 0 || offsetPosition >= mAdapter.getItemCount()) {
+                throw new IndexOutOfBoundsException("Inconsistency detected. Invalid item "
+                        + "position " + position + "(offset:" + offsetPosition + ")."
+                        + "state:" + mState.getItemCount());
+            }
+            tryBindViewHolderByDeadline(holder, offsetPosition, position, FOREVER_NS);
+
+            final ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
+            final LayoutParams rvLayoutParams;
+            if (lp == null) {
+                rvLayoutParams = (LayoutParams) generateDefaultLayoutParams();
+                holder.itemView.setLayoutParams(rvLayoutParams);
+            } else if (!checkLayoutParams(lp)) {
+                rvLayoutParams = (LayoutParams) generateLayoutParams(lp);
+                holder.itemView.setLayoutParams(rvLayoutParams);
+            } else {
+                rvLayoutParams = (LayoutParams) lp;
+            }
+
+            rvLayoutParams.mInsetsDirty = true;
+            rvLayoutParams.mViewHolder = holder;
+            rvLayoutParams.mPendingInvalidate = holder.itemView.getParent() == null;
+        }
+
+        /**
+         * RecyclerView provides artificial position range (item count) in pre-layout state and
+         * automatically maps these positions to {@link Adapter} positions when
+         * {@link #getViewForPosition(int)} or {@link #bindViewToPosition(View, int)} is called.
+         * <p>
+         * Usually, LayoutManager does not need to worry about this. However, in some cases, your
+         * LayoutManager may need to call some custom component with item positions in which
+         * case you need the actual adapter position instead of the pre layout position. You
+         * can use this method to convert a pre-layout position to adapter (post layout) position.
+         * <p>
+         * Note that if the provided position belongs to a deleted ViewHolder, this method will
+         * return -1.
+         * <p>
+         * Calling this method in post-layout state returns the same value back.
+         *
+         * @param position The pre-layout position to convert. Must be greater or equal to 0 and
+         *                 less than {@link State#getItemCount()}.
+         */
+        public int convertPreLayoutPositionToPostLayout(int position) {
+            if (position < 0 || position >= mState.getItemCount()) {
+                throw new IndexOutOfBoundsException("invalid position " + position + ". State "
+                        + "item count is " + mState.getItemCount());
+            }
+            if (!mState.isPreLayout()) {
+                return position;
+            }
+            return mAdapterHelper.findPositionOffset(position);
+        }
+
+        /**
+         * Obtain a view initialized for the given position.
+         *
+         * This method should be used by {@link LayoutManager} implementations to obtain
+         * views to represent data from an {@link Adapter}.
+         * <p>
+         * The Recycler may reuse a scrap or detached view from a shared pool if one is
+         * available for the correct view type. If the adapter has not indicated that the
+         * data at the given position has changed, the Recycler will attempt to hand back
+         * a scrap view that was previously initialized for that data without rebinding.
+         *
+         * @param position Position to obtain a view for
+         * @return A view representing the data at <code>position</code> from <code>adapter</code>
+         */
+        public View getViewForPosition(int position) {
+            return getViewForPosition(position, false);
+        }
+
+        View getViewForPosition(int position, boolean dryRun) {
+            return tryGetViewHolderForPositionByDeadline(position, dryRun, FOREVER_NS).itemView;
+        }
+
+        /**
+         * Attempts to get the ViewHolder for the given position, either from the Recycler scrap,
+         * cache, the RecycledViewPool, or creating it directly.
+         * <p>
+         * If a deadlineNs other than {@link #FOREVER_NS} is passed, this method early return
+         * rather than constructing or binding a ViewHolder if it doesn't think it has time.
+         * If a ViewHolder must be constructed and not enough time remains, null is returned. If a
+         * ViewHolder is aquired and must be bound but not enough time remains, an unbound holder is
+         * returned. Use {@link ViewHolder#isBound()} on the returned object to check for this.
+         *
+         * @param position Position of ViewHolder to be returned.
+         * @param dryRun True if the ViewHolder should not be removed from scrap/cache/
+         * @param deadlineNs Time, relative to getNanoTime(), by which bind/create work should
+         *                   complete. If FOREVER_NS is passed, this method will not fail to
+         *                   create/bind the holder if needed.
+         *
+         * @return ViewHolder for requested position
+         */
+        @Nullable
+        ViewHolder tryGetViewHolderForPositionByDeadline(int position,
+                boolean dryRun, long deadlineNs) {
+            if (position < 0 || position >= mState.getItemCount()) {
+                throw new IndexOutOfBoundsException("Invalid item position " + position
+                        + "(" + position + "). Item count:" + mState.getItemCount());
+            }
+            boolean fromScrapOrHiddenOrCache = false;
+            ViewHolder holder = null;
+            // 0) If there is a changed scrap, try to find from there
+            if (mState.isPreLayout()) {
+                holder = getChangedScrapViewForPosition(position);
+                fromScrapOrHiddenOrCache = holder != null;
+            }
+            // 1) Find by position from scrap/hidden list/cache
+            if (holder == null) {
+                holder = getScrapOrHiddenOrCachedHolderForPosition(position, dryRun);
+                if (holder != null) {
+                    if (!validateViewHolderForOffsetPosition(holder)) {
+                        // recycle holder (and unscrap if relevant) since it can't be used
+                        if (!dryRun) {
+                            // we would like to recycle this but need to make sure it is not used by
+                            // animation logic etc.
+                            holder.addFlags(ViewHolder.FLAG_INVALID);
+                            if (holder.isScrap()) {
+                                removeDetachedView(holder.itemView, false);
+                                holder.unScrap();
+                            } else if (holder.wasReturnedFromScrap()) {
+                                holder.clearReturnedFromScrapFlag();
+                            }
+                            recycleViewHolderInternal(holder);
+                        }
+                        holder = null;
+                    } else {
+                        fromScrapOrHiddenOrCache = true;
+                    }
+                }
+            }
+            if (holder == null) {
+                final int offsetPosition = mAdapterHelper.findPositionOffset(position);
+                if (offsetPosition < 0 || offsetPosition >= mAdapter.getItemCount()) {
+                    throw new IndexOutOfBoundsException("Inconsistency detected. Invalid item "
+                            + "position " + position + "(offset:" + offsetPosition + ")."
+                            + "state:" + mState.getItemCount());
+                }
+
+                final int type = mAdapter.getItemViewType(offsetPosition);
+                // 2) Find from scrap/cache via stable ids, if exists
+                if (mAdapter.hasStableIds()) {
+                    holder = getScrapOrCachedViewForId(mAdapter.getItemId(offsetPosition),
+                            type, dryRun);
+                    if (holder != null) {
+                        // update position
+                        holder.mPosition = offsetPosition;
+                        fromScrapOrHiddenOrCache = true;
+                    }
+                }
+                if (holder == null && mViewCacheExtension != null) {
+                    // We are NOT sending the offsetPosition because LayoutManager does not
+                    // know it.
+                    final View view = mViewCacheExtension
+                            .getViewForPositionAndType(this, position, type);
+                    if (view != null) {
+                        holder = getChildViewHolder(view);
+                        if (holder == null) {
+                            throw new IllegalArgumentException("getViewForPositionAndType returned"
+                                    + " a view which does not have a ViewHolder");
+                        } else if (holder.shouldIgnore()) {
+                            throw new IllegalArgumentException("getViewForPositionAndType returned"
+                                    + " a view that is ignored. You must call stopIgnoring before"
+                                    + " returning this view.");
+                        }
+                    }
+                }
+                if (holder == null) { // fallback to pool
+                    if (DEBUG) {
+                        Log.d(TAG, "tryGetViewHolderForPositionByDeadline("
+                                + position + ") fetching from shared pool");
+                    }
+                    holder = getRecycledViewPool().getRecycledView(type);
+                    if (holder != null) {
+                        holder.resetInternal();
+                        if (FORCE_INVALIDATE_DISPLAY_LIST) {
+                            invalidateDisplayListInt(holder);
+                        }
+                    }
+                }
+                if (holder == null) {
+                    long start = getNanoTime();
+                    if (deadlineNs != FOREVER_NS
+                            && !mRecyclerPool.willCreateInTime(type, start, deadlineNs)) {
+                        // abort - we have a deadline we can't meet
+                        return null;
+                    }
+                    holder = mAdapter.createViewHolder(RecyclerView.this, type);
+                    if (ALLOW_THREAD_GAP_WORK) {
+                        // only bother finding nested RV if prefetching
+                        RecyclerView innerView = findNestedRecyclerView(holder.itemView);
+                        if (innerView != null) {
+                            holder.mNestedRecyclerView = new WeakReference<>(innerView);
+                        }
+                    }
+
+                    long end = getNanoTime();
+                    mRecyclerPool.factorInCreateTime(type, end - start);
+                    if (DEBUG) {
+                        Log.d(TAG, "tryGetViewHolderForPositionByDeadline created new ViewHolder");
+                    }
+                }
+            }
+
+            // This is very ugly but the only place we can grab this information
+            // before the View is rebound and returned to the LayoutManager for post layout ops.
+            // We don't need this in pre-layout since the VH is not updated by the LM.
+            if (fromScrapOrHiddenOrCache && !mState.isPreLayout() && holder
+                    .hasAnyOfTheFlags(ViewHolder.FLAG_BOUNCED_FROM_HIDDEN_LIST)) {
+                holder.setFlags(0, ViewHolder.FLAG_BOUNCED_FROM_HIDDEN_LIST);
+                if (mState.mRunSimpleAnimations) {
+                    int changeFlags = ItemAnimator
+                            .buildAdapterChangeFlagsForAnimations(holder);
+                    changeFlags |= ItemAnimator.FLAG_APPEARED_IN_PRE_LAYOUT;
+                    final ItemHolderInfo info = mItemAnimator.recordPreLayoutInformation(mState,
+                            holder, changeFlags, holder.getUnmodifiedPayloads());
+                    recordAnimationInfoIfBouncedHiddenView(holder, info);
+                }
+            }
+
+            boolean bound = false;
+            if (mState.isPreLayout() && holder.isBound()) {
+                // do not update unless we absolutely have to.
+                holder.mPreLayoutPosition = position;
+            } else if (!holder.isBound() || holder.needsUpdate() || holder.isInvalid()) {
+                if (DEBUG && holder.isRemoved()) {
+                    throw new IllegalStateException("Removed holder should be bound and it should"
+                            + " come here only in pre-layout. Holder: " + holder);
+                }
+                final int offsetPosition = mAdapterHelper.findPositionOffset(position);
+                bound = tryBindViewHolderByDeadline(holder, offsetPosition, position, deadlineNs);
+            }
+
+            final ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
+            final LayoutParams rvLayoutParams;
+            if (lp == null) {
+                rvLayoutParams = (LayoutParams) generateDefaultLayoutParams();
+                holder.itemView.setLayoutParams(rvLayoutParams);
+            } else if (!checkLayoutParams(lp)) {
+                rvLayoutParams = (LayoutParams) generateLayoutParams(lp);
+                holder.itemView.setLayoutParams(rvLayoutParams);
+            } else {
+                rvLayoutParams = (LayoutParams) lp;
+            }
+            rvLayoutParams.mViewHolder = holder;
+            rvLayoutParams.mPendingInvalidate = fromScrapOrHiddenOrCache && bound;
+            return holder;
+        }
+
+        private void attachAccessibilityDelegate(View itemView) {
+            if (isAccessibilityEnabled()) {
+                if (itemView.getImportantForAccessibility()
+                        == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
+                    itemView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
+                }
+
+                if (itemView.getAccessibilityDelegate() == null) {
+                    itemView.setAccessibilityDelegate(mAccessibilityDelegate.getItemDelegate());
+                }
+            }
+        }
+
+        private void invalidateDisplayListInt(ViewHolder holder) {
+            if (holder.itemView instanceof ViewGroup) {
+                invalidateDisplayListInt((ViewGroup) holder.itemView, false);
+            }
+        }
+
+        private void invalidateDisplayListInt(ViewGroup viewGroup, boolean invalidateThis) {
+            for (int i = viewGroup.getChildCount() - 1; i >= 0; i--) {
+                final View view = viewGroup.getChildAt(i);
+                if (view instanceof ViewGroup) {
+                    invalidateDisplayListInt((ViewGroup) view, true);
+                }
+            }
+            if (!invalidateThis) {
+                return;
+            }
+            // we need to force it to become invisible
+            if (viewGroup.getVisibility() == View.INVISIBLE) {
+                viewGroup.setVisibility(View.VISIBLE);
+                viewGroup.setVisibility(View.INVISIBLE);
+            } else {
+                final int visibility = viewGroup.getVisibility();
+                viewGroup.setVisibility(View.INVISIBLE);
+                viewGroup.setVisibility(visibility);
+            }
+        }
+
+        /**
+         * Recycle a detached view. The specified view will be added to a pool of views
+         * for later rebinding and reuse.
+         *
+         * <p>A view must be fully detached (removed from parent) before it may be recycled. If the
+         * View is scrapped, it will be removed from scrap list.</p>
+         *
+         * @param view Removed view for recycling
+         * @see LayoutManager#removeAndRecycleView(View, Recycler)
+         */
+        public void recycleView(View view) {
+            // This public recycle method tries to make view recycle-able since layout manager
+            // intended to recycle this view (e.g. even if it is in scrap or change cache)
+            ViewHolder holder = getChildViewHolderInt(view);
+            if (holder.isTmpDetached()) {
+                removeDetachedView(view, false);
+            }
+            if (holder.isScrap()) {
+                holder.unScrap();
+            } else if (holder.wasReturnedFromScrap()) {
+                holder.clearReturnedFromScrapFlag();
+            }
+            recycleViewHolderInternal(holder);
+        }
+
+        /**
+         * Internally, use this method instead of {@link #recycleView(android.view.View)} to
+         * catch potential bugs.
+         * @param view
+         */
+        void recycleViewInternal(View view) {
+            recycleViewHolderInternal(getChildViewHolderInt(view));
+        }
+
+        void recycleAndClearCachedViews() {
+            final int count = mCachedViews.size();
+            for (int i = count - 1; i >= 0; i--) {
+                recycleCachedViewAt(i);
+            }
+            mCachedViews.clear();
+            if (ALLOW_THREAD_GAP_WORK) {
+                mPrefetchRegistry.clearPrefetchPositions();
+            }
+        }
+
+        /**
+         * Recycles a cached view and removes the view from the list. Views are added to cache
+         * if and only if they are recyclable, so this method does not check it again.
+         * <p>
+         * A small exception to this rule is when the view does not have an animator reference
+         * but transient state is true (due to animations created outside ItemAnimator). In that
+         * case, adapter may choose to recycle it. From RecyclerView's perspective, the view is
+         * still recyclable since Adapter wants to do so.
+         *
+         * @param cachedViewIndex The index of the view in cached views list
+         */
+        void recycleCachedViewAt(int cachedViewIndex) {
+            if (DEBUG) {
+                Log.d(TAG, "Recycling cached view at index " + cachedViewIndex);
+            }
+            ViewHolder viewHolder = mCachedViews.get(cachedViewIndex);
+            if (DEBUG) {
+                Log.d(TAG, "CachedViewHolder to be recycled: " + viewHolder);
+            }
+            addViewHolderToRecycledViewPool(viewHolder, true);
+            mCachedViews.remove(cachedViewIndex);
+        }
+
+        /**
+         * internal implementation checks if view is scrapped or attached and throws an exception
+         * if so.
+         * Public version un-scraps before calling recycle.
+         */
+        void recycleViewHolderInternal(ViewHolder holder) {
+            if (holder.isScrap() || holder.itemView.getParent() != null) {
+                throw new IllegalArgumentException(
+                        "Scrapped or attached views may not be recycled. isScrap:"
+                                + holder.isScrap() + " isAttached:"
+                                + (holder.itemView.getParent() != null));
+            }
+
+            if (holder.isTmpDetached()) {
+                throw new IllegalArgumentException("Tmp detached view should be removed "
+                        + "from RecyclerView before it can be recycled: " + holder);
+            }
+
+            if (holder.shouldIgnore()) {
+                throw new IllegalArgumentException("Trying to recycle an ignored view holder. You"
+                        + " should first call stopIgnoringView(view) before calling recycle.");
+            }
+            //noinspection unchecked
+            final boolean transientStatePreventsRecycling = holder
+                    .doesTransientStatePreventRecycling();
+            final boolean forceRecycle = mAdapter != null
+                    && transientStatePreventsRecycling
+                    && mAdapter.onFailedToRecycleView(holder);
+            boolean cached = false;
+            boolean recycled = false;
+            if (DEBUG && mCachedViews.contains(holder)) {
+                throw new IllegalArgumentException("cached view received recycle internal? "
+                        + holder);
+            }
+            if (forceRecycle || holder.isRecyclable()) {
+                if (mViewCacheMax > 0
+                        && !holder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID
+                                | ViewHolder.FLAG_REMOVED
+                                | ViewHolder.FLAG_UPDATE
+                                | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)) {
+                    // Retire oldest cached view
+                    int cachedViewSize = mCachedViews.size();
+                    if (cachedViewSize >= mViewCacheMax && cachedViewSize > 0) {
+                        recycleCachedViewAt(0);
+                        cachedViewSize--;
+                    }
+
+                    int targetCacheIndex = cachedViewSize;
+                    if (ALLOW_THREAD_GAP_WORK
+                            && cachedViewSize > 0
+                            && !mPrefetchRegistry.lastPrefetchIncludedPosition(holder.mPosition)) {
+                        // when adding the view, skip past most recently prefetched views
+                        int cacheIndex = cachedViewSize - 1;
+                        while (cacheIndex >= 0) {
+                            int cachedPos = mCachedViews.get(cacheIndex).mPosition;
+                            if (!mPrefetchRegistry.lastPrefetchIncludedPosition(cachedPos)) {
+                                break;
+                            }
+                            cacheIndex--;
+                        }
+                        targetCacheIndex = cacheIndex + 1;
+                    }
+                    mCachedViews.add(targetCacheIndex, holder);
+                    cached = true;
+                }
+                if (!cached) {
+                    addViewHolderToRecycledViewPool(holder, true);
+                    recycled = true;
+                }
+            } else {
+                // NOTE: A view can fail to be recycled when it is scrolled off while an animation
+                // runs. In this case, the item is eventually recycled by
+                // ItemAnimatorRestoreListener#onAnimationFinished.
+
+                // TODO: consider cancelling an animation when an item is removed scrollBy,
+                // to return it to the pool faster
+                if (DEBUG) {
+                    Log.d(TAG, "trying to recycle a non-recycleable holder. Hopefully, it will "
+                            + "re-visit here. We are still removing it from animation lists");
+                }
+            }
+            // even if the holder is not removed, we still call this method so that it is removed
+            // from view holder lists.
+            mViewInfoStore.removeViewHolder(holder);
+            if (!cached && !recycled && transientStatePreventsRecycling) {
+                holder.mOwnerRecyclerView = null;
+            }
+        }
+
+        /**
+         * Prepares the ViewHolder to be removed/recycled, and inserts it into the RecycledViewPool.
+         *
+         * Pass false to dispatchRecycled for views that have not been bound.
+         *
+         * @param holder Holder to be added to the pool.
+         * @param dispatchRecycled True to dispatch View recycled callbacks.
+         */
+        void addViewHolderToRecycledViewPool(ViewHolder holder, boolean dispatchRecycled) {
+            clearNestedRecyclerViewIfNotNested(holder);
+            holder.itemView.setAccessibilityDelegate(null);
+            if (dispatchRecycled) {
+                dispatchViewRecycled(holder);
+            }
+            holder.mOwnerRecyclerView = null;
+            getRecycledViewPool().putRecycledView(holder);
+        }
+
+        /**
+         * Used as a fast path for unscrapping and recycling a view during a bulk operation.
+         * The caller must call {@link #clearScrap()} when it's done to update the recycler's
+         * internal bookkeeping.
+         */
+        void quickRecycleScrapView(View view) {
+            final ViewHolder holder = getChildViewHolderInt(view);
+            holder.mScrapContainer = null;
+            holder.mInChangeScrap = false;
+            holder.clearReturnedFromScrapFlag();
+            recycleViewHolderInternal(holder);
+        }
+
+        /**
+         * Mark an attached view as scrap.
+         *
+         * <p>"Scrap" views are still attached to their parent RecyclerView but are eligible
+         * for rebinding and reuse. Requests for a view for a given position may return a
+         * reused or rebound scrap view instance.</p>
+         *
+         * @param view View to scrap
+         */
+        void scrapView(View view) {
+            final ViewHolder holder = getChildViewHolderInt(view);
+            if (holder.hasAnyOfTheFlags(ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_INVALID)
+                    || !holder.isUpdated() || canReuseUpdatedViewHolder(holder)) {
+                if (holder.isInvalid() && !holder.isRemoved() && !mAdapter.hasStableIds()) {
+                    throw new IllegalArgumentException("Called scrap view with an invalid view."
+                            + " Invalid views cannot be reused from scrap, they should rebound from"
+                            + " recycler pool.");
+                }
+                holder.setScrapContainer(this, false);
+                mAttachedScrap.add(holder);
+            } else {
+                if (mChangedScrap == null) {
+                    mChangedScrap = new ArrayList<ViewHolder>();
+                }
+                holder.setScrapContainer(this, true);
+                mChangedScrap.add(holder);
+            }
+        }
+
+        /**
+         * Remove a previously scrapped view from the pool of eligible scrap.
+         *
+         * <p>This view will no longer be eligible for reuse until re-scrapped or
+         * until it is explicitly removed and recycled.</p>
+         */
+        void unscrapView(ViewHolder holder) {
+            if (holder.mInChangeScrap) {
+                mChangedScrap.remove(holder);
+            } else {
+                mAttachedScrap.remove(holder);
+            }
+            holder.mScrapContainer = null;
+            holder.mInChangeScrap = false;
+            holder.clearReturnedFromScrapFlag();
+        }
+
+        int getScrapCount() {
+            return mAttachedScrap.size();
+        }
+
+        View getScrapViewAt(int index) {
+            return mAttachedScrap.get(index).itemView;
+        }
+
+        void clearScrap() {
+            mAttachedScrap.clear();
+            if (mChangedScrap != null) {
+                mChangedScrap.clear();
+            }
+        }
+
+        ViewHolder getChangedScrapViewForPosition(int position) {
+            // If pre-layout, check the changed scrap for an exact match.
+            final int changedScrapSize;
+            if (mChangedScrap == null || (changedScrapSize = mChangedScrap.size()) == 0) {
+                return null;
+            }
+            // find by position
+            for (int i = 0; i < changedScrapSize; i++) {
+                final ViewHolder holder = mChangedScrap.get(i);
+                if (!holder.wasReturnedFromScrap() && holder.getLayoutPosition() == position) {
+                    holder.addFlags(ViewHolder.FLAG_RETURNED_FROM_SCRAP);
+                    return holder;
+                }
+            }
+            // find by id
+            if (mAdapter.hasStableIds()) {
+                final int offsetPosition = mAdapterHelper.findPositionOffset(position);
+                if (offsetPosition > 0 && offsetPosition < mAdapter.getItemCount()) {
+                    final long id = mAdapter.getItemId(offsetPosition);
+                    for (int i = 0; i < changedScrapSize; i++) {
+                        final ViewHolder holder = mChangedScrap.get(i);
+                        if (!holder.wasReturnedFromScrap() && holder.getItemId() == id) {
+                            holder.addFlags(ViewHolder.FLAG_RETURNED_FROM_SCRAP);
+                            return holder;
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Returns a view for the position either from attach scrap, hidden children, or cache.
+         *
+         * @param position Item position
+         * @param dryRun  Does a dry run, finds the ViewHolder but does not remove
+         * @return a ViewHolder that can be re-used for this position.
+         */
+        ViewHolder getScrapOrHiddenOrCachedHolderForPosition(int position, boolean dryRun) {
+            final int scrapCount = mAttachedScrap.size();
+
+            // Try first for an exact, non-invalid match from scrap.
+            for (int i = 0; i < scrapCount; i++) {
+                final ViewHolder holder = mAttachedScrap.get(i);
+                if (!holder.wasReturnedFromScrap() && holder.getLayoutPosition() == position
+                        && !holder.isInvalid() && (mState.mInPreLayout || !holder.isRemoved())) {
+                    holder.addFlags(ViewHolder.FLAG_RETURNED_FROM_SCRAP);
+                    return holder;
+                }
+            }
+
+            if (!dryRun) {
+                View view = mChildHelper.findHiddenNonRemovedView(position);
+                if (view != null) {
+                    // This View is good to be used. We just need to unhide, detach and move to the
+                    // scrap list.
+                    final ViewHolder vh = getChildViewHolderInt(view);
+                    mChildHelper.unhide(view);
+                    int layoutIndex = mChildHelper.indexOfChild(view);
+                    if (layoutIndex == RecyclerView.NO_POSITION) {
+                        throw new IllegalStateException("layout index should not be -1 after "
+                                + "unhiding a view:" + vh);
+                    }
+                    mChildHelper.detachViewFromParent(layoutIndex);
+                    scrapView(view);
+                    vh.addFlags(ViewHolder.FLAG_RETURNED_FROM_SCRAP
+                            | ViewHolder.FLAG_BOUNCED_FROM_HIDDEN_LIST);
+                    return vh;
+                }
+            }
+
+            // Search in our first-level recycled view cache.
+            final int cacheSize = mCachedViews.size();
+            for (int i = 0; i < cacheSize; i++) {
+                final ViewHolder holder = mCachedViews.get(i);
+                // invalid view holders may be in cache if adapter has stable ids as they can be
+                // retrieved via getScrapOrCachedViewForId
+                if (!holder.isInvalid() && holder.getLayoutPosition() == position) {
+                    if (!dryRun) {
+                        mCachedViews.remove(i);
+                    }
+                    if (DEBUG) {
+                        Log.d(TAG, "getScrapOrHiddenOrCachedHolderForPosition(" + position
+                                + ") found match in cache: " + holder);
+                    }
+                    return holder;
+                }
+            }
+            return null;
+        }
+
+        ViewHolder getScrapOrCachedViewForId(long id, int type, boolean dryRun) {
+            // Look in our attached views first
+            final int count = mAttachedScrap.size();
+            for (int i = count - 1; i >= 0; i--) {
+                final ViewHolder holder = mAttachedScrap.get(i);
+                if (holder.getItemId() == id && !holder.wasReturnedFromScrap()) {
+                    if (type == holder.getItemViewType()) {
+                        holder.addFlags(ViewHolder.FLAG_RETURNED_FROM_SCRAP);
+                        if (holder.isRemoved()) {
+                            // this might be valid in two cases:
+                            // > item is removed but we are in pre-layout pass
+                            // >> do nothing. return as is. make sure we don't rebind
+                            // > item is removed then added to another position and we are in
+                            // post layout.
+                            // >> remove removed and invalid flags, add update flag to rebind
+                            // because item was invisible to us and we don't know what happened in
+                            // between.
+                            if (!mState.isPreLayout()) {
+                                holder.setFlags(ViewHolder.FLAG_UPDATE, ViewHolder.FLAG_UPDATE
+                                        | ViewHolder.FLAG_INVALID | ViewHolder.FLAG_REMOVED);
+                            }
+                        }
+                        return holder;
+                    } else if (!dryRun) {
+                        // if we are running animations, it is actually better to keep it in scrap
+                        // but this would force layout manager to lay it out which would be bad.
+                        // Recycle this scrap. Type mismatch.
+                        mAttachedScrap.remove(i);
+                        removeDetachedView(holder.itemView, false);
+                        quickRecycleScrapView(holder.itemView);
+                    }
+                }
+            }
+
+            // Search the first-level cache
+            final int cacheSize = mCachedViews.size();
+            for (int i = cacheSize - 1; i >= 0; i--) {
+                final ViewHolder holder = mCachedViews.get(i);
+                if (holder.getItemId() == id) {
+                    if (type == holder.getItemViewType()) {
+                        if (!dryRun) {
+                            mCachedViews.remove(i);
+                        }
+                        return holder;
+                    } else if (!dryRun) {
+                        recycleCachedViewAt(i);
+                        return null;
+                    }
+                }
+            }
+            return null;
+        }
+
+        void dispatchViewRecycled(ViewHolder holder) {
+            if (mRecyclerListener != null) {
+                mRecyclerListener.onViewRecycled(holder);
+            }
+            if (mAdapter != null) {
+                mAdapter.onViewRecycled(holder);
+            }
+            if (mState != null) {
+                mViewInfoStore.removeViewHolder(holder);
+            }
+            if (DEBUG) Log.d(TAG, "dispatchViewRecycled: " + holder);
+        }
+
+        void onAdapterChanged(Adapter oldAdapter, Adapter newAdapter,
+                boolean compatibleWithPrevious) {
+            clear();
+            getRecycledViewPool().onAdapterChanged(oldAdapter, newAdapter, compatibleWithPrevious);
+        }
+
+        void offsetPositionRecordsForMove(int from, int to) {
+            final int start, end, inBetweenOffset;
+            if (from < to) {
+                start = from;
+                end = to;
+                inBetweenOffset = -1;
+            } else {
+                start = to;
+                end = from;
+                inBetweenOffset = 1;
+            }
+            final int cachedCount = mCachedViews.size();
+            for (int i = 0; i < cachedCount; i++) {
+                final ViewHolder holder = mCachedViews.get(i);
+                if (holder == null || holder.mPosition < start || holder.mPosition > end) {
+                    continue;
+                }
+                if (holder.mPosition == from) {
+                    holder.offsetPosition(to - from, false);
+                } else {
+                    holder.offsetPosition(inBetweenOffset, false);
+                }
+                if (DEBUG) {
+                    Log.d(TAG, "offsetPositionRecordsForMove cached child " + i + " holder "
+                            + holder);
+                }
+            }
+        }
+
+        void offsetPositionRecordsForInsert(int insertedAt, int count) {
+            final int cachedCount = mCachedViews.size();
+            for (int i = 0; i < cachedCount; i++) {
+                final ViewHolder holder = mCachedViews.get(i);
+                if (holder != null && holder.mPosition >= insertedAt) {
+                    if (DEBUG) {
+                        Log.d(TAG, "offsetPositionRecordsForInsert cached " + i + " holder "
+                                + holder + " now at position " + (holder.mPosition + count));
+                    }
+                    holder.offsetPosition(count, true);
+                }
+            }
+        }
+
+        /**
+         * @param removedFrom Remove start index
+         * @param count Remove count
+         * @param applyToPreLayout If true, changes will affect ViewHolder's pre-layout position, if
+         *                         false, they'll be applied before the second layout pass
+         */
+        void offsetPositionRecordsForRemove(int removedFrom, int count, boolean applyToPreLayout) {
+            final int removedEnd = removedFrom + count;
+            final int cachedCount = mCachedViews.size();
+            for (int i = cachedCount - 1; i >= 0; i--) {
+                final ViewHolder holder = mCachedViews.get(i);
+                if (holder != null) {
+                    if (holder.mPosition >= removedEnd) {
+                        if (DEBUG) {
+                            Log.d(TAG, "offsetPositionRecordsForRemove cached " + i
+                                    + " holder " + holder + " now at position "
+                                    + (holder.mPosition - count));
+                        }
+                        holder.offsetPosition(-count, applyToPreLayout);
+                    } else if (holder.mPosition >= removedFrom) {
+                        // Item for this view was removed. Dump it from the cache.
+                        holder.addFlags(ViewHolder.FLAG_REMOVED);
+                        recycleCachedViewAt(i);
+                    }
+                }
+            }
+        }
+
+        void setViewCacheExtension(ViewCacheExtension extension) {
+            mViewCacheExtension = extension;
+        }
+
+        void setRecycledViewPool(RecycledViewPool pool) {
+            if (mRecyclerPool != null) {
+                mRecyclerPool.detach();
+            }
+            mRecyclerPool = pool;
+            if (pool != null) {
+                mRecyclerPool.attach(getAdapter());
+            }
+        }
+
+        RecycledViewPool getRecycledViewPool() {
+            if (mRecyclerPool == null) {
+                mRecyclerPool = new RecycledViewPool();
+            }
+            return mRecyclerPool;
+        }
+
+        void viewRangeUpdate(int positionStart, int itemCount) {
+            final int positionEnd = positionStart + itemCount;
+            final int cachedCount = mCachedViews.size();
+            for (int i = cachedCount - 1; i >= 0; i--) {
+                final ViewHolder holder = mCachedViews.get(i);
+                if (holder == null) {
+                    continue;
+                }
+
+                final int pos = holder.getLayoutPosition();
+                if (pos >= positionStart && pos < positionEnd) {
+                    holder.addFlags(ViewHolder.FLAG_UPDATE);
+                    recycleCachedViewAt(i);
+                    // cached views should not be flagged as changed because this will cause them
+                    // to animate when they are returned from cache.
+                }
+            }
+        }
+
+        void setAdapterPositionsAsUnknown() {
+            final int cachedCount = mCachedViews.size();
+            for (int i = 0; i < cachedCount; i++) {
+                final ViewHolder holder = mCachedViews.get(i);
+                if (holder != null) {
+                    holder.addFlags(ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN);
+                }
+            }
+        }
+
+        void markKnownViewsInvalid() {
+            if (mAdapter != null && mAdapter.hasStableIds()) {
+                final int cachedCount = mCachedViews.size();
+                for (int i = 0; i < cachedCount; i++) {
+                    final ViewHolder holder = mCachedViews.get(i);
+                    if (holder != null) {
+                        holder.addFlags(ViewHolder.FLAG_UPDATE | ViewHolder.FLAG_INVALID);
+                        holder.addChangePayload(null);
+                    }
+                }
+            } else {
+                // we cannot re-use cached views in this case. Recycle them all
+                recycleAndClearCachedViews();
+            }
+        }
+
+        void clearOldPositions() {
+            final int cachedCount = mCachedViews.size();
+            for (int i = 0; i < cachedCount; i++) {
+                final ViewHolder holder = mCachedViews.get(i);
+                holder.clearOldPosition();
+            }
+            final int scrapCount = mAttachedScrap.size();
+            for (int i = 0; i < scrapCount; i++) {
+                mAttachedScrap.get(i).clearOldPosition();
+            }
+            if (mChangedScrap != null) {
+                final int changedScrapCount = mChangedScrap.size();
+                for (int i = 0; i < changedScrapCount; i++) {
+                    mChangedScrap.get(i).clearOldPosition();
+                }
+            }
+        }
+
+        void markItemDecorInsetsDirty() {
+            final int cachedCount = mCachedViews.size();
+            for (int i = 0; i < cachedCount; i++) {
+                final ViewHolder holder = mCachedViews.get(i);
+                LayoutParams layoutParams = (LayoutParams) holder.itemView.getLayoutParams();
+                if (layoutParams != null) {
+                    layoutParams.mInsetsDirty = true;
+                }
+            }
+        }
+    }
+
+    /**
+     * ViewCacheExtension is a helper class to provide an additional layer of view caching that can
+     * be controlled by the developer.
+     * <p>
+     * When {@link Recycler#getViewForPosition(int)} is called, Recycler checks attached scrap and
+     * first level cache to find a matching View. If it cannot find a suitable View, Recycler will
+     * call the {@link #getViewForPositionAndType(Recycler, int, int)} before checking
+     * {@link RecycledViewPool}.
+     * <p>
+     * Note that, Recycler never sends Views to this method to be cached. It is developers
+     * responsibility to decide whether they want to keep their Views in this custom cache or let
+     * the default recycling policy handle it.
+     */
+    public abstract static class ViewCacheExtension {
+
+        /**
+         * Returns a View that can be binded to the given Adapter position.
+         * <p>
+         * This method should <b>not</b> create a new View. Instead, it is expected to return
+         * an already created View that can be re-used for the given type and position.
+         * If the View is marked as ignored, it should first call
+         * {@link LayoutManager#stopIgnoringView(View)} before returning the View.
+         * <p>
+         * RecyclerView will re-bind the returned View to the position if necessary.
+         *
+         * @param recycler The Recycler that can be used to bind the View
+         * @param position The adapter position
+         * @param type     The type of the View, defined by adapter
+         * @return A View that is bound to the given position or NULL if there is no View to re-use
+         * @see LayoutManager#ignoreView(View)
+         */
+        public abstract View getViewForPositionAndType(Recycler recycler, int position, int type);
+    }
+
+    /**
+     * Base class for an Adapter
+     *
+     * <p>Adapters provide a binding from an app-specific data set to views that are displayed
+     * within a {@link RecyclerView}.</p>
+     *
+     * @param <VH> A class that extends ViewHolder that will be used by the adapter.
+     */
+    public abstract static class Adapter<VH extends ViewHolder> {
+        private final AdapterDataObservable mObservable = new AdapterDataObservable();
+        private boolean mHasStableIds = false;
+
+        /**
+         * Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent
+         * an item.
+         * <p>
+         * This new ViewHolder should be constructed with a new View that can represent the items
+         * of the given type. You can either create a new View manually or inflate it from an XML
+         * layout file.
+         * <p>
+         * The new ViewHolder will be used to display items of the adapter using
+         * {@link #onBindViewHolder(ViewHolder, int, List)}. Since it will be re-used to display
+         * different items in the data set, it is a good idea to cache references to sub views of
+         * the View to avoid unnecessary {@link View#findViewById(int)} calls.
+         *
+         * @param parent The ViewGroup into which the new View will be added after it is bound to
+         *               an adapter position.
+         * @param viewType The view type of the new View.
+         *
+         * @return A new ViewHolder that holds a View of the given view type.
+         * @see #getItemViewType(int)
+         * @see #onBindViewHolder(ViewHolder, int)
+         */
+        public abstract VH onCreateViewHolder(ViewGroup parent, int viewType);
+
+        /**
+         * Called by RecyclerView to display the data at the specified position. This method should
+         * update the contents of the {@link ViewHolder#itemView} to reflect the item at the given
+         * position.
+         * <p>
+         * Note that unlike {@link android.widget.ListView}, RecyclerView will not call this method
+         * again if the position of the item changes in the data set unless the item itself is
+         * invalidated or the new position cannot be determined. For this reason, you should only
+         * use the <code>position</code> parameter while acquiring the related data item inside
+         * this method and should not keep a copy of it. If you need the position of an item later
+         * on (e.g. in a click listener), use {@link ViewHolder#getAdapterPosition()} which will
+         * have the updated adapter position.
+         *
+         * Override {@link #onBindViewHolder(ViewHolder, int, List)} instead if Adapter can
+         * handle efficient partial bind.
+         *
+         * @param holder The ViewHolder which should be updated to represent the contents of the
+         *        item at the given position in the data set.
+         * @param position The position of the item within the adapter's data set.
+         */
+        public abstract void onBindViewHolder(VH holder, int position);
+
+        /**
+         * Called by RecyclerView to display the data at the specified position. This method
+         * should update the contents of the {@link ViewHolder#itemView} to reflect the item at
+         * the given position.
+         * <p>
+         * Note that unlike {@link android.widget.ListView}, RecyclerView will not call this method
+         * again if the position of the item changes in the data set unless the item itself is
+         * invalidated or the new position cannot be determined. For this reason, you should only
+         * use the <code>position</code> parameter while acquiring the related data item inside
+         * this method and should not keep a copy of it. If you need the position of an item later
+         * on (e.g. in a click listener), use {@link ViewHolder#getAdapterPosition()} which will
+         * have the updated adapter position.
+         * <p>
+         * Partial bind vs full bind:
+         * <p>
+         * The payloads parameter is a merge list from {@link #notifyItemChanged(int, Object)} or
+         * {@link #notifyItemRangeChanged(int, int, Object)}.  If the payloads list is not empty,
+         * the ViewHolder is currently bound to old data and Adapter may run an efficient partial
+         * update using the payload info.  If the payload is empty,  Adapter must run a full bind.
+         * Adapter should not assume that the payload passed in notify methods will be received by
+         * onBindViewHolder().  For example when the view is not attached to the screen, the
+         * payload in notifyItemChange() will be simply dropped.
+         *
+         * @param holder The ViewHolder which should be updated to represent the contents of the
+         *               item at the given position in the data set.
+         * @param position The position of the item within the adapter's data set.
+         * @param payloads A non-null list of merged payloads. Can be empty list if requires full
+         *                 update.
+         */
+        public void onBindViewHolder(VH holder, int position, List<Object> payloads) {
+            onBindViewHolder(holder, position);
+        }
+
+        /**
+         * This method calls {@link #onCreateViewHolder(ViewGroup, int)} to create a new
+         * {@link ViewHolder} and initializes some private fields to be used by RecyclerView.
+         *
+         * @see #onCreateViewHolder(ViewGroup, int)
+         */
+        public final VH createViewHolder(ViewGroup parent, int viewType) {
+            Trace.beginSection(TRACE_CREATE_VIEW_TAG);
+            final VH holder = onCreateViewHolder(parent, viewType);
+            holder.mItemViewType = viewType;
+            Trace.endSection();
+            return holder;
+        }
+
+        /**
+         * This method internally calls {@link #onBindViewHolder(ViewHolder, int)} to update the
+         * {@link ViewHolder} contents with the item at the given position and also sets up some
+         * private fields to be used by RecyclerView.
+         *
+         * @see #onBindViewHolder(ViewHolder, int)
+         */
+        public final void bindViewHolder(VH holder, int position) {
+            holder.mPosition = position;
+            if (hasStableIds()) {
+                holder.mItemId = getItemId(position);
+            }
+            holder.setFlags(ViewHolder.FLAG_BOUND,
+                    ViewHolder.FLAG_BOUND | ViewHolder.FLAG_UPDATE | ViewHolder.FLAG_INVALID
+                            | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN);
+            Trace.beginSection(TRACE_BIND_VIEW_TAG);
+            onBindViewHolder(holder, position, holder.getUnmodifiedPayloads());
+            holder.clearPayload();
+            final ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
+            if (layoutParams instanceof RecyclerView.LayoutParams) {
+                ((LayoutParams) layoutParams).mInsetsDirty = true;
+            }
+            Trace.endSection();
+        }
+
+        /**
+         * Return the view type of the item at <code>position</code> for the purposes
+         * of view recycling.
+         *
+         * <p>The default implementation of this method returns 0, making the assumption of
+         * a single view type for the adapter. Unlike ListView adapters, types need not
+         * be contiguous. Consider using id resources to uniquely identify item view types.
+         *
+         * @param position position to query
+         * @return integer value identifying the type of the view needed to represent the item at
+         *                 <code>position</code>. Type codes need not be contiguous.
+         */
+        public int getItemViewType(int position) {
+            return 0;
+        }
+
+        /**
+         * Indicates whether each item in the data set can be represented with a unique identifier
+         * of type {@link java.lang.Long}.
+         *
+         * @param hasStableIds Whether items in data set have unique identifiers or not.
+         * @see #hasStableIds()
+         * @see #getItemId(int)
+         */
+        public void setHasStableIds(boolean hasStableIds) {
+            if (hasObservers()) {
+                throw new IllegalStateException("Cannot change whether this adapter has "
+                        + "stable IDs while the adapter has registered observers.");
+            }
+            mHasStableIds = hasStableIds;
+        }
+
+        /**
+         * Return the stable ID for the item at <code>position</code>. If {@link #hasStableIds()}
+         * would return false this method should return {@link #NO_ID}. The default implementation
+         * of this method returns {@link #NO_ID}.
+         *
+         * @param position Adapter position to query
+         * @return the stable ID of the item at position
+         */
+        public long getItemId(int position) {
+            return NO_ID;
+        }
+
+        /**
+         * Returns the total number of items in the data set held by the adapter.
+         *
+         * @return The total number of items in this adapter.
+         */
+        public abstract int getItemCount();
+
+        /**
+         * Returns true if this adapter publishes a unique <code>long</code> value that can
+         * act as a key for the item at a given position in the data set. If that item is relocated
+         * in the data set, the ID returned for that item should be the same.
+         *
+         * @return true if this adapter's items have stable IDs
+         */
+        public final boolean hasStableIds() {
+            return mHasStableIds;
+        }
+
+        /**
+         * Called when a view created by this adapter has been recycled.
+         *
+         * <p>A view is recycled when a {@link LayoutManager} decides that it no longer
+         * needs to be attached to its parent {@link RecyclerView}. This can be because it has
+         * fallen out of visibility or a set of cached views represented by views still
+         * attached to the parent RecyclerView. If an item view has large or expensive data
+         * bound to it such as large bitmaps, this may be a good place to release those
+         * resources.</p>
+         * <p>
+         * RecyclerView calls this method right before clearing ViewHolder's internal data and
+         * sending it to RecycledViewPool. This way, if ViewHolder was holding valid information
+         * before being recycled, you can call {@link ViewHolder#getAdapterPosition()} to get
+         * its adapter position.
+         *
+         * @param holder The ViewHolder for the view being recycled
+         */
+        public void onViewRecycled(VH holder) {
+        }
+
+        /**
+         * Called by the RecyclerView if a ViewHolder created by this Adapter cannot be recycled
+         * due to its transient state. Upon receiving this callback, Adapter can clear the
+         * animation(s) that effect the View's transient state and return <code>true</code> so that
+         * the View can be recycled. Keep in mind that the View in question is already removed from
+         * the RecyclerView.
+         * <p>
+         * In some cases, it is acceptable to recycle a View although it has transient state. Most
+         * of the time, this is a case where the transient state will be cleared in
+         * {@link #onBindViewHolder(ViewHolder, int)} call when View is rebound to a new position.
+         * For this reason, RecyclerView leaves the decision to the Adapter and uses the return
+         * value of this method to decide whether the View should be recycled or not.
+         * <p>
+         * Note that when all animations are created by {@link RecyclerView.ItemAnimator}, you
+         * should never receive this callback because RecyclerView keeps those Views as children
+         * until their animations are complete. This callback is useful when children of the item
+         * views create animations which may not be easy to implement using an {@link ItemAnimator}.
+         * <p>
+         * You should <em>never</em> fix this issue by calling
+         * <code>holder.itemView.setHasTransientState(false);</code> unless you've previously called
+         * <code>holder.itemView.setHasTransientState(true);</code>. Each
+         * <code>View.setHasTransientState(true)</code> call must be matched by a
+         * <code>View.setHasTransientState(false)</code> call, otherwise, the state of the View
+         * may become inconsistent. You should always prefer to end or cancel animations that are
+         * triggering the transient state instead of handling it manually.
+         *
+         * @param holder The ViewHolder containing the View that could not be recycled due to its
+         *               transient state.
+         * @return True if the View should be recycled, false otherwise. Note that if this method
+         * returns <code>true</code>, RecyclerView <em>will ignore</em> the transient state of
+         * the View and recycle it regardless. If this method returns <code>false</code>,
+         * RecyclerView will check the View's transient state again before giving a final decision.
+         * Default implementation returns false.
+         */
+        public boolean onFailedToRecycleView(VH holder) {
+            return false;
+        }
+
+        /**
+         * Called when a view created by this adapter has been attached to a window.
+         *
+         * <p>This can be used as a reasonable signal that the view is about to be seen
+         * by the user. If the adapter previously freed any resources in
+         * {@link #onViewDetachedFromWindow(RecyclerView.ViewHolder) onViewDetachedFromWindow}
+         * those resources should be restored here.</p>
+         *
+         * @param holder Holder of the view being attached
+         */
+        public void onViewAttachedToWindow(VH holder) {
+        }
+
+        /**
+         * Called when a view created by this adapter has been detached from its window.
+         *
+         * <p>Becoming detached from the window is not necessarily a permanent condition;
+         * the consumer of an Adapter's views may choose to cache views offscreen while they
+         * are not visible, attaching and detaching them as appropriate.</p>
+         *
+         * @param holder Holder of the view being detached
+         */
+        public void onViewDetachedFromWindow(VH holder) {
+        }
+
+        /**
+         * Returns true if one or more observers are attached to this adapter.
+         *
+         * @return true if this adapter has observers
+         */
+        public final boolean hasObservers() {
+            return mObservable.hasObservers();
+        }
+
+        /**
+         * Register a new observer to listen for data changes.
+         *
+         * <p>The adapter may publish a variety of events describing specific changes.
+         * Not all adapters may support all change types and some may fall back to a generic
+         * {@link com.android.internal.widget.RecyclerView.AdapterDataObserver#onChanged()
+         * "something changed"} event if more specific data is not available.</p>
+         *
+         * <p>Components registering observers with an adapter are responsible for
+         * {@link #unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver)
+         * unregistering} those observers when finished.</p>
+         *
+         * @param observer Observer to register
+         *
+         * @see #unregisterAdapterDataObserver(RecyclerView.AdapterDataObserver)
+         */
+        public void registerAdapterDataObserver(AdapterDataObserver observer) {
+            mObservable.registerObserver(observer);
+        }
+
+        /**
+         * Unregister an observer currently listening for data changes.
+         *
+         * <p>The unregistered observer will no longer receive events about changes
+         * to the adapter.</p>
+         *
+         * @param observer Observer to unregister
+         *
+         * @see #registerAdapterDataObserver(RecyclerView.AdapterDataObserver)
+         */
+        public void unregisterAdapterDataObserver(AdapterDataObserver observer) {
+            mObservable.unregisterObserver(observer);
+        }
+
+        /**
+         * Called by RecyclerView when it starts observing this Adapter.
+         * <p>
+         * Keep in mind that same adapter may be observed by multiple RecyclerViews.
+         *
+         * @param recyclerView The RecyclerView instance which started observing this adapter.
+         * @see #onDetachedFromRecyclerView(RecyclerView)
+         */
+        public void onAttachedToRecyclerView(RecyclerView recyclerView) {
+        }
+
+        /**
+         * Called by RecyclerView when it stops observing this Adapter.
+         *
+         * @param recyclerView The RecyclerView instance which stopped observing this adapter.
+         * @see #onAttachedToRecyclerView(RecyclerView)
+         */
+        public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
+        }
+
+        /**
+         * Notify any registered observers that the data set has changed.
+         *
+         * <p>There are two different classes of data change events, item changes and structural
+         * changes. Item changes are when a single item has its data updated but no positional
+         * changes have occurred. Structural changes are when items are inserted, removed or moved
+         * within the data set.</p>
+         *
+         * <p>This event does not specify what about the data set has changed, forcing
+         * any observers to assume that all existing items and structure may no longer be valid.
+         * LayoutManagers will be forced to fully rebind and relayout all visible views.</p>
+         *
+         * <p><code>RecyclerView</code> will attempt to synthesize visible structural change events
+         * for adapters that report that they have {@link #hasStableIds() stable IDs} when
+         * this method is used. This can help for the purposes of animation and visual
+         * object persistence but individual item views will still need to be rebound
+         * and relaid out.</p>
+         *
+         * <p>If you are writing an adapter it will always be more efficient to use the more
+         * specific change events if you can. Rely on <code>notifyDataSetChanged()</code>
+         * as a last resort.</p>
+         *
+         * @see #notifyItemChanged(int)
+         * @see #notifyItemInserted(int)
+         * @see #notifyItemRemoved(int)
+         * @see #notifyItemRangeChanged(int, int)
+         * @see #notifyItemRangeInserted(int, int)
+         * @see #notifyItemRangeRemoved(int, int)
+         */
+        public final void notifyDataSetChanged() {
+            mObservable.notifyChanged();
+        }
+
+        /**
+         * Notify any registered observers that the item at <code>position</code> has changed.
+         * Equivalent to calling <code>notifyItemChanged(position, null);</code>.
+         *
+         * <p>This is an item change event, not a structural change event. It indicates that any
+         * reflection of the data at <code>position</code> is out of date and should be updated.
+         * The item at <code>position</code> retains the same identity.</p>
+         *
+         * @param position Position of the item that has changed
+         *
+         * @see #notifyItemRangeChanged(int, int)
+         */
+        public final void notifyItemChanged(int position) {
+            mObservable.notifyItemRangeChanged(position, 1);
+        }
+
+        /**
+         * Notify any registered observers that the item at <code>position</code> has changed with
+         * an optional payload object.
+         *
+         * <p>This is an item change event, not a structural change event. It indicates that any
+         * reflection of the data at <code>position</code> is out of date and should be updated.
+         * The item at <code>position</code> retains the same identity.
+         * </p>
+         *
+         * <p>
+         * Client can optionally pass a payload for partial change. These payloads will be merged
+         * and may be passed to adapter's {@link #onBindViewHolder(ViewHolder, int, List)} if the
+         * item is already represented by a ViewHolder and it will be rebound to the same
+         * ViewHolder. A notifyItemRangeChanged() with null payload will clear all existing
+         * payloads on that item and prevent future payload until
+         * {@link #onBindViewHolder(ViewHolder, int, List)} is called. Adapter should not assume
+         * that the payload will always be passed to onBindViewHolder(), e.g. when the view is not
+         * attached, the payload will be simply dropped.
+         *
+         * @param position Position of the item that has changed
+         * @param payload Optional parameter, use null to identify a "full" update
+         *
+         * @see #notifyItemRangeChanged(int, int)
+         */
+        public final void notifyItemChanged(int position, Object payload) {
+            mObservable.notifyItemRangeChanged(position, 1, payload);
+        }
+
+        /**
+         * Notify any registered observers that the <code>itemCount</code> items starting at
+         * position <code>positionStart</code> have changed.
+         * Equivalent to calling <code>notifyItemRangeChanged(position, itemCount, null);</code>.
+         *
+         * <p>This is an item change event, not a structural change event. It indicates that
+         * any reflection of the data in the given position range is out of date and should
+         * be updated. The items in the given range retain the same identity.</p>
+         *
+         * @param positionStart Position of the first item that has changed
+         * @param itemCount Number of items that have changed
+         *
+         * @see #notifyItemChanged(int)
+         */
+        public final void notifyItemRangeChanged(int positionStart, int itemCount) {
+            mObservable.notifyItemRangeChanged(positionStart, itemCount);
+        }
+
+        /**
+         * Notify any registered observers that the <code>itemCount</code> items starting at
+         * position <code>positionStart</code> have changed. An optional payload can be
+         * passed to each changed item.
+         *
+         * <p>This is an item change event, not a structural change event. It indicates that any
+         * reflection of the data in the given position range is out of date and should be updated.
+         * The items in the given range retain the same identity.
+         * </p>
+         *
+         * <p>
+         * Client can optionally pass a payload for partial change. These payloads will be merged
+         * and may be passed to adapter's {@link #onBindViewHolder(ViewHolder, int, List)} if the
+         * item is already represented by a ViewHolder and it will be rebound to the same
+         * ViewHolder. A notifyItemRangeChanged() with null payload will clear all existing
+         * payloads on that item and prevent future payload until
+         * {@link #onBindViewHolder(ViewHolder, int, List)} is called. Adapter should not assume
+         * that the payload will always be passed to onBindViewHolder(), e.g. when the view is not
+         * attached, the payload will be simply dropped.
+         *
+         * @param positionStart Position of the first item that has changed
+         * @param itemCount Number of items that have changed
+         * @param payload  Optional parameter, use null to identify a "full" update
+         *
+         * @see #notifyItemChanged(int)
+         */
+        public final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) {
+            mObservable.notifyItemRangeChanged(positionStart, itemCount, payload);
+        }
+
+        /**
+         * Notify any registered observers that the item reflected at <code>position</code>
+         * has been newly inserted. The item previously at <code>position</code> is now at
+         * position <code>position + 1</code>.
+         *
+         * <p>This is a structural change event. Representations of other existing items in the
+         * data set are still considered up to date and will not be rebound, though their
+         * positions may be altered.</p>
+         *
+         * @param position Position of the newly inserted item in the data set
+         *
+         * @see #notifyItemRangeInserted(int, int)
+         */
+        public final void notifyItemInserted(int position) {
+            mObservable.notifyItemRangeInserted(position, 1);
+        }
+
+        /**
+         * Notify any registered observers that the item reflected at <code>fromPosition</code>
+         * has been moved to <code>toPosition</code>.
+         *
+         * <p>This is a structural change event. Representations of other existing items in the
+         * data set are still considered up to date and will not be rebound, though their
+         * positions may be altered.</p>
+         *
+         * @param fromPosition Previous position of the item.
+         * @param toPosition New position of the item.
+         */
+        public final void notifyItemMoved(int fromPosition, int toPosition) {
+            mObservable.notifyItemMoved(fromPosition, toPosition);
+        }
+
+        /**
+         * Notify any registered observers that the currently reflected <code>itemCount</code>
+         * items starting at <code>positionStart</code> have been newly inserted. The items
+         * previously located at <code>positionStart</code> and beyond can now be found starting
+         * at position <code>positionStart + itemCount</code>.
+         *
+         * <p>This is a structural change event. Representations of other existing items in the
+         * data set are still considered up to date and will not be rebound, though their positions
+         * may be altered.</p>
+         *
+         * @param positionStart Position of the first item that was inserted
+         * @param itemCount Number of items inserted
+         *
+         * @see #notifyItemInserted(int)
+         */
+        public final void notifyItemRangeInserted(int positionStart, int itemCount) {
+            mObservable.notifyItemRangeInserted(positionStart, itemCount);
+        }
+
+        /**
+         * Notify any registered observers that the item previously located at <code>position</code>
+         * has been removed from the data set. The items previously located at and after
+         * <code>position</code> may now be found at <code>oldPosition - 1</code>.
+         *
+         * <p>This is a structural change event. Representations of other existing items in the
+         * data set are still considered up to date and will not be rebound, though their positions
+         * may be altered.</p>
+         *
+         * @param position Position of the item that has now been removed
+         *
+         * @see #notifyItemRangeRemoved(int, int)
+         */
+        public final void notifyItemRemoved(int position) {
+            mObservable.notifyItemRangeRemoved(position, 1);
+        }
+
+        /**
+         * Notify any registered observers that the <code>itemCount</code> items previously
+         * located at <code>positionStart</code> have been removed from the data set. The items
+         * previously located at and after <code>positionStart + itemCount</code> may now be found
+         * at <code>oldPosition - itemCount</code>.
+         *
+         * <p>This is a structural change event. Representations of other existing items in the data
+         * set are still considered up to date and will not be rebound, though their positions
+         * may be altered.</p>
+         *
+         * @param positionStart Previous position of the first item that was removed
+         * @param itemCount Number of items removed from the data set
+         */
+        public final void notifyItemRangeRemoved(int positionStart, int itemCount) {
+            mObservable.notifyItemRangeRemoved(positionStart, itemCount);
+        }
+    }
+
+    void dispatchChildDetached(View child) {
+        final ViewHolder viewHolder = getChildViewHolderInt(child);
+        onChildDetachedFromWindow(child);
+        if (mAdapter != null && viewHolder != null) {
+            mAdapter.onViewDetachedFromWindow(viewHolder);
+        }
+        if (mOnChildAttachStateListeners != null) {
+            final int cnt = mOnChildAttachStateListeners.size();
+            for (int i = cnt - 1; i >= 0; i--) {
+                mOnChildAttachStateListeners.get(i).onChildViewDetachedFromWindow(child);
+            }
+        }
+    }
+
+    void dispatchChildAttached(View child) {
+        final ViewHolder viewHolder = getChildViewHolderInt(child);
+        onChildAttachedToWindow(child);
+        if (mAdapter != null && viewHolder != null) {
+            mAdapter.onViewAttachedToWindow(viewHolder);
+        }
+        if (mOnChildAttachStateListeners != null) {
+            final int cnt = mOnChildAttachStateListeners.size();
+            for (int i = cnt - 1; i >= 0; i--) {
+                mOnChildAttachStateListeners.get(i).onChildViewAttachedToWindow(child);
+            }
+        }
+    }
+
+    /**
+     * A <code>LayoutManager</code> is responsible for measuring and positioning item views
+     * within a <code>RecyclerView</code> as well as determining the policy for when to recycle
+     * item views that are no longer visible to the user. By changing the <code>LayoutManager</code>
+     * a <code>RecyclerView</code> can be used to implement a standard vertically scrolling list,
+     * a uniform grid, staggered grids, horizontally scrolling collections and more. Several stock
+     * layout managers are provided for general use.
+     * <p/>
+     * If the LayoutManager specifies a default constructor or one with the signature
+     * ({@link Context}, {@link AttributeSet}, {@code int}, {@code int}), RecyclerView will
+     * instantiate and set the LayoutManager when being inflated. Most used properties can
+     * be then obtained from {@link #getProperties(Context, AttributeSet, int, int)}. In case
+     * a LayoutManager specifies both constructors, the non-default constructor will take
+     * precedence.
+     *
+     */
+    public abstract static class LayoutManager {
+        ChildHelper mChildHelper;
+        RecyclerView mRecyclerView;
+
+        @Nullable
+        SmoothScroller mSmoothScroller;
+
+        boolean mRequestedSimpleAnimations = false;
+
+        boolean mIsAttachedToWindow = false;
+
+        boolean mAutoMeasure = false;
+
+        /**
+         * LayoutManager has its own more strict measurement cache to avoid re-measuring a child
+         * if the space that will be given to it is already larger than what it has measured before.
+         */
+        private boolean mMeasurementCacheEnabled = true;
+
+        private boolean mItemPrefetchEnabled = true;
+
+        /**
+         * Written by {@link GapWorker} when prefetches occur to track largest number of view ever
+         * requested by a {@link #collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)} or
+         * {@link #collectAdjacentPrefetchPositions(int, int, State, LayoutPrefetchRegistry)} call.
+         *
+         * If expanded by a {@link #collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)},
+         * will be reset upon layout to prevent initial prefetches (often large, since they're
+         * proportional to expected child count) from expanding cache permanently.
+         */
+        int mPrefetchMaxCountObserved;
+
+        /**
+         * If true, mPrefetchMaxCountObserved is only valid until next layout, and should be reset.
+         */
+        boolean mPrefetchMaxObservedInInitialPrefetch;
+
+        /**
+         * These measure specs might be the measure specs that were passed into RecyclerView's
+         * onMeasure method OR fake measure specs created by the RecyclerView.
+         * For example, when a layout is run, RecyclerView always sets these specs to be
+         * EXACTLY because a LayoutManager cannot resize RecyclerView during a layout pass.
+         * <p>
+         * Also, to be able to use the hint in unspecified measure specs, RecyclerView checks the
+         * API level and sets the size to 0 pre-M to avoid any issue that might be caused by
+         * corrupt values. Older platforms have no responsibility to provide a size if they set
+         * mode to unspecified.
+         */
+        private int mWidthMode, mHeightMode;
+        private int mWidth, mHeight;
+
+
+        /**
+         * Interface for LayoutManagers to request items to be prefetched, based on position, with
+         * specified distance from viewport, which indicates priority.
+         *
+         * @see LayoutManager#collectAdjacentPrefetchPositions(int, int, State, LayoutPrefetchRegistry)
+         * @see LayoutManager#collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)
+         */
+        public interface LayoutPrefetchRegistry {
+            /**
+             * Requests an an item to be prefetched, based on position, with a specified distance,
+             * indicating priority.
+             *
+             * @param layoutPosition Position of the item to prefetch.
+             * @param pixelDistance Distance from the current viewport to the bounds of the item,
+             *                      must be non-negative.
+             */
+            void addPosition(int layoutPosition, int pixelDistance);
+        }
+
+        void setRecyclerView(RecyclerView recyclerView) {
+            if (recyclerView == null) {
+                mRecyclerView = null;
+                mChildHelper = null;
+                mWidth = 0;
+                mHeight = 0;
+            } else {
+                mRecyclerView = recyclerView;
+                mChildHelper = recyclerView.mChildHelper;
+                mWidth = recyclerView.getWidth();
+                mHeight = recyclerView.getHeight();
+            }
+            mWidthMode = MeasureSpec.EXACTLY;
+            mHeightMode = MeasureSpec.EXACTLY;
+        }
+
+        void setMeasureSpecs(int wSpec, int hSpec) {
+            mWidth = MeasureSpec.getSize(wSpec);
+            mWidthMode = MeasureSpec.getMode(wSpec);
+            if (mWidthMode == MeasureSpec.UNSPECIFIED && !ALLOW_SIZE_IN_UNSPECIFIED_SPEC) {
+                mWidth = 0;
+            }
+
+            mHeight = MeasureSpec.getSize(hSpec);
+            mHeightMode = MeasureSpec.getMode(hSpec);
+            if (mHeightMode == MeasureSpec.UNSPECIFIED && !ALLOW_SIZE_IN_UNSPECIFIED_SPEC) {
+                mHeight = 0;
+            }
+        }
+
+        /**
+         * Called after a layout is calculated during a measure pass when using auto-measure.
+         * <p>
+         * It simply traverses all children to calculate a bounding box then calls
+         * {@link #setMeasuredDimension(Rect, int, int)}. LayoutManagers can override that method
+         * if they need to handle the bounding box differently.
+         * <p>
+         * For example, GridLayoutManager override that method to ensure that even if a column is
+         * empty, the GridLayoutManager still measures wide enough to include it.
+         *
+         * @param widthSpec The widthSpec that was passing into RecyclerView's onMeasure
+         * @param heightSpec The heightSpec that was passing into RecyclerView's onMeasure
+         */
+        void setMeasuredDimensionFromChildren(int widthSpec, int heightSpec) {
+            final int count = getChildCount();
+            if (count == 0) {
+                mRecyclerView.defaultOnMeasure(widthSpec, heightSpec);
+                return;
+            }
+            int minX = Integer.MAX_VALUE;
+            int minY = Integer.MAX_VALUE;
+            int maxX = Integer.MIN_VALUE;
+            int maxY = Integer.MIN_VALUE;
+
+            for (int i = 0; i < count; i++) {
+                View child = getChildAt(i);
+                final Rect bounds = mRecyclerView.mTempRect;
+                getDecoratedBoundsWithMargins(child, bounds);
+                if (bounds.left < minX) {
+                    minX = bounds.left;
+                }
+                if (bounds.right > maxX) {
+                    maxX = bounds.right;
+                }
+                if (bounds.top < minY) {
+                    minY = bounds.top;
+                }
+                if (bounds.bottom > maxY) {
+                    maxY = bounds.bottom;
+                }
+            }
+            mRecyclerView.mTempRect.set(minX, minY, maxX, maxY);
+            setMeasuredDimension(mRecyclerView.mTempRect, widthSpec, heightSpec);
+        }
+
+        /**
+         * Sets the measured dimensions from the given bounding box of the children and the
+         * measurement specs that were passed into {@link RecyclerView#onMeasure(int, int)}. It is
+         * called after the RecyclerView calls
+         * {@link LayoutManager#onLayoutChildren(Recycler, State)} during a measurement pass.
+         * <p>
+         * This method should call {@link #setMeasuredDimension(int, int)}.
+         * <p>
+         * The default implementation adds the RecyclerView's padding to the given bounding box
+         * then caps the value to be within the given measurement specs.
+         * <p>
+         * This method is only called if the LayoutManager opted into the auto measurement API.
+         *
+         * @param childrenBounds The bounding box of all children
+         * @param wSpec The widthMeasureSpec that was passed into the RecyclerView.
+         * @param hSpec The heightMeasureSpec that was passed into the RecyclerView.
+         *
+         * @see #setAutoMeasureEnabled(boolean)
+         */
+        public void setMeasuredDimension(Rect childrenBounds, int wSpec, int hSpec) {
+            int usedWidth = childrenBounds.width() + getPaddingLeft() + getPaddingRight();
+            int usedHeight = childrenBounds.height() + getPaddingTop() + getPaddingBottom();
+            int width = chooseSize(wSpec, usedWidth, getMinimumWidth());
+            int height = chooseSize(hSpec, usedHeight, getMinimumHeight());
+            setMeasuredDimension(width, height);
+        }
+
+        /**
+         * Calls {@code RecyclerView#requestLayout} on the underlying RecyclerView
+         */
+        public void requestLayout() {
+            if (mRecyclerView != null) {
+                mRecyclerView.requestLayout();
+            }
+        }
+
+        /**
+         * Checks if RecyclerView is in the middle of a layout or scroll and throws an
+         * {@link IllegalStateException} if it <b>is not</b>.
+         *
+         * @param message The message for the exception. Can be null.
+         * @see #assertNotInLayoutOrScroll(String)
+         */
+        public void assertInLayoutOrScroll(String message) {
+            if (mRecyclerView != null) {
+                mRecyclerView.assertInLayoutOrScroll(message);
+            }
+        }
+
+        /**
+         * Chooses a size from the given specs and parameters that is closest to the desired size
+         * and also complies with the spec.
+         *
+         * @param spec The measureSpec
+         * @param desired The preferred measurement
+         * @param min The minimum value
+         *
+         * @return A size that fits to the given specs
+         */
+        public static int chooseSize(int spec, int desired, int min) {
+            final int mode = View.MeasureSpec.getMode(spec);
+            final int size = View.MeasureSpec.getSize(spec);
+            switch (mode) {
+                case View.MeasureSpec.EXACTLY:
+                    return size;
+                case View.MeasureSpec.AT_MOST:
+                    return Math.min(size, Math.max(desired, min));
+                case View.MeasureSpec.UNSPECIFIED:
+                default:
+                    return Math.max(desired, min);
+            }
+        }
+
+        /**
+         * Checks if RecyclerView is in the middle of a layout or scroll and throws an
+         * {@link IllegalStateException} if it <b>is</b>.
+         *
+         * @param message The message for the exception. Can be null.
+         * @see #assertInLayoutOrScroll(String)
+         */
+        public void assertNotInLayoutOrScroll(String message) {
+            if (mRecyclerView != null) {
+                mRecyclerView.assertNotInLayoutOrScroll(message);
+            }
+        }
+
+        /**
+         * Defines whether the layout should be measured by the RecyclerView or the LayoutManager
+         * wants to handle the layout measurements itself.
+         * <p>
+         * This method is usually called by the LayoutManager with value {@code true} if it wants
+         * to support WRAP_CONTENT. If you are using a public LayoutManager but want to customize
+         * the measurement logic, you can call this method with {@code false} and override
+         * {@link LayoutManager#onMeasure(int, int)} to implement your custom measurement logic.
+         * <p>
+         * AutoMeasure is a convenience mechanism for LayoutManagers to easily wrap their content or
+         * handle various specs provided by the RecyclerView's parent.
+         * It works by calling {@link LayoutManager#onLayoutChildren(Recycler, State)} during an
+         * {@link RecyclerView#onMeasure(int, int)} call, then calculating desired dimensions based
+         * on children's positions. It does this while supporting all existing animation
+         * capabilities of the RecyclerView.
+         * <p>
+         * AutoMeasure works as follows:
+         * <ol>
+         * <li>LayoutManager should call {@code setAutoMeasureEnabled(true)} to enable it. All of
+         * the framework LayoutManagers use {@code auto-measure}.</li>
+         * <li>When {@link RecyclerView#onMeasure(int, int)} is called, if the provided specs are
+         * exact, RecyclerView will only call LayoutManager's {@code onMeasure} and return without
+         * doing any layout calculation.</li>
+         * <li>If one of the layout specs is not {@code EXACT}, the RecyclerView will start the
+         * layout process in {@code onMeasure} call. It will process all pending Adapter updates and
+         * decide whether to run a predictive layout or not. If it decides to do so, it will first
+         * call {@link #onLayoutChildren(Recycler, State)} with {@link State#isPreLayout()} set to
+         * {@code true}. At this stage, {@link #getWidth()} and {@link #getHeight()} will still
+         * return the width and height of the RecyclerView as of the last layout calculation.
+         * <p>
+         * After handling the predictive case, RecyclerView will call
+         * {@link #onLayoutChildren(Recycler, State)} with {@link State#isMeasuring()} set to
+         * {@code true} and {@link State#isPreLayout()} set to {@code false}. The LayoutManager can
+         * access the measurement specs via {@link #getHeight()}, {@link #getHeightMode()},
+         * {@link #getWidth()} and {@link #getWidthMode()}.</li>
+         * <li>After the layout calculation, RecyclerView sets the measured width & height by
+         * calculating the bounding box for the children (+ RecyclerView's padding). The
+         * LayoutManagers can override {@link #setMeasuredDimension(Rect, int, int)} to choose
+         * different values. For instance, GridLayoutManager overrides this value to handle the case
+         * where if it is vertical and has 3 columns but only 2 items, it should still measure its
+         * width to fit 3 items, not 2.</li>
+         * <li>Any following on measure call to the RecyclerView will run
+         * {@link #onLayoutChildren(Recycler, State)} with {@link State#isMeasuring()} set to
+         * {@code true} and {@link State#isPreLayout()} set to {@code false}. RecyclerView will
+         * take care of which views are actually added / removed / moved / changed for animations so
+         * that the LayoutManager should not worry about them and handle each
+         * {@link #onLayoutChildren(Recycler, State)} call as if it is the last one.
+         * </li>
+         * <li>When measure is complete and RecyclerView's
+         * {@link #onLayout(boolean, int, int, int, int)} method is called, RecyclerView checks
+         * whether it already did layout calculations during the measure pass and if so, it re-uses
+         * that information. It may still decide to call {@link #onLayoutChildren(Recycler, State)}
+         * if the last measure spec was different from the final dimensions or adapter contents
+         * have changed between the measure call and the layout call.</li>
+         * <li>Finally, animations are calculated and run as usual.</li>
+         * </ol>
+         *
+         * @param enabled <code>True</code> if the Layout should be measured by the
+         *                             RecyclerView, <code>false</code> if the LayoutManager wants
+         *                             to measure itself.
+         *
+         * @see #setMeasuredDimension(Rect, int, int)
+         * @see #isAutoMeasureEnabled()
+         */
+        public void setAutoMeasureEnabled(boolean enabled) {
+            mAutoMeasure = enabled;
+        }
+
+        /**
+         * Returns whether the LayoutManager uses the automatic measurement API or not.
+         *
+         * @return <code>True</code> if the LayoutManager is measured by the RecyclerView or
+         * <code>false</code> if it measures itself.
+         *
+         * @see #setAutoMeasureEnabled(boolean)
+         */
+        public boolean isAutoMeasureEnabled() {
+            return mAutoMeasure;
+        }
+
+        /**
+         * Returns whether this LayoutManager supports automatic item animations.
+         * A LayoutManager wishing to support item animations should obey certain
+         * rules as outlined in {@link #onLayoutChildren(Recycler, State)}.
+         * The default return value is <code>false</code>, so subclasses of LayoutManager
+         * will not get predictive item animations by default.
+         *
+         * <p>Whether item animations are enabled in a RecyclerView is determined both
+         * by the return value from this method and the
+         * {@link RecyclerView#setItemAnimator(ItemAnimator) ItemAnimator} set on the
+         * RecyclerView itself. If the RecyclerView has a non-null ItemAnimator but this
+         * method returns false, then simple item animations will be enabled, in which
+         * views that are moving onto or off of the screen are simply faded in/out. If
+         * the RecyclerView has a non-null ItemAnimator and this method returns true,
+         * then there will be two calls to {@link #onLayoutChildren(Recycler, State)} to
+         * setup up the information needed to more intelligently predict where appearing
+         * and disappearing views should be animated from/to.</p>
+         *
+         * @return true if predictive item animations should be enabled, false otherwise
+         */
+        public boolean supportsPredictiveItemAnimations() {
+            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;
+                mPrefetchMaxCountObserved = 0;
+                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;
+        }
+
+        /**
+         * Gather all positions from the LayoutManager to be prefetched, given specified momentum.
+         *
+         * <p>If item prefetch is enabled, this method is called in between traversals to gather
+         * which positions the LayoutManager will soon need, given upcoming movement in subsequent
+         * traversals.</p>
+         *
+         * <p>The LayoutManager should call {@link LayoutPrefetchRegistry#addPosition(int, int)} for
+         * each item to be prepared, and these positions will have their ViewHolders created and
+         * bound, if there is sufficient time available, in advance of being needed by a
+         * scroll or layout.</p>
+         *
+         * @param dx X movement component.
+         * @param dy Y movement component.
+         * @param state State of RecyclerView
+         * @param layoutPrefetchRegistry PrefetchRegistry to add prefetch entries into.
+         *
+         * @see #isItemPrefetchEnabled()
+         * @see #collectInitialPrefetchPositions(int, LayoutPrefetchRegistry)
+         */
+        public void collectAdjacentPrefetchPositions(int dx, int dy, State state,
+                LayoutPrefetchRegistry layoutPrefetchRegistry) {}
+
+        /**
+         * Gather all positions from the LayoutManager to be prefetched in preperation for its
+         * RecyclerView to come on screen, due to the movement of another, containing RecyclerView.
+         *
+         * <p>This method is only called when a RecyclerView is nested in another RecyclerView.</p>
+         *
+         * <p>If item prefetch is enabled for this LayoutManager, as well in another containing
+         * LayoutManager, this method is called in between draw traversals to gather
+         * which positions this LayoutManager will first need, once it appears on the screen.</p>
+         *
+         * <p>For example, if this LayoutManager represents a horizontally scrolling list within a
+         * vertically scrolling LayoutManager, this method would be called when the horizontal list
+         * is about to come onscreen.</p>
+         *
+         * <p>The LayoutManager should call {@link LayoutPrefetchRegistry#addPosition(int, int)} for
+         * each item to be prepared, and these positions will have their ViewHolders created and
+         * bound, if there is sufficient time available, in advance of being needed by a
+         * scroll or layout.</p>
+         *
+         * @param adapterItemCount number of items in the associated adapter.
+         * @param layoutPrefetchRegistry PrefetchRegistry to add prefetch entries into.
+         *
+         * @see #isItemPrefetchEnabled()
+         * @see #collectAdjacentPrefetchPositions(int, int, State, LayoutPrefetchRegistry)
+         */
+        public void collectInitialPrefetchPositions(int adapterItemCount,
+                LayoutPrefetchRegistry layoutPrefetchRegistry) {}
+
+        void dispatchAttachedToWindow(RecyclerView view) {
+            mIsAttachedToWindow = true;
+            onAttachedToWindow(view);
+        }
+
+        void dispatchDetachedFromWindow(RecyclerView view, Recycler recycler) {
+            mIsAttachedToWindow = false;
+            onDetachedFromWindow(view, recycler);
+        }
+
+        /**
+         * Returns whether LayoutManager is currently attached to a RecyclerView which is attached
+         * to a window.
+         *
+         * @return True if this LayoutManager is controlling a RecyclerView and the RecyclerView
+         * is attached to window.
+         */
+        public boolean isAttachedToWindow() {
+            return mIsAttachedToWindow;
+        }
+
+        /**
+         * Causes the Runnable to execute on the next animation time step.
+         * The runnable will be run on the user interface thread.
+         * <p>
+         * Calling this method when LayoutManager is not attached to a RecyclerView has no effect.
+         *
+         * @param action The Runnable that will be executed.
+         *
+         * @see #removeCallbacks
+         */
+        public void postOnAnimation(Runnable action) {
+            if (mRecyclerView != null) {
+                mRecyclerView.postOnAnimation(action);
+            }
+        }
+
+        /**
+         * Removes the specified Runnable from the message queue.
+         * <p>
+         * Calling this method when LayoutManager is not attached to a RecyclerView has no effect.
+         *
+         * @param action The Runnable to remove from the message handling queue
+         *
+         * @return true if RecyclerView could ask the Handler to remove the Runnable,
+         *         false otherwise. When the returned value is true, the Runnable
+         *         may or may not have been actually removed from the message queue
+         *         (for instance, if the Runnable was not in the queue already.)
+         *
+         * @see #postOnAnimation
+         */
+        public boolean removeCallbacks(Runnable action) {
+            if (mRecyclerView != null) {
+                return mRecyclerView.removeCallbacks(action);
+            }
+            return false;
+        }
+        /**
+         * Called when this LayoutManager is both attached to a RecyclerView and that RecyclerView
+         * is attached to a window.
+         * <p>
+         * If the RecyclerView is re-attached with the same LayoutManager and Adapter, it may not
+         * call {@link #onLayoutChildren(Recycler, State)} if nothing has changed and a layout was
+         * not requested on the RecyclerView while it was detached.
+         * <p>
+         * Subclass implementations should always call through to the superclass implementation.
+         *
+         * @param view The RecyclerView this LayoutManager is bound to
+         *
+         * @see #onDetachedFromWindow(RecyclerView, Recycler)
+         */
+        @CallSuper
+        public void onAttachedToWindow(RecyclerView view) {
+        }
+
+        /**
+         * @deprecated
+         * override {@link #onDetachedFromWindow(RecyclerView, Recycler)}
+         */
+        @Deprecated
+        public void onDetachedFromWindow(RecyclerView view) {
+
+        }
+
+        /**
+         * Called when this LayoutManager is detached from its parent RecyclerView or when
+         * its parent RecyclerView is detached from its window.
+         * <p>
+         * LayoutManager should clear all of its View references as another LayoutManager might be
+         * assigned to the RecyclerView.
+         * <p>
+         * If the RecyclerView is re-attached with the same LayoutManager and Adapter, it may not
+         * call {@link #onLayoutChildren(Recycler, State)} if nothing has changed and a layout was
+         * not requested on the RecyclerView while it was detached.
+         * <p>
+         * If your LayoutManager has View references that it cleans in on-detach, it should also
+         * call {@link RecyclerView#requestLayout()} to ensure that it is re-laid out when
+         * RecyclerView is re-attached.
+         * <p>
+         * Subclass implementations should always call through to the superclass implementation.
+         *
+         * @param view The RecyclerView this LayoutManager is bound to
+         * @param recycler The recycler to use if you prefer to recycle your children instead of
+         *                 keeping them around.
+         *
+         * @see #onAttachedToWindow(RecyclerView)
+         */
+        @CallSuper
+        public void onDetachedFromWindow(RecyclerView view, Recycler recycler) {
+            onDetachedFromWindow(view);
+        }
+
+        /**
+         * Check if the RecyclerView is configured to clip child views to its padding.
+         *
+         * @return true if this RecyclerView clips children to its padding, false otherwise
+         */
+        public boolean getClipToPadding() {
+            return mRecyclerView != null && mRecyclerView.mClipToPadding;
+        }
+
+        /**
+         * Lay out all relevant child views from the given adapter.
+         *
+         * The LayoutManager is in charge of the behavior of item animations. By default,
+         * RecyclerView has a non-null {@link #getItemAnimator() ItemAnimator}, and simple
+         * item animations are enabled. This means that add/remove operations on the
+         * adapter will result in animations to add new or appearing items, removed or
+         * disappearing items, and moved items. If a LayoutManager returns false from
+         * {@link #supportsPredictiveItemAnimations()}, which is the default, and runs a
+         * normal layout operation during {@link #onLayoutChildren(Recycler, State)}, the
+         * RecyclerView will have enough information to run those animations in a simple
+         * way. For example, the default ItemAnimator, {@link DefaultItemAnimator}, will
+         * simply fade views in and out, whether they are actually added/removed or whether
+         * they are moved on or off the screen due to other add/remove operations.
+         *
+         * <p>A LayoutManager wanting a better item animation experience, where items can be
+         * animated onto and off of the screen according to where the items exist when they
+         * are not on screen, then the LayoutManager should return true from
+         * {@link #supportsPredictiveItemAnimations()} and add additional logic to
+         * {@link #onLayoutChildren(Recycler, State)}. Supporting predictive animations
+         * means that {@link #onLayoutChildren(Recycler, State)} will be called twice;
+         * once as a "pre" layout step to determine where items would have been prior to
+         * a real layout, and again to do the "real" layout. In the pre-layout phase,
+         * items will remember their pre-layout positions to allow them to be laid out
+         * appropriately. Also, {@link LayoutParams#isItemRemoved() removed} items will
+         * be returned from the scrap to help determine correct placement of other items.
+         * These removed items should not be added to the child list, but should be used
+         * to help calculate correct positioning of other views, including views that
+         * were not previously onscreen (referred to as APPEARING views), but whose
+         * pre-layout offscreen position can be determined given the extra
+         * information about the pre-layout removed views.</p>
+         *
+         * <p>The second layout pass is the real layout in which only non-removed views
+         * will be used. The only additional requirement during this pass is, if
+         * {@link #supportsPredictiveItemAnimations()} returns true, to note which
+         * views exist in the child list prior to layout and which are not there after
+         * layout (referred to as DISAPPEARING views), and to position/layout those views
+         * appropriately, without regard to the actual bounds of the RecyclerView. This allows
+         * the animation system to know the location to which to animate these disappearing
+         * views.</p>
+         *
+         * <p>The default LayoutManager implementations for RecyclerView handle all of these
+         * requirements for animations already. Clients of RecyclerView can either use one
+         * of these layout managers directly or look at their implementations of
+         * onLayoutChildren() to see how they account for the APPEARING and
+         * DISAPPEARING views.</p>
+         *
+         * @param recycler         Recycler to use for fetching potentially cached views for a
+         *                         position
+         * @param state            Transient state of RecyclerView
+         */
+        public void onLayoutChildren(Recycler recycler, State state) {
+            Log.e(TAG, "You must override onLayoutChildren(Recycler recycler, State state) ");
+        }
+
+        /**
+         * Called after a full layout calculation is finished. The layout calculation may include
+         * multiple {@link #onLayoutChildren(Recycler, State)} calls due to animations or
+         * layout measurement but it will include only one {@link #onLayoutCompleted(State)} call.
+         * This method will be called at the end of {@link View#layout(int, int, int, int)} call.
+         * <p>
+         * This is a good place for the LayoutManager to do some cleanup like pending scroll
+         * position, saved state etc.
+         *
+         * @param state Transient state of RecyclerView
+         */
+        public void onLayoutCompleted(State state) {
+        }
+
+        /**
+         * Create a default <code>LayoutParams</code> object for a child of the RecyclerView.
+         *
+         * <p>LayoutManagers will often want to use a custom <code>LayoutParams</code> type
+         * to store extra information specific to the layout. Client code should subclass
+         * {@link RecyclerView.LayoutParams} for this purpose.</p>
+         *
+         * <p><em>Important:</em> if you use your own custom <code>LayoutParams</code> type
+         * you must also override
+         * {@link #checkLayoutParams(LayoutParams)},
+         * {@link #generateLayoutParams(android.view.ViewGroup.LayoutParams)} and
+         * {@link #generateLayoutParams(android.content.Context, android.util.AttributeSet)}.</p>
+         *
+         * @return A new LayoutParams for a child view
+         */
+        public abstract LayoutParams generateDefaultLayoutParams();
+
+        /**
+         * Determines the validity of the supplied LayoutParams object.
+         *
+         * <p>This should check to make sure that the object is of the correct type
+         * and all values are within acceptable ranges. The default implementation
+         * returns <code>true</code> for non-null params.</p>
+         *
+         * @param lp LayoutParams object to check
+         * @return true if this LayoutParams object is valid, false otherwise
+         */
+        public boolean checkLayoutParams(LayoutParams lp) {
+            return lp != null;
+        }
+
+        /**
+         * Create a LayoutParams object suitable for this LayoutManager, copying relevant
+         * values from the supplied LayoutParams object if possible.
+         *
+         * <p><em>Important:</em> if you use your own custom <code>LayoutParams</code> type
+         * you must also override
+         * {@link #checkLayoutParams(LayoutParams)},
+         * {@link #generateLayoutParams(android.view.ViewGroup.LayoutParams)} and
+         * {@link #generateLayoutParams(android.content.Context, android.util.AttributeSet)}.</p>
+         *
+         * @param lp Source LayoutParams object to copy values from
+         * @return a new LayoutParams object
+         */
+        public LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
+            if (lp instanceof LayoutParams) {
+                return new LayoutParams((LayoutParams) lp);
+            } else if (lp instanceof MarginLayoutParams) {
+                return new LayoutParams((MarginLayoutParams) lp);
+            } else {
+                return new LayoutParams(lp);
+            }
+        }
+
+        /**
+         * Create a LayoutParams object suitable for this LayoutManager from
+         * an inflated layout resource.
+         *
+         * <p><em>Important:</em> if you use your own custom <code>LayoutParams</code> type
+         * you must also override
+         * {@link #checkLayoutParams(LayoutParams)},
+         * {@link #generateLayoutParams(android.view.ViewGroup.LayoutParams)} and
+         * {@link #generateLayoutParams(android.content.Context, android.util.AttributeSet)}.</p>
+         *
+         * @param c Context for obtaining styled attributes
+         * @param attrs AttributeSet describing the supplied arguments
+         * @return a new LayoutParams object
+         */
+        public LayoutParams generateLayoutParams(Context c, AttributeSet attrs) {
+            return new LayoutParams(c, attrs);
+        }
+
+        /**
+         * Scroll horizontally by dx pixels in screen coordinates and return the distance traveled.
+         * The default implementation does nothing and returns 0.
+         *
+         * @param dx            distance to scroll by in pixels. X increases as scroll position
+         *                      approaches the right.
+         * @param recycler      Recycler to use for fetching potentially cached views for a
+         *                      position
+         * @param state         Transient state of RecyclerView
+         * @return The actual distance scrolled. The return value will be negative if dx was
+         * negative and scrolling proceeeded in that direction.
+         * <code>Math.abs(result)</code> may be less than dx if a boundary was reached.
+         */
+        public int scrollHorizontallyBy(int dx, Recycler recycler, State state) {
+            return 0;
+        }
+
+        /**
+         * Scroll vertically by dy pixels in screen coordinates and return the distance traveled.
+         * The default implementation does nothing and returns 0.
+         *
+         * @param dy            distance to scroll in pixels. Y increases as scroll position
+         *                      approaches the bottom.
+         * @param recycler      Recycler to use for fetching potentially cached views for a
+         *                      position
+         * @param state         Transient state of RecyclerView
+         * @return The actual distance scrolled. The return value will be negative if dy was
+         * negative and scrolling proceeeded in that direction.
+         * <code>Math.abs(result)</code> may be less than dy if a boundary was reached.
+         */
+        public int scrollVerticallyBy(int dy, Recycler recycler, State state) {
+            return 0;
+        }
+
+        /**
+         * Query if horizontal scrolling is currently supported. The default implementation
+         * returns false.
+         *
+         * @return True if this LayoutManager can scroll the current contents horizontally
+         */
+        public boolean canScrollHorizontally() {
+            return false;
+        }
+
+        /**
+         * Query if vertical scrolling is currently supported. The default implementation
+         * returns false.
+         *
+         * @return True if this LayoutManager can scroll the current contents vertically
+         */
+        public boolean canScrollVertically() {
+            return false;
+        }
+
+        /**
+         * Scroll to the specified adapter position.
+         *
+         * Actual position of the item on the screen depends on the LayoutManager implementation.
+         * @param position Scroll to this adapter position.
+         */
+        public void scrollToPosition(int position) {
+            if (DEBUG) {
+                Log.e(TAG, "You MUST implement scrollToPosition. It will soon become abstract");
+            }
+        }
+
+        /**
+         * <p>Smooth scroll to the specified adapter position.</p>
+         * <p>To support smooth scrolling, override this method, create your {@link SmoothScroller}
+         * instance and call {@link #startSmoothScroll(SmoothScroller)}.
+         * </p>
+         * @param recyclerView The RecyclerView to which this layout manager is attached
+         * @param state    Current State of RecyclerView
+         * @param position Scroll to this adapter position.
+         */
+        public void smoothScrollToPosition(RecyclerView recyclerView, State state,
+                int position) {
+            Log.e(TAG, "You must override smoothScrollToPosition to support smooth scrolling");
+        }
+
+        /**
+         * <p>Starts a smooth scroll using the provided SmoothScroller.</p>
+         * <p>Calling this method will cancel any previous smooth scroll request.</p>
+         * @param smoothScroller Instance which defines how smooth scroll should be animated
+         */
+        public void startSmoothScroll(SmoothScroller smoothScroller) {
+            if (mSmoothScroller != null && smoothScroller != mSmoothScroller
+                    && mSmoothScroller.isRunning()) {
+                mSmoothScroller.stop();
+            }
+            mSmoothScroller = smoothScroller;
+            mSmoothScroller.start(mRecyclerView, this);
+        }
+
+        /**
+         * @return true if RecycylerView is currently in the state of smooth scrolling.
+         */
+        public boolean isSmoothScrolling() {
+            return mSmoothScroller != null && mSmoothScroller.isRunning();
+        }
+
+
+        /**
+         * Returns the resolved layout direction for this RecyclerView.
+         *
+         * @return {@link android.view.View#LAYOUT_DIRECTION_RTL} if the layout
+         * direction is RTL or returns
+         * {@link android.view.View#LAYOUT_DIRECTION_LTR} if the layout direction
+         * is not RTL.
+         */
+        public int getLayoutDirection() {
+            return mRecyclerView.getLayoutDirection();
+        }
+
+        /**
+         * Ends all animations on the view created by the {@link ItemAnimator}.
+         *
+         * @param view The View for which the animations should be ended.
+         * @see RecyclerView.ItemAnimator#endAnimations()
+         */
+        public void endAnimation(View view) {
+            if (mRecyclerView.mItemAnimator != null) {
+                mRecyclerView.mItemAnimator.endAnimation(getChildViewHolderInt(view));
+            }
+        }
+
+        /**
+         * To be called only during {@link #onLayoutChildren(Recycler, State)} to add a view
+         * to the layout that is known to be going away, either because it has been
+         * {@link Adapter#notifyItemRemoved(int) removed} or because it is actually not in the
+         * visible portion of the container but is being laid out in order to inform RecyclerView
+         * in how to animate the item out of view.
+         * <p>
+         * Views added via this method are going to be invisible to LayoutManager after the
+         * dispatchLayout pass is complete. They cannot be retrieved via {@link #getChildAt(int)}
+         * or won't be included in {@link #getChildCount()} method.
+         *
+         * @param child View to add and then remove with animation.
+         */
+        public void addDisappearingView(View child) {
+            addDisappearingView(child, -1);
+        }
+
+        /**
+         * To be called only during {@link #onLayoutChildren(Recycler, State)} to add a view
+         * to the layout that is known to be going away, either because it has been
+         * {@link Adapter#notifyItemRemoved(int) removed} or because it is actually not in the
+         * visible portion of the container but is being laid out in order to inform RecyclerView
+         * in how to animate the item out of view.
+         * <p>
+         * Views added via this method are going to be invisible to LayoutManager after the
+         * dispatchLayout pass is complete. They cannot be retrieved via {@link #getChildAt(int)}
+         * or won't be included in {@link #getChildCount()} method.
+         *
+         * @param child View to add and then remove with animation.
+         * @param index Index of the view.
+         */
+        public void addDisappearingView(View child, int index) {
+            addViewInt(child, index, true);
+        }
+
+        /**
+         * Add a view to the currently attached RecyclerView if needed. LayoutManagers should
+         * use this method to add views obtained from a {@link Recycler} using
+         * {@link Recycler#getViewForPosition(int)}.
+         *
+         * @param child View to add
+         */
+        public void addView(View child) {
+            addView(child, -1);
+        }
+
+        /**
+         * Add a view to the currently attached RecyclerView if needed. LayoutManagers should
+         * use this method to add views obtained from a {@link Recycler} using
+         * {@link Recycler#getViewForPosition(int)}.
+         *
+         * @param child View to add
+         * @param index Index to add child at
+         */
+        public void addView(View child, int index) {
+            addViewInt(child, index, false);
+        }
+
+        private void addViewInt(View child, int index, boolean disappearing) {
+            final ViewHolder holder = getChildViewHolderInt(child);
+            if (disappearing || holder.isRemoved()) {
+                // these views will be hidden at the end of the layout pass.
+                mRecyclerView.mViewInfoStore.addToDisappearedInLayout(holder);
+            } else {
+                // This may look like unnecessary but may happen if layout manager supports
+                // predictive layouts and adapter removed then re-added the same item.
+                // In this case, added version will be visible in the post layout (because add is
+                // deferred) but RV will still bind it to the same View.
+                // So if a View re-appears in post layout pass, remove it from disappearing list.
+                mRecyclerView.mViewInfoStore.removeFromDisappearedInLayout(holder);
+            }
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            if (holder.wasReturnedFromScrap() || holder.isScrap()) {
+                if (holder.isScrap()) {
+                    holder.unScrap();
+                } else {
+                    holder.clearReturnedFromScrapFlag();
+                }
+                mChildHelper.attachViewToParent(child, index, child.getLayoutParams(), false);
+                if (DISPATCH_TEMP_DETACH) {
+                    child.dispatchFinishTemporaryDetach();
+                }
+            } else if (child.getParent() == mRecyclerView) { // it was not a scrap but a valid child
+                // ensure in correct position
+                int currentIndex = mChildHelper.indexOfChild(child);
+                if (index == -1) {
+                    index = mChildHelper.getChildCount();
+                }
+                if (currentIndex == -1) {
+                    throw new IllegalStateException("Added View has RecyclerView as parent but"
+                            + " view is not a real child. Unfiltered index:"
+                            + mRecyclerView.indexOfChild(child));
+                }
+                if (currentIndex != index) {
+                    mRecyclerView.mLayout.moveView(currentIndex, index);
+                }
+            } else {
+                mChildHelper.addView(child, index, false);
+                lp.mInsetsDirty = true;
+                if (mSmoothScroller != null && mSmoothScroller.isRunning()) {
+                    mSmoothScroller.onChildAttachedToWindow(child);
+                }
+            }
+            if (lp.mPendingInvalidate) {
+                if (DEBUG) {
+                    Log.d(TAG, "consuming pending invalidate on child " + lp.mViewHolder);
+                }
+                holder.itemView.invalidate();
+                lp.mPendingInvalidate = false;
+            }
+        }
+
+        /**
+         * Remove a view from the currently attached RecyclerView if needed. LayoutManagers should
+         * use this method to completely remove a child view that is no longer needed.
+         * LayoutManagers should strongly consider recycling removed views using
+         * {@link Recycler#recycleView(android.view.View)}.
+         *
+         * @param child View to remove
+         */
+        public void removeView(View child) {
+            mChildHelper.removeView(child);
+        }
+
+        /**
+         * Remove a view from the currently attached RecyclerView if needed. LayoutManagers should
+         * use this method to completely remove a child view that is no longer needed.
+         * LayoutManagers should strongly consider recycling removed views using
+         * {@link Recycler#recycleView(android.view.View)}.
+         *
+         * @param index Index of the child view to remove
+         */
+        public void removeViewAt(int index) {
+            final View child = getChildAt(index);
+            if (child != null) {
+                mChildHelper.removeViewAt(index);
+            }
+        }
+
+        /**
+         * Remove all views from the currently attached RecyclerView. This will not recycle
+         * any of the affected views; the LayoutManager is responsible for doing so if desired.
+         */
+        public void removeAllViews() {
+            // Only remove non-animating views
+            final int childCount = getChildCount();
+            for (int i = childCount - 1; i >= 0; i--) {
+                mChildHelper.removeViewAt(i);
+            }
+        }
+
+        /**
+         * Returns offset of the RecyclerView's text baseline from the its top boundary.
+         *
+         * @return The offset of the RecyclerView's text baseline from the its top boundary; -1 if
+         * there is no baseline.
+         */
+        public int getBaseline() {
+            return -1;
+        }
+
+        /**
+         * Returns the adapter position of the item represented by the given View. This does not
+         * contain any adapter changes that might have happened after the last layout.
+         *
+         * @param view The view to query
+         * @return The adapter position of the item which is rendered by this View.
+         */
+        public int getPosition(View view) {
+            return ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
+        }
+
+        /**
+         * Returns the View type defined by the adapter.
+         *
+         * @param view The view to query
+         * @return The type of the view assigned by the adapter.
+         */
+        public int getItemViewType(View view) {
+            return getChildViewHolderInt(view).getItemViewType();
+        }
+
+        /**
+         * Traverses the ancestors of the given view and returns the item view that contains it
+         * and also a direct child of the LayoutManager.
+         * <p>
+         * Note that this method may return null if the view is a child of the RecyclerView but
+         * not a child of the LayoutManager (e.g. running a disappear animation).
+         *
+         * @param view The view that is a descendant of the LayoutManager.
+         *
+         * @return The direct child of the LayoutManager which contains the given view or null if
+         * the provided view is not a descendant of this LayoutManager.
+         *
+         * @see RecyclerView#getChildViewHolder(View)
+         * @see RecyclerView#findContainingViewHolder(View)
+         */
+        @Nullable
+        public View findContainingItemView(View view) {
+            if (mRecyclerView == null) {
+                return null;
+            }
+            View found = mRecyclerView.findContainingItemView(view);
+            if (found == null) {
+                return null;
+            }
+            if (mChildHelper.isHidden(found)) {
+                return null;
+            }
+            return found;
+        }
+
+        /**
+         * Finds the view which represents the given adapter position.
+         * <p>
+         * This method traverses each child since it has no information about child order.
+         * Override this method to improve performance if your LayoutManager keeps data about
+         * child views.
+         * <p>
+         * If a view is ignored via {@link #ignoreView(View)}, it is also ignored by this method.
+         *
+         * @param position Position of the item in adapter
+         * @return The child view that represents the given position or null if the position is not
+         * laid out
+         */
+        public View findViewByPosition(int position) {
+            final int childCount = getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                View child = getChildAt(i);
+                ViewHolder vh = getChildViewHolderInt(child);
+                if (vh == null) {
+                    continue;
+                }
+                if (vh.getLayoutPosition() == position && !vh.shouldIgnore()
+                        && (mRecyclerView.mState.isPreLayout() || !vh.isRemoved())) {
+                    return child;
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Temporarily detach a child view.
+         *
+         * <p>LayoutManagers may want to perform a lightweight detach operation to rearrange
+         * views currently attached to the RecyclerView. Generally LayoutManager implementations
+         * will want to use {@link #detachAndScrapView(android.view.View, RecyclerView.Recycler)}
+         * so that the detached view may be rebound and reused.</p>
+         *
+         * <p>If a LayoutManager uses this method to detach a view, it <em>must</em>
+         * {@link #attachView(android.view.View, int, RecyclerView.LayoutParams) reattach}
+         * or {@link #removeDetachedView(android.view.View) fully remove} the detached view
+         * before the LayoutManager entry point method called by RecyclerView returns.</p>
+         *
+         * @param child Child to detach
+         */
+        public void detachView(View child) {
+            final int ind = mChildHelper.indexOfChild(child);
+            if (ind >= 0) {
+                detachViewInternal(ind, child);
+            }
+        }
+
+        /**
+         * Temporarily detach a child view.
+         *
+         * <p>LayoutManagers may want to perform a lightweight detach operation to rearrange
+         * views currently attached to the RecyclerView. Generally LayoutManager implementations
+         * will want to use {@link #detachAndScrapView(android.view.View, RecyclerView.Recycler)}
+         * so that the detached view may be rebound and reused.</p>
+         *
+         * <p>If a LayoutManager uses this method to detach a view, it <em>must</em>
+         * {@link #attachView(android.view.View, int, RecyclerView.LayoutParams) reattach}
+         * or {@link #removeDetachedView(android.view.View) fully remove} the detached view
+         * before the LayoutManager entry point method called by RecyclerView returns.</p>
+         *
+         * @param index Index of the child to detach
+         */
+        public void detachViewAt(int index) {
+            detachViewInternal(index, getChildAt(index));
+        }
+
+        private void detachViewInternal(int index, View view) {
+            if (DISPATCH_TEMP_DETACH) {
+                view.dispatchStartTemporaryDetach();
+            }
+            mChildHelper.detachViewFromParent(index);
+        }
+
+        /**
+         * Reattach a previously {@link #detachView(android.view.View) detached} view.
+         * This method should not be used to reattach views that were previously
+         * {@link #detachAndScrapView(android.view.View, RecyclerView.Recycler)}  scrapped}.
+         *
+         * @param child Child to reattach
+         * @param index Intended child index for child
+         * @param lp LayoutParams for child
+         */
+        public void attachView(View child, int index, LayoutParams lp) {
+            ViewHolder vh = getChildViewHolderInt(child);
+            if (vh.isRemoved()) {
+                mRecyclerView.mViewInfoStore.addToDisappearedInLayout(vh);
+            } else {
+                mRecyclerView.mViewInfoStore.removeFromDisappearedInLayout(vh);
+            }
+            mChildHelper.attachViewToParent(child, index, lp, vh.isRemoved());
+            if (DISPATCH_TEMP_DETACH)  {
+                child.dispatchFinishTemporaryDetach();
+            }
+        }
+
+        /**
+         * Reattach a previously {@link #detachView(android.view.View) detached} view.
+         * This method should not be used to reattach views that were previously
+         * {@link #detachAndScrapView(android.view.View, RecyclerView.Recycler)}  scrapped}.
+         *
+         * @param child Child to reattach
+         * @param index Intended child index for child
+         */
+        public void attachView(View child, int index) {
+            attachView(child, index, (LayoutParams) child.getLayoutParams());
+        }
+
+        /**
+         * Reattach a previously {@link #detachView(android.view.View) detached} view.
+         * This method should not be used to reattach views that were previously
+         * {@link #detachAndScrapView(android.view.View, RecyclerView.Recycler)}  scrapped}.
+         *
+         * @param child Child to reattach
+         */
+        public void attachView(View child) {
+            attachView(child, -1);
+        }
+
+        /**
+         * Finish removing a view that was previously temporarily
+         * {@link #detachView(android.view.View) detached}.
+         *
+         * @param child Detached child to remove
+         */
+        public void removeDetachedView(View child) {
+            mRecyclerView.removeDetachedView(child, false);
+        }
+
+        /**
+         * Moves a View from one position to another.
+         *
+         * @param fromIndex The View's initial index
+         * @param toIndex The View's target index
+         */
+        public void moveView(int fromIndex, int toIndex) {
+            View view = getChildAt(fromIndex);
+            if (view == null) {
+                throw new IllegalArgumentException("Cannot move a child from non-existing index:"
+                        + fromIndex);
+            }
+            detachViewAt(fromIndex);
+            attachView(view, toIndex);
+        }
+
+        /**
+         * Detach a child view and add it to a {@link Recycler Recycler's} scrap heap.
+         *
+         * <p>Scrapping a view allows it to be rebound and reused to show updated or
+         * different data.</p>
+         *
+         * @param child Child to detach and scrap
+         * @param recycler Recycler to deposit the new scrap view into
+         */
+        public void detachAndScrapView(View child, Recycler recycler) {
+            int index = mChildHelper.indexOfChild(child);
+            scrapOrRecycleView(recycler, index, child);
+        }
+
+        /**
+         * Detach a child view and add it to a {@link Recycler Recycler's} scrap heap.
+         *
+         * <p>Scrapping a view allows it to be rebound and reused to show updated or
+         * different data.</p>
+         *
+         * @param index Index of child to detach and scrap
+         * @param recycler Recycler to deposit the new scrap view into
+         */
+        public void detachAndScrapViewAt(int index, Recycler recycler) {
+            final View child = getChildAt(index);
+            scrapOrRecycleView(recycler, index, child);
+        }
+
+        /**
+         * Remove a child view and recycle it using the given Recycler.
+         *
+         * @param child Child to remove and recycle
+         * @param recycler Recycler to use to recycle child
+         */
+        public void removeAndRecycleView(View child, Recycler recycler) {
+            removeView(child);
+            recycler.recycleView(child);
+        }
+
+        /**
+         * Remove a child view and recycle it using the given Recycler.
+         *
+         * @param index Index of child to remove and recycle
+         * @param recycler Recycler to use to recycle child
+         */
+        public void removeAndRecycleViewAt(int index, Recycler recycler) {
+            final View view = getChildAt(index);
+            removeViewAt(index);
+            recycler.recycleView(view);
+        }
+
+        /**
+         * Return the current number of child views attached to the parent RecyclerView.
+         * This does not include child views that were temporarily detached and/or scrapped.
+         *
+         * @return Number of attached children
+         */
+        public int getChildCount() {
+            return mChildHelper != null ? mChildHelper.getChildCount() : 0;
+        }
+
+        /**
+         * Return the child view at the given index
+         * @param index Index of child to return
+         * @return Child view at index
+         */
+        public View getChildAt(int index) {
+            return mChildHelper != null ? mChildHelper.getChildAt(index) : null;
+        }
+
+        /**
+         * Return the width measurement spec mode of the RecyclerView.
+         * <p>
+         * This value is set only if the LayoutManager opts into the auto measure api via
+         * {@link #setAutoMeasureEnabled(boolean)}.
+         * <p>
+         * When RecyclerView is running a layout, this value is always set to
+         * {@link View.MeasureSpec#EXACTLY} even if it was measured with a different spec mode.
+         *
+         * @return Width measure spec mode.
+         *
+         * @see View.MeasureSpec#getMode(int)
+         * @see View#onMeasure(int, int)
+         */
+        public int getWidthMode() {
+            return mWidthMode;
+        }
+
+        /**
+         * Return the height measurement spec mode of the RecyclerView.
+         * <p>
+         * This value is set only if the LayoutManager opts into the auto measure api via
+         * {@link #setAutoMeasureEnabled(boolean)}.
+         * <p>
+         * When RecyclerView is running a layout, this value is always set to
+         * {@link View.MeasureSpec#EXACTLY} even if it was measured with a different spec mode.
+         *
+         * @return Height measure spec mode.
+         *
+         * @see View.MeasureSpec#getMode(int)
+         * @see View#onMeasure(int, int)
+         */
+        public int getHeightMode() {
+            return mHeightMode;
+        }
+
+        /**
+         * Return the width of the parent RecyclerView
+         *
+         * @return Width in pixels
+         */
+        public int getWidth() {
+            return mWidth;
+        }
+
+        /**
+         * Return the height of the parent RecyclerView
+         *
+         * @return Height in pixels
+         */
+        public int getHeight() {
+            return mHeight;
+        }
+
+        /**
+         * Return the left padding of the parent RecyclerView
+         *
+         * @return Padding in pixels
+         */
+        public int getPaddingLeft() {
+            return mRecyclerView != null ? mRecyclerView.getPaddingLeft() : 0;
+        }
+
+        /**
+         * Return the top padding of the parent RecyclerView
+         *
+         * @return Padding in pixels
+         */
+        public int getPaddingTop() {
+            return mRecyclerView != null ? mRecyclerView.getPaddingTop() : 0;
+        }
+
+        /**
+         * Return the right padding of the parent RecyclerView
+         *
+         * @return Padding in pixels
+         */
+        public int getPaddingRight() {
+            return mRecyclerView != null ? mRecyclerView.getPaddingRight() : 0;
+        }
+
+        /**
+         * Return the bottom padding of the parent RecyclerView
+         *
+         * @return Padding in pixels
+         */
+        public int getPaddingBottom() {
+            return mRecyclerView != null ? mRecyclerView.getPaddingBottom() : 0;
+        }
+
+        /**
+         * Return the start padding of the parent RecyclerView
+         *
+         * @return Padding in pixels
+         */
+        public int getPaddingStart() {
+            return mRecyclerView != null ? mRecyclerView.getPaddingStart() : 0;
+        }
+
+        /**
+         * Return the end padding of the parent RecyclerView
+         *
+         * @return Padding in pixels
+         */
+        public int getPaddingEnd() {
+            return mRecyclerView != null ? mRecyclerView.getPaddingEnd() : 0;
+        }
+
+        /**
+         * Returns true if the RecyclerView this LayoutManager is bound to has focus.
+         *
+         * @return True if the RecyclerView has focus, false otherwise.
+         * @see View#isFocused()
+         */
+        public boolean isFocused() {
+            return mRecyclerView != null && mRecyclerView.isFocused();
+        }
+
+        /**
+         * Returns true if the RecyclerView this LayoutManager is bound to has or contains focus.
+         *
+         * @return true if the RecyclerView has or contains focus
+         * @see View#hasFocus()
+         */
+        public boolean hasFocus() {
+            return mRecyclerView != null && mRecyclerView.hasFocus();
+        }
+
+        /**
+         * Returns the item View which has or contains focus.
+         *
+         * @return A direct child of RecyclerView which has focus or contains the focused child.
+         */
+        public View getFocusedChild() {
+            if (mRecyclerView == null) {
+                return null;
+            }
+            final View focused = mRecyclerView.getFocusedChild();
+            if (focused == null || mChildHelper.isHidden(focused)) {
+                return null;
+            }
+            return focused;
+        }
+
+        /**
+         * Returns the number of items in the adapter bound to the parent RecyclerView.
+         * <p>
+         * Note that this number is not necessarily equal to
+         * {@link State#getItemCount() State#getItemCount()}. In methods where {@link State} is
+         * available, you should use {@link State#getItemCount() State#getItemCount()} instead.
+         * For more details, check the documentation for
+         * {@link State#getItemCount() State#getItemCount()}.
+         *
+         * @return The number of items in the bound adapter
+         * @see State#getItemCount()
+         */
+        public int getItemCount() {
+            final Adapter a = mRecyclerView != null ? mRecyclerView.getAdapter() : null;
+            return a != null ? a.getItemCount() : 0;
+        }
+
+        /**
+         * Offset all child views attached to the parent RecyclerView by dx pixels along
+         * the horizontal axis.
+         *
+         * @param dx Pixels to offset by
+         */
+        public void offsetChildrenHorizontal(int dx) {
+            if (mRecyclerView != null) {
+                mRecyclerView.offsetChildrenHorizontal(dx);
+            }
+        }
+
+        /**
+         * Offset all child views attached to the parent RecyclerView by dy pixels along
+         * the vertical axis.
+         *
+         * @param dy Pixels to offset by
+         */
+        public void offsetChildrenVertical(int dy) {
+            if (mRecyclerView != null) {
+                mRecyclerView.offsetChildrenVertical(dy);
+            }
+        }
+
+        /**
+         * Flags a view so that it will not be scrapped or recycled.
+         * <p>
+         * Scope of ignoring a child is strictly restricted to position tracking, scrapping and
+         * recyling. Methods like {@link #removeAndRecycleAllViews(Recycler)} will ignore the child
+         * whereas {@link #removeAllViews()} or {@link #offsetChildrenHorizontal(int)} will not
+         * ignore the child.
+         * <p>
+         * Before this child can be recycled again, you have to call
+         * {@link #stopIgnoringView(View)}.
+         * <p>
+         * You can call this method only if your LayoutManger is in onLayout or onScroll callback.
+         *
+         * @param view View to ignore.
+         * @see #stopIgnoringView(View)
+         */
+        public void ignoreView(View view) {
+            if (view.getParent() != mRecyclerView || mRecyclerView.indexOfChild(view) == -1) {
+                // checking this because calling this method on a recycled or detached view may
+                // cause loss of state.
+                throw new IllegalArgumentException("View should be fully attached to be ignored");
+            }
+            final ViewHolder vh = getChildViewHolderInt(view);
+            vh.addFlags(ViewHolder.FLAG_IGNORE);
+            mRecyclerView.mViewInfoStore.removeViewHolder(vh);
+        }
+
+        /**
+         * View can be scrapped and recycled again.
+         * <p>
+         * Note that calling this method removes all information in the view holder.
+         * <p>
+         * You can call this method only if your LayoutManger is in onLayout or onScroll callback.
+         *
+         * @param view View to ignore.
+         */
+        public void stopIgnoringView(View view) {
+            final ViewHolder vh = getChildViewHolderInt(view);
+            vh.stopIgnoring();
+            vh.resetInternal();
+            vh.addFlags(ViewHolder.FLAG_INVALID);
+        }
+
+        /**
+         * Temporarily detach and scrap all currently attached child views. Views will be scrapped
+         * into the given Recycler. The Recycler may prefer to reuse scrap views before
+         * other views that were previously recycled.
+         *
+         * @param recycler Recycler to scrap views into
+         */
+        public void detachAndScrapAttachedViews(Recycler recycler) {
+            final int childCount = getChildCount();
+            for (int i = childCount - 1; i >= 0; i--) {
+                final View v = getChildAt(i);
+                scrapOrRecycleView(recycler, i, v);
+            }
+        }
+
+        private void scrapOrRecycleView(Recycler recycler, int index, View view) {
+            final ViewHolder viewHolder = getChildViewHolderInt(view);
+            if (viewHolder.shouldIgnore()) {
+                if (DEBUG) {
+                    Log.d(TAG, "ignoring view " + viewHolder);
+                }
+                return;
+            }
+            if (viewHolder.isInvalid() && !viewHolder.isRemoved()
+                    && !mRecyclerView.mAdapter.hasStableIds()) {
+                removeViewAt(index);
+                recycler.recycleViewHolderInternal(viewHolder);
+            } else {
+                detachViewAt(index);
+                recycler.scrapView(view);
+                mRecyclerView.mViewInfoStore.onViewDetached(viewHolder);
+            }
+        }
+
+        /**
+         * Recycles the scrapped views.
+         * <p>
+         * When a view is detached and removed, it does not trigger a ViewGroup invalidate. This is
+         * the expected behavior if scrapped views are used for animations. Otherwise, we need to
+         * call remove and invalidate RecyclerView to ensure UI update.
+         *
+         * @param recycler Recycler
+         */
+        void removeAndRecycleScrapInt(Recycler recycler) {
+            final int scrapCount = recycler.getScrapCount();
+            // Loop backward, recycler might be changed by removeDetachedView()
+            for (int i = scrapCount - 1; i >= 0; i--) {
+                final View scrap = recycler.getScrapViewAt(i);
+                final ViewHolder vh = getChildViewHolderInt(scrap);
+                if (vh.shouldIgnore()) {
+                    continue;
+                }
+                // If the scrap view is animating, we need to cancel them first. If we cancel it
+                // here, ItemAnimator callback may recycle it which will cause double recycling.
+                // To avoid this, we mark it as not recycleable before calling the item animator.
+                // Since removeDetachedView calls a user API, a common mistake (ending animations on
+                // the view) may recycle it too, so we guard it before we call user APIs.
+                vh.setIsRecyclable(false);
+                if (vh.isTmpDetached()) {
+                    mRecyclerView.removeDetachedView(scrap, false);
+                }
+                if (mRecyclerView.mItemAnimator != null) {
+                    mRecyclerView.mItemAnimator.endAnimation(vh);
+                }
+                vh.setIsRecyclable(true);
+                recycler.quickRecycleScrapView(scrap);
+            }
+            recycler.clearScrap();
+            if (scrapCount > 0) {
+                mRecyclerView.invalidate();
+            }
+        }
+
+
+        /**
+         * Measure a child view using standard measurement policy, taking the padding
+         * of the parent RecyclerView and any added item decorations into account.
+         *
+         * <p>If the RecyclerView can be scrolled in either dimension the caller may
+         * pass 0 as the widthUsed or heightUsed parameters as they will be irrelevant.</p>
+         *
+         * @param child Child view to measure
+         * @param widthUsed Width in pixels currently consumed by other views, if relevant
+         * @param heightUsed Height in pixels currently consumed by other views, if relevant
+         */
+        public void measureChild(View child, int widthUsed, int heightUsed) {
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            final Rect insets = mRecyclerView.getItemDecorInsetsForChild(child);
+            widthUsed += insets.left + insets.right;
+            heightUsed += insets.top + insets.bottom;
+            final int widthSpec = getChildMeasureSpec(getWidth(), getWidthMode(),
+                    getPaddingLeft() + getPaddingRight() + widthUsed, lp.width,
+                    canScrollHorizontally());
+            final int heightSpec = getChildMeasureSpec(getHeight(), getHeightMode(),
+                    getPaddingTop() + getPaddingBottom() + heightUsed, lp.height,
+                    canScrollVertically());
+            if (shouldMeasureChild(child, widthSpec, heightSpec, lp)) {
+                child.measure(widthSpec, heightSpec);
+            }
+        }
+
+        /**
+         * RecyclerView internally does its own View measurement caching which should help with
+         * WRAP_CONTENT.
+         * <p>
+         * Use this method if the View is already measured once in this layout pass.
+         */
+        boolean shouldReMeasureChild(View child, int widthSpec, int heightSpec, LayoutParams lp) {
+            return !mMeasurementCacheEnabled
+                    || !isMeasurementUpToDate(child.getMeasuredWidth(), widthSpec, lp.width)
+                    || !isMeasurementUpToDate(child.getMeasuredHeight(), heightSpec, lp.height);
+        }
+
+        // we may consider making this public
+        /**
+         * RecyclerView internally does its own View measurement caching which should help with
+         * WRAP_CONTENT.
+         * <p>
+         * Use this method if the View is not yet measured and you need to decide whether to
+         * measure this View or not.
+         */
+        boolean shouldMeasureChild(View child, int widthSpec, int heightSpec, LayoutParams lp) {
+            return child.isLayoutRequested()
+                    || !mMeasurementCacheEnabled
+                    || !isMeasurementUpToDate(child.getWidth(), widthSpec, lp.width)
+                    || !isMeasurementUpToDate(child.getHeight(), heightSpec, lp.height);
+        }
+
+        /**
+         * In addition to the View Framework's measurement cache, RecyclerView uses its own
+         * additional measurement cache for its children to avoid re-measuring them when not
+         * necessary. It is on by default but it can be turned off via
+         * {@link #setMeasurementCacheEnabled(boolean)}.
+         *
+         * @return True if measurement cache is enabled, false otherwise.
+         *
+         * @see #setMeasurementCacheEnabled(boolean)
+         */
+        public boolean isMeasurementCacheEnabled() {
+            return mMeasurementCacheEnabled;
+        }
+
+        /**
+         * Sets whether RecyclerView should use its own measurement cache for the children. This is
+         * a more aggressive cache than the framework uses.
+         *
+         * @param measurementCacheEnabled True to enable the measurement cache, false otherwise.
+         *
+         * @see #isMeasurementCacheEnabled()
+         */
+        public void setMeasurementCacheEnabled(boolean measurementCacheEnabled) {
+            mMeasurementCacheEnabled = measurementCacheEnabled;
+        }
+
+        private static boolean isMeasurementUpToDate(int childSize, int spec, int dimension) {
+            final int specMode = MeasureSpec.getMode(spec);
+            final int specSize = MeasureSpec.getSize(spec);
+            if (dimension > 0 && childSize != dimension) {
+                return false;
+            }
+            switch (specMode) {
+                case MeasureSpec.UNSPECIFIED:
+                    return true;
+                case MeasureSpec.AT_MOST:
+                    return specSize >= childSize;
+                case MeasureSpec.EXACTLY:
+                    return  specSize == childSize;
+            }
+            return false;
+        }
+
+        /**
+         * Measure a child view using standard measurement policy, taking the padding
+         * of the parent RecyclerView, any added item decorations and the child margins
+         * into account.
+         *
+         * <p>If the RecyclerView can be scrolled in either dimension the caller may
+         * pass 0 as the widthUsed or heightUsed parameters as they will be irrelevant.</p>
+         *
+         * @param child Child view to measure
+         * @param widthUsed Width in pixels currently consumed by other views, if relevant
+         * @param heightUsed Height in pixels currently consumed by other views, if relevant
+         */
+        public void measureChildWithMargins(View child, int widthUsed, int heightUsed) {
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+            final Rect insets = mRecyclerView.getItemDecorInsetsForChild(child);
+            widthUsed += insets.left + insets.right;
+            heightUsed += insets.top + insets.bottom;
+
+            final int widthSpec = getChildMeasureSpec(getWidth(), getWidthMode(),
+                    getPaddingLeft() + getPaddingRight()
+                            + lp.leftMargin + lp.rightMargin + widthUsed, lp.width,
+                    canScrollHorizontally());
+            final int heightSpec = getChildMeasureSpec(getHeight(), getHeightMode(),
+                    getPaddingTop() + getPaddingBottom()
+                            + lp.topMargin + lp.bottomMargin + heightUsed, lp.height,
+                    canScrollVertically());
+            if (shouldMeasureChild(child, widthSpec, heightSpec, lp)) {
+                child.measure(widthSpec, heightSpec);
+            }
+        }
+
+        /**
+         * Calculate a MeasureSpec value for measuring a child view in one dimension.
+         *
+         * @param parentSize Size of the parent view where the child will be placed
+         * @param padding Total space currently consumed by other elements of the parent
+         * @param childDimension Desired size of the child view, or MATCH_PARENT/WRAP_CONTENT.
+         *                       Generally obtained from the child view's LayoutParams
+         * @param canScroll true if the parent RecyclerView can scroll in this dimension
+         *
+         * @return a MeasureSpec value for the child view
+         * @deprecated use {@link #getChildMeasureSpec(int, int, int, int, boolean)}
+         */
+        @Deprecated
+        public static int getChildMeasureSpec(int parentSize, int padding, int childDimension,
+                boolean canScroll) {
+            int size = Math.max(0, parentSize - padding);
+            int resultSize = 0;
+            int resultMode = 0;
+            if (canScroll) {
+                if (childDimension >= 0) {
+                    resultSize = childDimension;
+                    resultMode = MeasureSpec.EXACTLY;
+                } else {
+                    // MATCH_PARENT can't be applied since we can scroll in this dimension, wrap
+                    // instead using UNSPECIFIED.
+                    resultSize = 0;
+                    resultMode = MeasureSpec.UNSPECIFIED;
+                }
+            } else {
+                if (childDimension >= 0) {
+                    resultSize = childDimension;
+                    resultMode = MeasureSpec.EXACTLY;
+                } else if (childDimension == LayoutParams.MATCH_PARENT) {
+                    resultSize = size;
+                    // TODO this should be my spec.
+                    resultMode = MeasureSpec.EXACTLY;
+                } else if (childDimension == LayoutParams.WRAP_CONTENT) {
+                    resultSize = size;
+                    resultMode = MeasureSpec.AT_MOST;
+                }
+            }
+            return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
+        }
+
+        /**
+         * Calculate a MeasureSpec value for measuring a child view in one dimension.
+         *
+         * @param parentSize Size of the parent view where the child will be placed
+         * @param parentMode The measurement spec mode of the parent
+         * @param padding Total space currently consumed by other elements of parent
+         * @param childDimension Desired size of the child view, or MATCH_PARENT/WRAP_CONTENT.
+         *                       Generally obtained from the child view's LayoutParams
+         * @param canScroll true if the parent RecyclerView can scroll in this dimension
+         *
+         * @return a MeasureSpec value for the child view
+         */
+        public static int getChildMeasureSpec(int parentSize, int parentMode, int padding,
+                int childDimension, boolean canScroll) {
+            int size = Math.max(0, parentSize - padding);
+            int resultSize = 0;
+            int resultMode = 0;
+            if (canScroll) {
+                if (childDimension >= 0) {
+                    resultSize = childDimension;
+                    resultMode = MeasureSpec.EXACTLY;
+                } else if (childDimension == LayoutParams.MATCH_PARENT) {
+                    switch (parentMode) {
+                        case MeasureSpec.AT_MOST:
+                        case MeasureSpec.EXACTLY:
+                            resultSize = size;
+                            resultMode = parentMode;
+                            break;
+                        case MeasureSpec.UNSPECIFIED:
+                            resultSize = 0;
+                            resultMode = MeasureSpec.UNSPECIFIED;
+                            break;
+                    }
+                } else if (childDimension == LayoutParams.WRAP_CONTENT) {
+                    resultSize = 0;
+                    resultMode = MeasureSpec.UNSPECIFIED;
+                }
+            } else {
+                if (childDimension >= 0) {
+                    resultSize = childDimension;
+                    resultMode = MeasureSpec.EXACTLY;
+                } else if (childDimension == LayoutParams.MATCH_PARENT) {
+                    resultSize = size;
+                    resultMode = parentMode;
+                } else if (childDimension == LayoutParams.WRAP_CONTENT) {
+                    resultSize = size;
+                    if (parentMode == MeasureSpec.AT_MOST || parentMode == MeasureSpec.EXACTLY) {
+                        resultMode = MeasureSpec.AT_MOST;
+                    } else {
+                        resultMode = MeasureSpec.UNSPECIFIED;
+                    }
+
+                }
+            }
+            //noinspection WrongConstant
+            return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
+        }
+
+        /**
+         * Returns the measured width of the given child, plus the additional size of
+         * any insets applied by {@link ItemDecoration ItemDecorations}.
+         *
+         * @param child Child view to query
+         * @return child's measured width plus <code>ItemDecoration</code> insets
+         *
+         * @see View#getMeasuredWidth()
+         */
+        public int getDecoratedMeasuredWidth(View child) {
+            final Rect insets = ((LayoutParams) child.getLayoutParams()).mDecorInsets;
+            return child.getMeasuredWidth() + insets.left + insets.right;
+        }
+
+        /**
+         * Returns the measured height of the given child, plus the additional size of
+         * any insets applied by {@link ItemDecoration ItemDecorations}.
+         *
+         * @param child Child view to query
+         * @return child's measured height plus <code>ItemDecoration</code> insets
+         *
+         * @see View#getMeasuredHeight()
+         */
+        public int getDecoratedMeasuredHeight(View child) {
+            final Rect insets = ((LayoutParams) child.getLayoutParams()).mDecorInsets;
+            return child.getMeasuredHeight() + insets.top + insets.bottom;
+        }
+
+        /**
+         * Lay out the given child view within the RecyclerView using coordinates that
+         * include any current {@link ItemDecoration ItemDecorations}.
+         *
+         * <p>LayoutManagers should prefer working in sizes and coordinates that include
+         * item decoration insets whenever possible. This allows the LayoutManager to effectively
+         * ignore decoration insets within measurement and layout code. See the following
+         * methods:</p>
+         * <ul>
+         *     <li>{@link #layoutDecoratedWithMargins(View, int, int, int, int)}</li>
+         *     <li>{@link #getDecoratedBoundsWithMargins(View, Rect)}</li>
+         *     <li>{@link #measureChild(View, int, int)}</li>
+         *     <li>{@link #measureChildWithMargins(View, int, int)}</li>
+         *     <li>{@link #getDecoratedLeft(View)}</li>
+         *     <li>{@link #getDecoratedTop(View)}</li>
+         *     <li>{@link #getDecoratedRight(View)}</li>
+         *     <li>{@link #getDecoratedBottom(View)}</li>
+         *     <li>{@link #getDecoratedMeasuredWidth(View)}</li>
+         *     <li>{@link #getDecoratedMeasuredHeight(View)}</li>
+         * </ul>
+         *
+         * @param child Child to lay out
+         * @param left Left edge, with item decoration insets included
+         * @param top Top edge, with item decoration insets included
+         * @param right Right edge, with item decoration insets included
+         * @param bottom Bottom edge, with item decoration insets included
+         *
+         * @see View#layout(int, int, int, int)
+         * @see #layoutDecoratedWithMargins(View, int, int, int, int)
+         */
+        public void layoutDecorated(View child, int left, int top, int right, int bottom) {
+            final Rect insets = ((LayoutParams) child.getLayoutParams()).mDecorInsets;
+            child.layout(left + insets.left, top + insets.top, right - insets.right,
+                    bottom - insets.bottom);
+        }
+
+        /**
+         * Lay out the given child view within the RecyclerView using coordinates that
+         * include any current {@link ItemDecoration ItemDecorations} and margins.
+         *
+         * <p>LayoutManagers should prefer working in sizes and coordinates that include
+         * item decoration insets whenever possible. This allows the LayoutManager to effectively
+         * ignore decoration insets within measurement and layout code. See the following
+         * methods:</p>
+         * <ul>
+         *     <li>{@link #layoutDecorated(View, int, int, int, int)}</li>
+         *     <li>{@link #measureChild(View, int, int)}</li>
+         *     <li>{@link #measureChildWithMargins(View, int, int)}</li>
+         *     <li>{@link #getDecoratedLeft(View)}</li>
+         *     <li>{@link #getDecoratedTop(View)}</li>
+         *     <li>{@link #getDecoratedRight(View)}</li>
+         *     <li>{@link #getDecoratedBottom(View)}</li>
+         *     <li>{@link #getDecoratedMeasuredWidth(View)}</li>
+         *     <li>{@link #getDecoratedMeasuredHeight(View)}</li>
+         * </ul>
+         *
+         * @param child Child to lay out
+         * @param left Left edge, with item decoration insets and left margin included
+         * @param top Top edge, with item decoration insets and top margin included
+         * @param right Right edge, with item decoration insets and right margin included
+         * @param bottom Bottom edge, with item decoration insets and bottom margin included
+         *
+         * @see View#layout(int, int, int, int)
+         * @see #layoutDecorated(View, int, int, int, int)
+         */
+        public void layoutDecoratedWithMargins(View child, int left, int top, int right,
+                int bottom) {
+            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+            final Rect insets = lp.mDecorInsets;
+            child.layout(left + insets.left + lp.leftMargin, top + insets.top + lp.topMargin,
+                    right - insets.right - lp.rightMargin,
+                    bottom - insets.bottom - lp.bottomMargin);
+        }
+
+        /**
+         * Calculates the bounding box of the View while taking into account its matrix changes
+         * (translation, scale etc) with respect to the RecyclerView.
+         * <p>
+         * If {@code includeDecorInsets} is {@code true}, they are applied first before applying
+         * the View's matrix so that the decor offsets also go through the same transformation.
+         *
+         * @param child The ItemView whose bounding box should be calculated.
+         * @param includeDecorInsets True if the decor insets should be included in the bounding box
+         * @param out The rectangle into which the output will be written.
+         */
+        public void getTransformedBoundingBox(View child, boolean includeDecorInsets, Rect out) {
+            if (includeDecorInsets) {
+                Rect insets = ((LayoutParams) child.getLayoutParams()).mDecorInsets;
+                out.set(-insets.left, -insets.top,
+                        child.getWidth() + insets.right, child.getHeight() + insets.bottom);
+            } else {
+                out.set(0, 0, child.getWidth(), child.getHeight());
+            }
+
+            if (mRecyclerView != null) {
+                final Matrix childMatrix = child.getMatrix();
+                if (childMatrix != null && !childMatrix.isIdentity()) {
+                    final RectF tempRectF = mRecyclerView.mTempRectF;
+                    tempRectF.set(out);
+                    childMatrix.mapRect(tempRectF);
+                    out.set(
+                            (int) Math.floor(tempRectF.left),
+                            (int) Math.floor(tempRectF.top),
+                            (int) Math.ceil(tempRectF.right),
+                            (int) Math.ceil(tempRectF.bottom)
+                    );
+                }
+            }
+            out.offset(child.getLeft(), child.getTop());
+        }
+
+        /**
+         * Returns the bounds of the view including its decoration and margins.
+         *
+         * @param view The view element to check
+         * @param outBounds A rect that will receive the bounds of the element including its
+         *                  decoration and margins.
+         */
+        public void getDecoratedBoundsWithMargins(View view, Rect outBounds) {
+            RecyclerView.getDecoratedBoundsWithMarginsInt(view, outBounds);
+        }
+
+        /**
+         * Returns the left edge of the given child view within its parent, offset by any applied
+         * {@link ItemDecoration ItemDecorations}.
+         *
+         * @param child Child to query
+         * @return Child left edge with offsets applied
+         * @see #getLeftDecorationWidth(View)
+         */
+        public int getDecoratedLeft(View child) {
+            return child.getLeft() - getLeftDecorationWidth(child);
+        }
+
+        /**
+         * Returns the top edge of the given child view within its parent, offset by any applied
+         * {@link ItemDecoration ItemDecorations}.
+         *
+         * @param child Child to query
+         * @return Child top edge with offsets applied
+         * @see #getTopDecorationHeight(View)
+         */
+        public int getDecoratedTop(View child) {
+            return child.getTop() - getTopDecorationHeight(child);
+        }
+
+        /**
+         * Returns the right edge of the given child view within its parent, offset by any applied
+         * {@link ItemDecoration ItemDecorations}.
+         *
+         * @param child Child to query
+         * @return Child right edge with offsets applied
+         * @see #getRightDecorationWidth(View)
+         */
+        public int getDecoratedRight(View child) {
+            return child.getRight() + getRightDecorationWidth(child);
+        }
+
+        /**
+         * Returns the bottom edge of the given child view within its parent, offset by any applied
+         * {@link ItemDecoration ItemDecorations}.
+         *
+         * @param child Child to query
+         * @return Child bottom edge with offsets applied
+         * @see #getBottomDecorationHeight(View)
+         */
+        public int getDecoratedBottom(View child) {
+            return child.getBottom() + getBottomDecorationHeight(child);
+        }
+
+        /**
+         * Calculates the item decor insets applied to the given child and updates the provided
+         * Rect instance with the inset values.
+         * <ul>
+         *     <li>The Rect's left is set to the total width of left decorations.</li>
+         *     <li>The Rect's top is set to the total height of top decorations.</li>
+         *     <li>The Rect's right is set to the total width of right decorations.</li>
+         *     <li>The Rect's bottom is set to total height of bottom decorations.</li>
+         * </ul>
+         * <p>
+         * Note that item decorations are automatically calculated when one of the LayoutManager's
+         * measure child methods is called. If you need to measure the child with custom specs via
+         * {@link View#measure(int, int)}, you can use this method to get decorations.
+         *
+         * @param child The child view whose decorations should be calculated
+         * @param outRect The Rect to hold result values
+         */
+        public void calculateItemDecorationsForChild(View child, Rect outRect) {
+            if (mRecyclerView == null) {
+                outRect.set(0, 0, 0, 0);
+                return;
+            }
+            Rect insets = mRecyclerView.getItemDecorInsetsForChild(child);
+            outRect.set(insets);
+        }
+
+        /**
+         * Returns the total height of item decorations applied to child's top.
+         * <p>
+         * Note that this value is not updated until the View is measured or
+         * {@link #calculateItemDecorationsForChild(View, Rect)} is called.
+         *
+         * @param child Child to query
+         * @return The total height of item decorations applied to the child's top.
+         * @see #getDecoratedTop(View)
+         * @see #calculateItemDecorationsForChild(View, Rect)
+         */
+        public int getTopDecorationHeight(View child) {
+            return ((LayoutParams) child.getLayoutParams()).mDecorInsets.top;
+        }
+
+        /**
+         * Returns the total height of item decorations applied to child's bottom.
+         * <p>
+         * Note that this value is not updated until the View is measured or
+         * {@link #calculateItemDecorationsForChild(View, Rect)} is called.
+         *
+         * @param child Child to query
+         * @return The total height of item decorations applied to the child's bottom.
+         * @see #getDecoratedBottom(View)
+         * @see #calculateItemDecorationsForChild(View, Rect)
+         */
+        public int getBottomDecorationHeight(View child) {
+            return ((LayoutParams) child.getLayoutParams()).mDecorInsets.bottom;
+        }
+
+        /**
+         * Returns the total width of item decorations applied to child's left.
+         * <p>
+         * Note that this value is not updated until the View is measured or
+         * {@link #calculateItemDecorationsForChild(View, Rect)} is called.
+         *
+         * @param child Child to query
+         * @return The total width of item decorations applied to the child's left.
+         * @see #getDecoratedLeft(View)
+         * @see #calculateItemDecorationsForChild(View, Rect)
+         */
+        public int getLeftDecorationWidth(View child) {
+            return ((LayoutParams) child.getLayoutParams()).mDecorInsets.left;
+        }
+
+        /**
+         * Returns the total width of item decorations applied to child's right.
+         * <p>
+         * Note that this value is not updated until the View is measured or
+         * {@link #calculateItemDecorationsForChild(View, Rect)} is called.
+         *
+         * @param child Child to query
+         * @return The total width of item decorations applied to the child's right.
+         * @see #getDecoratedRight(View)
+         * @see #calculateItemDecorationsForChild(View, Rect)
+         */
+        public int getRightDecorationWidth(View child) {
+            return ((LayoutParams) child.getLayoutParams()).mDecorInsets.right;
+        }
+
+        /**
+         * Called when searching for a focusable view in the given direction has failed
+         * for the current content of the RecyclerView.
+         *
+         * <p>This is the LayoutManager's opportunity to populate views in the given direction
+         * to fulfill the request if it can. The LayoutManager should attach and return
+         * the view to be focused. The default implementation returns null.</p>
+         *
+         * @param focused   The currently focused view
+         * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
+         *                  {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT},
+         *                  {@link View#FOCUS_BACKWARD}, {@link View#FOCUS_FORWARD}
+         *                  or 0 for not applicable
+         * @param recycler  The recycler to use for obtaining views for currently offscreen items
+         * @param state     Transient state of RecyclerView
+         * @return The chosen view to be focused
+         */
+        @Nullable
+        public View onFocusSearchFailed(View focused, int direction, Recycler recycler,
+                State state) {
+            return null;
+        }
+
+        /**
+         * This method gives a LayoutManager an opportunity to intercept the initial focus search
+         * before the default behavior of {@link FocusFinder} is used. If this method returns
+         * null FocusFinder will attempt to find a focusable child view. If it fails
+         * then {@link #onFocusSearchFailed(View, int, RecyclerView.Recycler, RecyclerView.State)}
+         * will be called to give the LayoutManager an opportunity to add new views for items
+         * that did not have attached views representing them. The LayoutManager should not add
+         * or remove views from this method.
+         *
+         * @param focused The currently focused view
+         * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
+         *                  {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT},
+         *                  {@link View#FOCUS_BACKWARD}, {@link View#FOCUS_FORWARD}
+         * @return A descendant view to focus or null to fall back to default behavior.
+         *         The default implementation returns null.
+         */
+        public View onInterceptFocusSearch(View focused, int direction) {
+            return null;
+        }
+
+        /**
+         * Called when a child of the RecyclerView wants a particular rectangle to be positioned
+         * onto the screen. See {@link ViewParent#requestChildRectangleOnScreen(android.view.View,
+         * android.graphics.Rect, boolean)} for more details.
+         *
+         * <p>The base implementation will attempt to perform a standard programmatic scroll
+         * to bring the given rect into view, within the padded area of the RecyclerView.</p>
+         *
+         * @param child The direct child making the request.
+         * @param rect  The rectangle in the child's coordinates the child
+         *              wishes to be on the screen.
+         * @param immediate True to forbid animated or delayed scrolling,
+         *                  false otherwise
+         * @return Whether the group scrolled to handle the operation
+         */
+        public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect,
+                boolean immediate) {
+            final int parentLeft = getPaddingLeft();
+            final int parentTop = getPaddingTop();
+            final int parentRight = getWidth() - getPaddingRight();
+            final int parentBottom = getHeight() - getPaddingBottom();
+            final int childLeft = child.getLeft() + rect.left - child.getScrollX();
+            final int childTop = child.getTop() + rect.top - child.getScrollY();
+            final int childRight = childLeft + rect.width();
+            final int childBottom = childTop + rect.height();
+
+            final int offScreenLeft = Math.min(0, childLeft - parentLeft);
+            final int offScreenTop = Math.min(0, childTop - parentTop);
+            final int offScreenRight = Math.max(0, childRight - parentRight);
+            final int offScreenBottom = Math.max(0, childBottom - parentBottom);
+
+            // Favor the "start" layout direction over the end when bringing one side or the other
+            // of a large rect into view. If we decide to bring in end because start is already
+            // visible, limit the scroll such that start won't go out of bounds.
+            final int dx;
+            if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+                dx = offScreenRight != 0 ? offScreenRight
+                        : Math.max(offScreenLeft, childRight - parentRight);
+            } else {
+                dx = offScreenLeft != 0 ? offScreenLeft
+                        : Math.min(childLeft - parentLeft, offScreenRight);
+            }
+
+            // Favor bringing the top into view over the bottom. If top is already visible and
+            // we should scroll to make bottom visible, make sure top does not go out of bounds.
+            final int dy = offScreenTop != 0 ? offScreenTop
+                    : Math.min(childTop - parentTop, offScreenBottom);
+
+            if (dx != 0 || dy != 0) {
+                if (immediate) {
+                    parent.scrollBy(dx, dy);
+                } else {
+                    parent.smoothScrollBy(dx, dy);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * @deprecated Use {@link #onRequestChildFocus(RecyclerView, State, View, View)}
+         */
+        @Deprecated
+        public boolean onRequestChildFocus(RecyclerView parent, View child, View focused) {
+            // eat the request if we are in the middle of a scroll or layout
+            return isSmoothScrolling() || parent.isComputingLayout();
+        }
+
+        /**
+         * Called when a descendant view of the RecyclerView requests focus.
+         *
+         * <p>A LayoutManager wishing to keep focused views aligned in a specific
+         * portion of the view may implement that behavior in an override of this method.</p>
+         *
+         * <p>If the LayoutManager executes different behavior that should override the default
+         * behavior of scrolling the focused child on screen instead of running alongside it,
+         * this method should return true.</p>
+         *
+         * @param parent  The RecyclerView hosting this LayoutManager
+         * @param state   Current state of RecyclerView
+         * @param child   Direct child of the RecyclerView containing the newly focused view
+         * @param focused The newly focused view. This may be the same view as child or it may be
+         *                null
+         * @return true if the default scroll behavior should be suppressed
+         */
+        public boolean onRequestChildFocus(RecyclerView parent, State state, View child,
+                View focused) {
+            return onRequestChildFocus(parent, child, focused);
+        }
+
+        /**
+         * Called if the RecyclerView this LayoutManager is bound to has a different adapter set.
+         * The LayoutManager may use this opportunity to clear caches and configure state such
+         * that it can relayout appropriately with the new data and potentially new view types.
+         *
+         * <p>The default implementation removes all currently attached views.</p>
+         *
+         * @param oldAdapter The previous adapter instance. Will be null if there was previously no
+         *                   adapter.
+         * @param newAdapter The new adapter instance. Might be null if
+         *                   {@link #setAdapter(RecyclerView.Adapter)} is called with {@code null}.
+         */
+        public void onAdapterChanged(Adapter oldAdapter, Adapter newAdapter) {
+        }
+
+        /**
+         * Called to populate focusable views within the RecyclerView.
+         *
+         * <p>The LayoutManager implementation should return <code>true</code> if the default
+         * behavior of {@link ViewGroup#addFocusables(java.util.ArrayList, int)} should be
+         * suppressed.</p>
+         *
+         * <p>The default implementation returns <code>false</code> to trigger RecyclerView
+         * to fall back to the default ViewGroup behavior.</p>
+         *
+         * @param recyclerView The RecyclerView hosting this LayoutManager
+         * @param views List of output views. This method should add valid focusable views
+         *              to this list.
+         * @param direction One of {@link View#FOCUS_UP}, {@link View#FOCUS_DOWN},
+         *                  {@link View#FOCUS_LEFT}, {@link View#FOCUS_RIGHT},
+         *                  {@link View#FOCUS_BACKWARD}, {@link View#FOCUS_FORWARD}
+         * @param focusableMode The type of focusables to be added.
+         *
+         * @return true to suppress the default behavior, false to add default focusables after
+         *         this method returns.
+         *
+         * @see #FOCUSABLES_ALL
+         * @see #FOCUSABLES_TOUCH_MODE
+         */
+        public boolean onAddFocusables(RecyclerView recyclerView, ArrayList<View> views,
+                int direction, int focusableMode) {
+            return false;
+        }
+
+        /**
+         * Called when {@link Adapter#notifyDataSetChanged()} is triggered instead of giving
+         * detailed information on what has actually changed.
+         *
+         * @param recyclerView
+         */
+        public void onItemsChanged(RecyclerView recyclerView) {
+        }
+
+        /**
+         * Called when items have been added to the adapter. The LayoutManager may choose to
+         * requestLayout if the inserted items would require refreshing the currently visible set
+         * of child views. (e.g. currently empty space would be filled by appended items, etc.)
+         *
+         * @param recyclerView
+         * @param positionStart
+         * @param itemCount
+         */
+        public void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount) {
+        }
+
+        /**
+         * Called when items have been removed from the adapter.
+         *
+         * @param recyclerView
+         * @param positionStart
+         * @param itemCount
+         */
+        public void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount) {
+        }
+
+        /**
+         * Called when items have been changed in the adapter.
+         * To receive payload,  override {@link #onItemsUpdated(RecyclerView, int, int, Object)}
+         * instead, then this callback will not be invoked.
+         *
+         * @param recyclerView
+         * @param positionStart
+         * @param itemCount
+         */
+        public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount) {
+        }
+
+        /**
+         * Called when items have been changed in the adapter and with optional payload.
+         * Default implementation calls {@link #onItemsUpdated(RecyclerView, int, int)}.
+         *
+         * @param recyclerView
+         * @param positionStart
+         * @param itemCount
+         * @param payload
+         */
+        public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount,
+                Object payload) {
+            onItemsUpdated(recyclerView, positionStart, itemCount);
+        }
+
+        /**
+         * Called when an item is moved withing the adapter.
+         * <p>
+         * Note that, an item may also change position in response to another ADD/REMOVE/MOVE
+         * operation. This callback is only called if and only if {@link Adapter#notifyItemMoved}
+         * is called.
+         *
+         * @param recyclerView
+         * @param from
+         * @param to
+         * @param itemCount
+         */
+        public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCount) {
+
+        }
+
+
+        /**
+         * <p>Override this method if you want to support scroll bars.</p>
+         *
+         * <p>Read {@link RecyclerView#computeHorizontalScrollExtent()} for details.</p>
+         *
+         * <p>Default implementation returns 0.</p>
+         *
+         * @param state Current state of RecyclerView
+         * @return The horizontal extent of the scrollbar's thumb
+         * @see RecyclerView#computeHorizontalScrollExtent()
+         */
+        public int computeHorizontalScrollExtent(State state) {
+            return 0;
+        }
+
+        /**
+         * <p>Override this method if you want to support scroll bars.</p>
+         *
+         * <p>Read {@link RecyclerView#computeHorizontalScrollOffset()} for details.</p>
+         *
+         * <p>Default implementation returns 0.</p>
+         *
+         * @param state Current State of RecyclerView where you can find total item count
+         * @return The horizontal offset of the scrollbar's thumb
+         * @see RecyclerView#computeHorizontalScrollOffset()
+         */
+        public int computeHorizontalScrollOffset(State state) {
+            return 0;
+        }
+
+        /**
+         * <p>Override this method if you want to support scroll bars.</p>
+         *
+         * <p>Read {@link RecyclerView#computeHorizontalScrollRange()} for details.</p>
+         *
+         * <p>Default implementation returns 0.</p>
+         *
+         * @param state Current State of RecyclerView where you can find total item count
+         * @return The total horizontal range represented by the vertical scrollbar
+         * @see RecyclerView#computeHorizontalScrollRange()
+         */
+        public int computeHorizontalScrollRange(State state) {
+            return 0;
+        }
+
+        /**
+         * <p>Override this method if you want to support scroll bars.</p>
+         *
+         * <p>Read {@link RecyclerView#computeVerticalScrollExtent()} for details.</p>
+         *
+         * <p>Default implementation returns 0.</p>
+         *
+         * @param state Current state of RecyclerView
+         * @return The vertical extent of the scrollbar's thumb
+         * @see RecyclerView#computeVerticalScrollExtent()
+         */
+        public int computeVerticalScrollExtent(State state) {
+            return 0;
+        }
+
+        /**
+         * <p>Override this method if you want to support scroll bars.</p>
+         *
+         * <p>Read {@link RecyclerView#computeVerticalScrollOffset()} for details.</p>
+         *
+         * <p>Default implementation returns 0.</p>
+         *
+         * @param state Current State of RecyclerView where you can find total item count
+         * @return The vertical offset of the scrollbar's thumb
+         * @see RecyclerView#computeVerticalScrollOffset()
+         */
+        public int computeVerticalScrollOffset(State state) {
+            return 0;
+        }
+
+        /**
+         * <p>Override this method if you want to support scroll bars.</p>
+         *
+         * <p>Read {@link RecyclerView#computeVerticalScrollRange()} for details.</p>
+         *
+         * <p>Default implementation returns 0.</p>
+         *
+         * @param state Current State of RecyclerView where you can find total item count
+         * @return The total vertical range represented by the vertical scrollbar
+         * @see RecyclerView#computeVerticalScrollRange()
+         */
+        public int computeVerticalScrollRange(State state) {
+            return 0;
+        }
+
+        /**
+         * Measure the attached RecyclerView. Implementations must call
+         * {@link #setMeasuredDimension(int, int)} before returning.
+         *
+         * <p>The default implementation will handle EXACTLY measurements and respect
+         * the minimum width and height properties of the host RecyclerView if measured
+         * as UNSPECIFIED. AT_MOST measurements will be treated as EXACTLY and the RecyclerView
+         * will consume all available space.</p>
+         *
+         * @param recycler Recycler
+         * @param state Transient state of RecyclerView
+         * @param widthSpec Width {@link android.view.View.MeasureSpec}
+         * @param heightSpec Height {@link android.view.View.MeasureSpec}
+         */
+        public void onMeasure(Recycler recycler, State state, int widthSpec, int heightSpec) {
+            mRecyclerView.defaultOnMeasure(widthSpec, heightSpec);
+        }
+
+        /**
+         * {@link View#setMeasuredDimension(int, int) Set the measured dimensions} of the
+         * host RecyclerView.
+         *
+         * @param widthSize Measured width
+         * @param heightSize Measured height
+         */
+        public void setMeasuredDimension(int widthSize, int heightSize) {
+            mRecyclerView.setMeasuredDimension(widthSize, heightSize);
+        }
+
+        /**
+         * @return The host RecyclerView's {@link View#getMinimumWidth()}
+         */
+        public int getMinimumWidth() {
+            return mRecyclerView.getMinimumWidth();
+        }
+
+        /**
+         * @return The host RecyclerView's {@link View#getMinimumHeight()}
+         */
+        public int getMinimumHeight() {
+            return mRecyclerView.getMinimumHeight();
+        }
+        /**
+         * <p>Called when the LayoutManager should save its state. This is a good time to save your
+         * scroll position, configuration and anything else that may be required to restore the same
+         * layout state if the LayoutManager is recreated.</p>
+         * <p>RecyclerView does NOT verify if the LayoutManager has changed between state save and
+         * restore. This will let you share information between your LayoutManagers but it is also
+         * your responsibility to make sure they use the same parcelable class.</p>
+         *
+         * @return Necessary information for LayoutManager to be able to restore its state
+         */
+        public Parcelable onSaveInstanceState() {
+            return null;
+        }
+
+
+        public void onRestoreInstanceState(Parcelable state) {
+
+        }
+
+        void stopSmoothScroller() {
+            if (mSmoothScroller != null) {
+                mSmoothScroller.stop();
+            }
+        }
+
+        private void onSmoothScrollerStopped(SmoothScroller smoothScroller) {
+            if (mSmoothScroller == smoothScroller) {
+                mSmoothScroller = null;
+            }
+        }
+
+        /**
+         * RecyclerView calls this method to notify LayoutManager that scroll state has changed.
+         *
+         * @param state The new scroll state for RecyclerView
+         */
+        public void onScrollStateChanged(int state) {
+        }
+
+        /**
+         * Removes all views and recycles them using the given recycler.
+         * <p>
+         * If you want to clean cached views as well, you should call {@link Recycler#clear()} too.
+         * <p>
+         * If a View is marked as "ignored", it is not removed nor recycled.
+         *
+         * @param recycler Recycler to use to recycle children
+         * @see #removeAndRecycleView(View, Recycler)
+         * @see #removeAndRecycleViewAt(int, Recycler)
+         * @see #ignoreView(View)
+         */
+        public void removeAndRecycleAllViews(Recycler recycler) {
+            for (int i = getChildCount() - 1; i >= 0; i--) {
+                final View view = getChildAt(i);
+                if (!getChildViewHolderInt(view).shouldIgnore()) {
+                    removeAndRecycleViewAt(i, recycler);
+                }
+            }
+        }
+
+        // called by accessibility delegate
+        void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+            onInitializeAccessibilityNodeInfo(mRecyclerView.mRecycler, mRecyclerView.mState, info);
+        }
+
+        /**
+         * Called by the AccessibilityDelegate when the information about the current layout should
+         * be populated.
+         * <p>
+         * Default implementation adds a {@link
+         * android.view.accessibility.AccessibilityNodeInfo.CollectionInfo}.
+         * <p>
+         * You should override
+         * {@link #getRowCountForAccessibility(RecyclerView.Recycler, RecyclerView.State)},
+         * {@link #getColumnCountForAccessibility(RecyclerView.Recycler, RecyclerView.State)},
+         * {@link #isLayoutHierarchical(RecyclerView.Recycler, RecyclerView.State)} and
+         * {@link #getSelectionModeForAccessibility(RecyclerView.Recycler, RecyclerView.State)} for
+         * more accurate accessibility information.
+         *
+         * @param recycler The Recycler that can be used to convert view positions into adapter
+         *                 positions
+         * @param state    The current state of RecyclerView
+         * @param info     The info that should be filled by the LayoutManager
+         * @see View#onInitializeAccessibilityNodeInfo(
+         *android.view.accessibility.AccessibilityNodeInfo)
+         * @see #getRowCountForAccessibility(RecyclerView.Recycler, RecyclerView.State)
+         * @see #getColumnCountForAccessibility(RecyclerView.Recycler, RecyclerView.State)
+         * @see #isLayoutHierarchical(RecyclerView.Recycler, RecyclerView.State)
+         * @see #getSelectionModeForAccessibility(RecyclerView.Recycler, RecyclerView.State)
+         */
+        public void onInitializeAccessibilityNodeInfo(Recycler recycler, State state,
+                AccessibilityNodeInfo info) {
+            if (mRecyclerView.canScrollVertically(-1)
+                    || mRecyclerView.canScrollHorizontally(-1)) {
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+                info.setScrollable(true);
+            }
+            if (mRecyclerView.canScrollVertically(1)
+                    || mRecyclerView.canScrollHorizontally(1)) {
+                info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+                info.setScrollable(true);
+            }
+            final AccessibilityNodeInfo.CollectionInfo collectionInfo =
+                    AccessibilityNodeInfo.CollectionInfo
+                            .obtain(getRowCountForAccessibility(recycler, state),
+                                    getColumnCountForAccessibility(recycler, state),
+                                    isLayoutHierarchical(recycler, state),
+                                    getSelectionModeForAccessibility(recycler, state));
+            info.setCollectionInfo(collectionInfo);
+        }
+
+        // called by accessibility delegate
+        public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+            onInitializeAccessibilityEvent(mRecyclerView.mRecycler, mRecyclerView.mState, event);
+        }
+
+        /**
+         * Called by the accessibility delegate to initialize an accessibility event.
+         * <p>
+         * Default implementation adds item count and scroll information to the event.
+         *
+         * @param recycler The Recycler that can be used to convert view positions into adapter
+         *                 positions
+         * @param state    The current state of RecyclerView
+         * @param event    The event instance to initialize
+         * @see View#onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent)
+         */
+        public void onInitializeAccessibilityEvent(Recycler recycler, State state,
+                AccessibilityEvent event) {
+            if (mRecyclerView == null || event == null) {
+                return;
+            }
+            event.setScrollable(mRecyclerView.canScrollVertically(1)
+                    || mRecyclerView.canScrollVertically(-1)
+                    || mRecyclerView.canScrollHorizontally(-1)
+                    || mRecyclerView.canScrollHorizontally(1));
+
+            if (mRecyclerView.mAdapter != null) {
+                event.setItemCount(mRecyclerView.mAdapter.getItemCount());
+            }
+        }
+
+        // called by accessibility delegate
+        void onInitializeAccessibilityNodeInfoForItem(View host, AccessibilityNodeInfo info) {
+            final ViewHolder vh = getChildViewHolderInt(host);
+            // avoid trying to create accessibility node info for removed children
+            if (vh != null && !vh.isRemoved() && !mChildHelper.isHidden(vh.itemView)) {
+                onInitializeAccessibilityNodeInfoForItem(mRecyclerView.mRecycler,
+                        mRecyclerView.mState, host, info);
+            }
+        }
+
+        /**
+         * Called by the AccessibilityDelegate when the accessibility information for a specific
+         * item should be populated.
+         * <p>
+         * Default implementation adds basic positioning information about the item.
+         *
+         * @param recycler The Recycler that can be used to convert view positions into adapter
+         *                 positions
+         * @param state    The current state of RecyclerView
+         * @param host     The child for which accessibility node info should be populated
+         * @param info     The info to fill out about the item
+         * @see android.widget.AbsListView#onInitializeAccessibilityNodeInfoForItem(View, int,
+         * android.view.accessibility.AccessibilityNodeInfo)
+         */
+        public void onInitializeAccessibilityNodeInfoForItem(Recycler recycler, State state,
+                View host, AccessibilityNodeInfo info) {
+            int rowIndexGuess = canScrollVertically() ? getPosition(host) : 0;
+            int columnIndexGuess = canScrollHorizontally() ? getPosition(host) : 0;
+            final AccessibilityNodeInfo.CollectionItemInfo itemInfo =
+                    AccessibilityNodeInfo.CollectionItemInfo.obtain(rowIndexGuess, 1,
+                            columnIndexGuess, 1, false, false);
+            info.setCollectionItemInfo(itemInfo);
+        }
+
+        /**
+         * A LayoutManager can call this method to force RecyclerView to run simple animations in
+         * the next layout pass, even if there is not any trigger to do so. (e.g. adapter data
+         * change).
+         * <p>
+         * Note that, calling this method will not guarantee that RecyclerView will run animations
+         * at all. For example, if there is not any {@link ItemAnimator} set, RecyclerView will
+         * not run any animations but will still clear this flag after the layout is complete.
+         *
+         */
+        public void requestSimpleAnimationsInNextLayout() {
+            mRequestedSimpleAnimations = true;
+        }
+
+        /**
+         * Returns the selection mode for accessibility. Should be
+         * {@link AccessibilityNodeInfo.CollectionInfo#SELECTION_MODE_NONE},
+         * {@link AccessibilityNodeInfo.CollectionInfo#SELECTION_MODE_SINGLE} or
+         * {@link AccessibilityNodeInfo.CollectionInfo#SELECTION_MODE_MULTIPLE}.
+         * <p>
+         * Default implementation returns
+         * {@link AccessibilityNodeInfo.CollectionInfo#SELECTION_MODE_NONE}.
+         *
+         * @param recycler The Recycler that can be used to convert view positions into adapter
+         *                 positions
+         * @param state    The current state of RecyclerView
+         * @return Selection mode for accessibility. Default implementation returns
+         * {@link AccessibilityNodeInfo.CollectionInfo#SELECTION_MODE_NONE}.
+         */
+        public int getSelectionModeForAccessibility(Recycler recycler, State state) {
+            return AccessibilityNodeInfo.CollectionInfo.SELECTION_MODE_NONE;
+        }
+
+        /**
+         * Returns the number of rows for accessibility.
+         * <p>
+         * Default implementation returns the number of items in the adapter if LayoutManager
+         * supports vertical scrolling or 1 if LayoutManager does not support vertical
+         * scrolling.
+         *
+         * @param recycler The Recycler that can be used to convert view positions into adapter
+         *                 positions
+         * @param state    The current state of RecyclerView
+         * @return The number of rows in LayoutManager for accessibility.
+         */
+        public int getRowCountForAccessibility(Recycler recycler, State state) {
+            if (mRecyclerView == null || mRecyclerView.mAdapter == null) {
+                return 1;
+            }
+            return canScrollVertically() ? mRecyclerView.mAdapter.getItemCount() : 1;
+        }
+
+        /**
+         * Returns the number of columns for accessibility.
+         * <p>
+         * Default implementation returns the number of items in the adapter if LayoutManager
+         * supports horizontal scrolling or 1 if LayoutManager does not support horizontal
+         * scrolling.
+         *
+         * @param recycler The Recycler that can be used to convert view positions into adapter
+         *                 positions
+         * @param state    The current state of RecyclerView
+         * @return The number of rows in LayoutManager for accessibility.
+         */
+        public int getColumnCountForAccessibility(Recycler recycler, State state) {
+            if (mRecyclerView == null || mRecyclerView.mAdapter == null) {
+                return 1;
+            }
+            return canScrollHorizontally() ? mRecyclerView.mAdapter.getItemCount() : 1;
+        }
+
+        /**
+         * Returns whether layout is hierarchical or not to be used for accessibility.
+         * <p>
+         * Default implementation returns false.
+         *
+         * @param recycler The Recycler that can be used to convert view positions into adapter
+         *                 positions
+         * @param state    The current state of RecyclerView
+         * @return True if layout is hierarchical.
+         */
+        public boolean isLayoutHierarchical(Recycler recycler, State state) {
+            return false;
+        }
+
+        // called by accessibility delegate
+        boolean performAccessibilityAction(int action, Bundle args) {
+            return performAccessibilityAction(mRecyclerView.mRecycler, mRecyclerView.mState,
+                    action, args);
+        }
+
+        /**
+         * Called by AccessibilityDelegate when an action is requested from the RecyclerView.
+         *
+         * @param recycler  The Recycler that can be used to convert view positions into adapter
+         *                  positions
+         * @param state     The current state of RecyclerView
+         * @param action    The action to perform
+         * @param args      Optional action arguments
+         * @see View#performAccessibilityAction(int, android.os.Bundle)
+         */
+        public boolean performAccessibilityAction(Recycler recycler, State state, int action,
+                Bundle args) {
+            if (mRecyclerView == null) {
+                return false;
+            }
+            int vScroll = 0, hScroll = 0;
+            switch (action) {
+                case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+                    if (mRecyclerView.canScrollVertically(-1)) {
+                        vScroll = -(getHeight() - getPaddingTop() - getPaddingBottom());
+                    }
+                    if (mRecyclerView.canScrollHorizontally(-1)) {
+                        hScroll = -(getWidth() - getPaddingLeft() - getPaddingRight());
+                    }
+                    break;
+                case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+                    if (mRecyclerView.canScrollVertically(1)) {
+                        vScroll = getHeight() - getPaddingTop() - getPaddingBottom();
+                    }
+                    if (mRecyclerView.canScrollHorizontally(1)) {
+                        hScroll = getWidth() - getPaddingLeft() - getPaddingRight();
+                    }
+                    break;
+            }
+            if (vScroll == 0 && hScroll == 0) {
+                return false;
+            }
+            mRecyclerView.scrollBy(hScroll, vScroll);
+            return true;
+        }
+
+        // called by accessibility delegate
+        boolean performAccessibilityActionForItem(View view, int action, Bundle args) {
+            return performAccessibilityActionForItem(mRecyclerView.mRecycler, mRecyclerView.mState,
+                    view, action, args);
+        }
+
+        /**
+         * Called by AccessibilityDelegate when an accessibility action is requested on one of the
+         * children of LayoutManager.
+         * <p>
+         * Default implementation does not do anything.
+         *
+         * @param recycler The Recycler that can be used to convert view positions into adapter
+         *                 positions
+         * @param state    The current state of RecyclerView
+         * @param view     The child view on which the action is performed
+         * @param action   The action to perform
+         * @param args     Optional action arguments
+         * @return true if action is handled
+         * @see View#performAccessibilityAction(int, android.os.Bundle)
+         */
+        public boolean performAccessibilityActionForItem(Recycler recycler, State state, View view,
+                int action, Bundle args) {
+            return false;
+        }
+
+        /**
+         * Parse the xml attributes to get the most common properties used by layout managers.
+         *
+         * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_android_orientation
+         * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_spanCount
+         * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_reverseLayout
+         * @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_stackFromEnd
+         *
+         * @return an object containing the properties as specified in the attrs.
+         */
+        public static Properties getProperties(Context context, AttributeSet attrs,
+                int defStyleAttr, int defStyleRes) {
+            Properties properties = new Properties();
+            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RecyclerView,
+                    defStyleAttr, defStyleRes);
+            properties.orientation = a.getInt(R.styleable.RecyclerView_orientation, VERTICAL);
+            properties.spanCount = a.getInt(R.styleable.RecyclerView_spanCount, 1);
+            properties.reverseLayout = a.getBoolean(R.styleable.RecyclerView_reverseLayout, false);
+            properties.stackFromEnd = a.getBoolean(R.styleable.RecyclerView_stackFromEnd, false);
+            a.recycle();
+            return properties;
+        }
+
+        void setExactMeasureSpecsFrom(RecyclerView recyclerView) {
+            setMeasureSpecs(
+                    MeasureSpec.makeMeasureSpec(recyclerView.getWidth(), MeasureSpec.EXACTLY),
+                    MeasureSpec.makeMeasureSpec(recyclerView.getHeight(), MeasureSpec.EXACTLY)
+            );
+        }
+
+        /**
+         * Internal API to allow LayoutManagers to be measured twice.
+         * <p>
+         * This is not public because LayoutManagers should be able to handle their layouts in one
+         * pass but it is very convenient to make existing LayoutManagers support wrapping content
+         * when both orientations are undefined.
+         * <p>
+         * This API will be removed after default LayoutManagers properly implement wrap content in
+         * non-scroll orientation.
+         */
+        boolean shouldMeasureTwice() {
+            return false;
+        }
+
+        boolean hasFlexibleChildInBothOrientations() {
+            final int childCount = getChildCount();
+            for (int i = 0; i < childCount; i++) {
+                final View child = getChildAt(i);
+                final ViewGroup.LayoutParams lp = child.getLayoutParams();
+                if (lp.width < 0 && lp.height < 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Some general properties that a LayoutManager may want to use.
+         */
+        public static class Properties {
+            /** @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_android_orientation */
+            public int orientation;
+            /** @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_spanCount */
+            public int spanCount;
+            /** @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_reverseLayout */
+            public boolean reverseLayout;
+            /** @attr ref android.support.v7.recyclerview.R.styleable#RecyclerView_stackFromEnd */
+            public boolean stackFromEnd;
+        }
+    }
+
+    /**
+     * An ItemDecoration allows the application to add a special drawing and layout offset
+     * to specific item views from the adapter's data set. This can be useful for drawing dividers
+     * between items, highlights, visual grouping boundaries and more.
+     *
+     * <p>All ItemDecorations are drawn in the order they were added, before the item
+     * views (in {@link ItemDecoration#onDraw(Canvas, RecyclerView, RecyclerView.State) onDraw()}
+     * and after the items (in {@link ItemDecoration#onDrawOver(Canvas, RecyclerView,
+     * RecyclerView.State)}.</p>
+     */
+    public abstract static class ItemDecoration {
+        /**
+         * Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
+         * Any content drawn by this method will be drawn before the item views are drawn,
+         * and will thus appear underneath the views.
+         *
+         * @param c Canvas to draw into
+         * @param parent RecyclerView this ItemDecoration is drawing into
+         * @param state The current state of RecyclerView
+         */
+        public void onDraw(Canvas c, RecyclerView parent, State state) {
+            onDraw(c, parent);
+        }
+
+        /**
+         * @deprecated
+         * Override {@link #onDraw(Canvas, RecyclerView, RecyclerView.State)}
+         */
+        @Deprecated
+        public void onDraw(Canvas c, RecyclerView parent) {
+        }
+
+        /**
+         * Draw any appropriate decorations into the Canvas supplied to the RecyclerView.
+         * Any content drawn by this method will be drawn after the item views are drawn
+         * and will thus appear over the views.
+         *
+         * @param c Canvas to draw into
+         * @param parent RecyclerView this ItemDecoration is drawing into
+         * @param state The current state of RecyclerView.
+         */
+        public void onDrawOver(Canvas c, RecyclerView parent, State state) {
+            onDrawOver(c, parent);
+        }
+
+        /**
+         * @deprecated
+         * Override {@link #onDrawOver(Canvas, RecyclerView, RecyclerView.State)}
+         */
+        @Deprecated
+        public void onDrawOver(Canvas c, RecyclerView parent) {
+        }
+
+
+        /**
+         * @deprecated
+         * Use {@link #getItemOffsets(Rect, View, RecyclerView, State)}
+         */
+        @Deprecated
+        public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
+            outRect.set(0, 0, 0, 0);
+        }
+
+        /**
+         * Retrieve any offsets for the given item. Each field of <code>outRect</code> specifies
+         * the number of pixels that the item view should be inset by, similar to padding or margin.
+         * The default implementation sets the bounds of outRect to 0 and returns.
+         *
+         * <p>
+         * If this ItemDecoration does not affect the positioning of item views, it should set
+         * all four fields of <code>outRect</code> (left, top, right, bottom) to zero
+         * before returning.
+         *
+         * <p>
+         * If you need to access Adapter for additional data, you can call
+         * {@link RecyclerView#getChildAdapterPosition(View)} to get the adapter position of the
+         * View.
+         *
+         * @param outRect Rect to receive the output.
+         * @param view    The child view to decorate
+         * @param parent  RecyclerView this ItemDecoration is decorating
+         * @param state   The current state of RecyclerView.
+         */
+        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
+            getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
+                    parent);
+        }
+    }
+
+    /**
+     * An OnItemTouchListener allows the application to intercept touch events in progress at the
+     * view hierarchy level of the RecyclerView before those touch events are considered for
+     * RecyclerView's own scrolling behavior.
+     *
+     * <p>This can be useful for applications that wish to implement various forms of gestural
+     * manipulation of item views within the RecyclerView. OnItemTouchListeners may intercept
+     * a touch interaction already in progress even if the RecyclerView is already handling that
+     * gesture stream itself for the purposes of scrolling.</p>
+     *
+     * @see SimpleOnItemTouchListener
+     */
+    public interface OnItemTouchListener {
+        /**
+         * Silently observe and/or take over touch events sent to the RecyclerView
+         * before they are handled by either the RecyclerView itself or its child views.
+         *
+         * <p>The onInterceptTouchEvent methods of each attached OnItemTouchListener will be run
+         * in the order in which each listener was added, before any other touch processing
+         * by the RecyclerView itself or child views occurs.</p>
+         *
+         * @param e MotionEvent describing the touch event. All coordinates are in
+         *          the RecyclerView's coordinate system.
+         * @return true if this OnItemTouchListener wishes to begin intercepting touch events, false
+         *         to continue with the current behavior and continue observing future events in
+         *         the gesture.
+         */
+        boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e);
+
+        /**
+         * Process a touch event as part of a gesture that was claimed by returning true from
+         * a previous call to {@link #onInterceptTouchEvent}.
+         *
+         * @param e MotionEvent describing the touch event. All coordinates are in
+         *          the RecyclerView's coordinate system.
+         */
+        void onTouchEvent(RecyclerView rv, MotionEvent e);
+
+        /**
+         * Called when a child of RecyclerView does not want RecyclerView and its ancestors to
+         * intercept touch events with
+         * {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}.
+         *
+         * @param disallowIntercept True if the child does not want the parent to
+         *            intercept touch events.
+         * @see ViewParent#requestDisallowInterceptTouchEvent(boolean)
+         */
+        void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
+    }
+
+    /**
+     * An implementation of {@link RecyclerView.OnItemTouchListener} that has empty method bodies
+     * and default return values.
+     * <p>
+     * You may prefer to extend this class if you don't need to override all methods. Another
+     * benefit of using this class is future compatibility. As the interface may change, we'll
+     * always provide a default implementation on this class so that your code won't break when
+     * you update to a new version of the support library.
+     */
+    public static class SimpleOnItemTouchListener implements RecyclerView.OnItemTouchListener {
+        @Override
+        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
+            return false;
+        }
+
+        @Override
+        public void onTouchEvent(RecyclerView rv, MotionEvent e) {
+        }
+
+        @Override
+        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        }
+    }
+
+
+    /**
+     * An OnScrollListener can be added to a RecyclerView to receive messages when a scrolling event
+     * has occurred on that RecyclerView.
+     * <p>
+     * @see RecyclerView#addOnScrollListener(OnScrollListener)
+     * @see RecyclerView#clearOnChildAttachStateChangeListeners()
+     *
+     */
+    public abstract static class OnScrollListener {
+        /**
+         * Callback method to be invoked when RecyclerView's scroll state changes.
+         *
+         * @param recyclerView The RecyclerView whose scroll state has changed.
+         * @param newState     The updated scroll state. One of {@link #SCROLL_STATE_IDLE},
+         *                     {@link #SCROLL_STATE_DRAGGING} or {@link #SCROLL_STATE_SETTLING}.
+         */
+        public void onScrollStateChanged(RecyclerView recyclerView, int newState){}
+
+        /**
+         * Callback method to be invoked when the RecyclerView has been scrolled. This will be
+         * called after the scroll has completed.
+         * <p>
+         * This callback will also be called if visible item range changes after a layout
+         * calculation. In that case, dx and dy will be 0.
+         *
+         * @param recyclerView The RecyclerView which scrolled.
+         * @param dx The amount of horizontal scroll.
+         * @param dy The amount of vertical scroll.
+         */
+        public void onScrolled(RecyclerView recyclerView, int dx, int dy){}
+    }
+
+    /**
+     * A RecyclerListener can be set on a RecyclerView to receive messages whenever
+     * a view is recycled.
+     *
+     * @see RecyclerView#setRecyclerListener(RecyclerListener)
+     */
+    public interface RecyclerListener {
+
+        /**
+         * This method is called whenever the view in the ViewHolder is recycled.
+         *
+         * RecyclerView calls this method right before clearing ViewHolder's internal data and
+         * sending it to RecycledViewPool. This way, if ViewHolder was holding valid information
+         * before being recycled, you can call {@link ViewHolder#getAdapterPosition()} to get
+         * its adapter position.
+         *
+         * @param holder The ViewHolder containing the view that was recycled
+         */
+        void onViewRecycled(ViewHolder holder);
+    }
+
+    /**
+     * A Listener interface that can be attached to a RecylcerView to get notified
+     * whenever a ViewHolder is attached to or detached from RecyclerView.
+     */
+    public interface OnChildAttachStateChangeListener {
+
+        /**
+         * Called when a view is attached to the RecyclerView.
+         *
+         * @param view The View which is attached to the RecyclerView
+         */
+        void onChildViewAttachedToWindow(View view);
+
+        /**
+         * Called when a view is detached from RecyclerView.
+         *
+         * @param view The View which is being detached from the RecyclerView
+         */
+        void onChildViewDetachedFromWindow(View view);
+    }
+
+    /**
+     * A ViewHolder describes an item view and metadata about its place within the RecyclerView.
+     *
+     * <p>{@link Adapter} implementations should subclass ViewHolder and add fields for caching
+     * potentially expensive {@link View#findViewById(int)} results.</p>
+     *
+     * <p>While {@link LayoutParams} belong to the {@link LayoutManager},
+     * {@link ViewHolder ViewHolders} belong to the adapter. Adapters should feel free to use
+     * their own custom ViewHolder implementations to store data that makes binding view contents
+     * easier. Implementations should assume that individual item views will hold strong references
+     * to <code>ViewHolder</code> objects and that <code>RecyclerView</code> instances may hold
+     * strong references to extra off-screen item views for caching purposes</p>
+     */
+    public abstract static class ViewHolder {
+        public final View itemView;
+        WeakReference<RecyclerView> mNestedRecyclerView;
+        int mPosition = NO_POSITION;
+        int mOldPosition = NO_POSITION;
+        long mItemId = NO_ID;
+        int mItemViewType = INVALID_TYPE;
+        int mPreLayoutPosition = NO_POSITION;
+
+        // The item that this holder is shadowing during an item change event/animation
+        ViewHolder mShadowedHolder = null;
+        // The item that is shadowing this holder during an item change event/animation
+        ViewHolder mShadowingHolder = null;
+
+        /**
+         * This ViewHolder has been bound to a position; mPosition, mItemId and mItemViewType
+         * are all valid.
+         */
+        static final int FLAG_BOUND = 1 << 0;
+
+        /**
+         * The data this ViewHolder's view reflects is stale and needs to be rebound
+         * by the adapter. mPosition and mItemId are consistent.
+         */
+        static final int FLAG_UPDATE = 1 << 1;
+
+        /**
+         * This ViewHolder's data is invalid. The identity implied by mPosition and mItemId
+         * are not to be trusted and may no longer match the item view type.
+         * This ViewHolder must be fully rebound to different data.
+         */
+        static final int FLAG_INVALID = 1 << 2;
+
+        /**
+         * This ViewHolder points at data that represents an item previously removed from the
+         * data set. Its view may still be used for things like outgoing animations.
+         */
+        static final int FLAG_REMOVED = 1 << 3;
+
+        /**
+         * This ViewHolder should not be recycled. This flag is set via setIsRecyclable()
+         * and is intended to keep views around during animations.
+         */
+        static final int FLAG_NOT_RECYCLABLE = 1 << 4;
+
+        /**
+         * This ViewHolder is returned from scrap which means we are expecting an addView call
+         * for this itemView. When returned from scrap, ViewHolder stays in the scrap list until
+         * the end of the layout pass and then recycled by RecyclerView if it is not added back to
+         * the RecyclerView.
+         */
+        static final int FLAG_RETURNED_FROM_SCRAP = 1 << 5;
+
+        /**
+         * This ViewHolder is fully managed by the LayoutManager. We do not scrap, recycle or remove
+         * it unless LayoutManager is replaced.
+         * It is still fully visible to the LayoutManager.
+         */
+        static final int FLAG_IGNORE = 1 << 7;
+
+        /**
+         * When the View is detached form the parent, we set this flag so that we can take correct
+         * action when we need to remove it or add it back.
+         */
+        static final int FLAG_TMP_DETACHED = 1 << 8;
+
+        /**
+         * Set when we can no longer determine the adapter position of this ViewHolder until it is
+         * rebound to a new position. It is different than FLAG_INVALID because FLAG_INVALID is
+         * set even when the type does not match. Also, FLAG_ADAPTER_POSITION_UNKNOWN is set as soon
+         * as adapter notification arrives vs FLAG_INVALID is set lazily before layout is
+         * re-calculated.
+         */
+        static final int FLAG_ADAPTER_POSITION_UNKNOWN = 1 << 9;
+
+        /**
+         * Set when a addChangePayload(null) is called
+         */
+        static final int FLAG_ADAPTER_FULLUPDATE = 1 << 10;
+
+        /**
+         * Used by ItemAnimator when a ViewHolder's position changes
+         */
+        static final int FLAG_MOVED = 1 << 11;
+
+        /**
+         * Used by ItemAnimator when a ViewHolder appears in pre-layout
+         */
+        static final int FLAG_APPEARED_IN_PRE_LAYOUT = 1 << 12;
+
+        static final int PENDING_ACCESSIBILITY_STATE_NOT_SET = -1;
+
+        /**
+         * Used when a ViewHolder starts the layout pass as a hidden ViewHolder but is re-used from
+         * hidden list (as if it was scrap) without being recycled in between.
+         *
+         * When a ViewHolder is hidden, there are 2 paths it can be re-used:
+         *   a) Animation ends, view is recycled and used from the recycle pool.
+         *   b) LayoutManager asks for the View for that position while the ViewHolder is hidden.
+         *
+         * This flag is used to represent "case b" where the ViewHolder is reused without being
+         * recycled (thus "bounced" from the hidden list). This state requires special handling
+         * because the ViewHolder must be added to pre layout maps for animations as if it was
+         * already there.
+         */
+        static final int FLAG_BOUNCED_FROM_HIDDEN_LIST = 1 << 13;
+
+        private int mFlags;
+
+        private static final List<Object> FULLUPDATE_PAYLOADS = Collections.EMPTY_LIST;
+
+        List<Object> mPayloads = null;
+        List<Object> mUnmodifiedPayloads = null;
+
+        private int mIsRecyclableCount = 0;
+
+        // If non-null, view is currently considered scrap and may be reused for other data by the
+        // scrap container.
+        private Recycler mScrapContainer = null;
+        // Keeps whether this ViewHolder lives in Change scrap or Attached scrap
+        private boolean mInChangeScrap = false;
+
+        // Saves isImportantForAccessibility value for the view item while it's in hidden state and
+        // marked as unimportant for accessibility.
+        private int mWasImportantForAccessibilityBeforeHidden =
+                View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+        // set if we defer the accessibility state change of the view holder
+        @VisibleForTesting
+        int mPendingAccessibilityState = PENDING_ACCESSIBILITY_STATE_NOT_SET;
+
+        /**
+         * Is set when VH is bound from the adapter and cleaned right before it is sent to
+         * {@link RecycledViewPool}.
+         */
+        RecyclerView mOwnerRecyclerView;
+
+        public ViewHolder(View itemView) {
+            if (itemView == null) {
+                throw new IllegalArgumentException("itemView may not be null");
+            }
+            this.itemView = itemView;
+        }
+
+        void flagRemovedAndOffsetPosition(int mNewPosition, int offset, boolean applyToPreLayout) {
+            addFlags(ViewHolder.FLAG_REMOVED);
+            offsetPosition(offset, applyToPreLayout);
+            mPosition = mNewPosition;
+        }
+
+        void offsetPosition(int offset, boolean applyToPreLayout) {
+            if (mOldPosition == NO_POSITION) {
+                mOldPosition = mPosition;
+            }
+            if (mPreLayoutPosition == NO_POSITION) {
+                mPreLayoutPosition = mPosition;
+            }
+            if (applyToPreLayout) {
+                mPreLayoutPosition += offset;
+            }
+            mPosition += offset;
+            if (itemView.getLayoutParams() != null) {
+                ((LayoutParams) itemView.getLayoutParams()).mInsetsDirty = true;
+            }
+        }
+
+        void clearOldPosition() {
+            mOldPosition = NO_POSITION;
+            mPreLayoutPosition = NO_POSITION;
+        }
+
+        void saveOldPosition() {
+            if (mOldPosition == NO_POSITION) {
+                mOldPosition = mPosition;
+            }
+        }
+
+        boolean shouldIgnore() {
+            return (mFlags & FLAG_IGNORE) != 0;
+        }
+
+        /**
+         * @deprecated This method is deprecated because its meaning is ambiguous due to the async
+         * handling of adapter updates. Please use {@link #getLayoutPosition()} or
+         * {@link #getAdapterPosition()} depending on your use case.
+         *
+         * @see #getLayoutPosition()
+         * @see #getAdapterPosition()
+         */
+        @Deprecated
+        public final int getPosition() {
+            return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
+        }
+
+        /**
+         * Returns the position of the ViewHolder in terms of the latest layout pass.
+         * <p>
+         * This position is mostly used by RecyclerView components to be consistent while
+         * RecyclerView lazily processes adapter updates.
+         * <p>
+         * For performance and animation reasons, RecyclerView batches all adapter updates until the
+         * next layout pass. This may cause mismatches between the Adapter position of the item and
+         * the position it had in the latest layout calculations.
+         * <p>
+         * LayoutManagers should always call this method while doing calculations based on item
+         * positions. All methods in {@link RecyclerView.LayoutManager}, {@link RecyclerView.State},
+         * {@link RecyclerView.Recycler} that receive a position expect it to be the layout position
+         * of the item.
+         * <p>
+         * If LayoutManager needs to call an external method that requires the adapter position of
+         * the item, it can use {@link #getAdapterPosition()} or
+         * {@link RecyclerView.Recycler#convertPreLayoutPositionToPostLayout(int)}.
+         *
+         * @return Returns the adapter position of the ViewHolder in the latest layout pass.
+         * @see #getAdapterPosition()
+         */
+        public final int getLayoutPosition() {
+            return mPreLayoutPosition == NO_POSITION ? mPosition : mPreLayoutPosition;
+        }
+
+        /**
+         * Returns the Adapter position of the item represented by this ViewHolder.
+         * <p>
+         * Note that this might be different than the {@link #getLayoutPosition()} if there are
+         * pending adapter updates but a new layout pass has not happened yet.
+         * <p>
+         * RecyclerView does not handle any adapter updates until the next layout traversal. This
+         * may create temporary inconsistencies between what user sees on the screen and what
+         * adapter contents have. This inconsistency is not important since it will be less than
+         * 16ms but it might be a problem if you want to use ViewHolder position to access the
+         * adapter. Sometimes, you may need to get the exact adapter position to do
+         * some actions in response to user events. In that case, you should use this method which
+         * will calculate the Adapter position of the ViewHolder.
+         * <p>
+         * Note that if you've called {@link RecyclerView.Adapter#notifyDataSetChanged()}, until the
+         * next layout pass, the return value of this method will be {@link #NO_POSITION}.
+         *
+         * @return The adapter position of the item if it still exists in the adapter.
+         * {@link RecyclerView#NO_POSITION} if item has been removed from the adapter,
+         * {@link RecyclerView.Adapter#notifyDataSetChanged()} has been called after the last
+         * layout pass or the ViewHolder has already been recycled.
+         */
+        public final int getAdapterPosition() {
+            if (mOwnerRecyclerView == null) {
+                return NO_POSITION;
+            }
+            return mOwnerRecyclerView.getAdapterPositionFor(this);
+        }
+
+        /**
+         * When LayoutManager supports animations, RecyclerView tracks 3 positions for ViewHolders
+         * to perform animations.
+         * <p>
+         * If a ViewHolder was laid out in the previous onLayout call, old position will keep its
+         * adapter index in the previous layout.
+         *
+         * @return The previous adapter index of the Item represented by this ViewHolder or
+         * {@link #NO_POSITION} if old position does not exists or cleared (pre-layout is
+         * complete).
+         */
+        public final int getOldPosition() {
+            return mOldPosition;
+        }
+
+        /**
+         * Returns The itemId represented by this ViewHolder.
+         *
+         * @return The item's id if adapter has stable ids, {@link RecyclerView#NO_ID}
+         * otherwise
+         */
+        public final long getItemId() {
+            return mItemId;
+        }
+
+        /**
+         * @return The view type of this ViewHolder.
+         */
+        public final int getItemViewType() {
+            return mItemViewType;
+        }
+
+        boolean isScrap() {
+            return mScrapContainer != null;
+        }
+
+        void unScrap() {
+            mScrapContainer.unscrapView(this);
+        }
+
+        boolean wasReturnedFromScrap() {
+            return (mFlags & FLAG_RETURNED_FROM_SCRAP) != 0;
+        }
+
+        void clearReturnedFromScrapFlag() {
+            mFlags = mFlags & ~FLAG_RETURNED_FROM_SCRAP;
+        }
+
+        void clearTmpDetachFlag() {
+            mFlags = mFlags & ~FLAG_TMP_DETACHED;
+        }
+
+        void stopIgnoring() {
+            mFlags = mFlags & ~FLAG_IGNORE;
+        }
+
+        void setScrapContainer(Recycler recycler, boolean isChangeScrap) {
+            mScrapContainer = recycler;
+            mInChangeScrap = isChangeScrap;
+        }
+
+        boolean isInvalid() {
+            return (mFlags & FLAG_INVALID) != 0;
+        }
+
+        boolean needsUpdate() {
+            return (mFlags & FLAG_UPDATE) != 0;
+        }
+
+        boolean isBound() {
+            return (mFlags & FLAG_BOUND) != 0;
+        }
+
+        boolean isRemoved() {
+            return (mFlags & FLAG_REMOVED) != 0;
+        }
+
+        boolean hasAnyOfTheFlags(int flags) {
+            return (mFlags & flags) != 0;
+        }
+
+        boolean isTmpDetached() {
+            return (mFlags & FLAG_TMP_DETACHED) != 0;
+        }
+
+        boolean isAdapterPositionUnknown() {
+            return (mFlags & FLAG_ADAPTER_POSITION_UNKNOWN) != 0 || isInvalid();
+        }
+
+        void setFlags(int flags, int mask) {
+            mFlags = (mFlags & ~mask) | (flags & mask);
+        }
+
+        void addFlags(int flags) {
+            mFlags |= flags;
+        }
+
+        void addChangePayload(Object payload) {
+            if (payload == null) {
+                addFlags(FLAG_ADAPTER_FULLUPDATE);
+            } else if ((mFlags & FLAG_ADAPTER_FULLUPDATE) == 0) {
+                createPayloadsIfNeeded();
+                mPayloads.add(payload);
+            }
+        }
+
+        private void createPayloadsIfNeeded() {
+            if (mPayloads == null) {
+                mPayloads = new ArrayList<Object>();
+                mUnmodifiedPayloads = Collections.unmodifiableList(mPayloads);
+            }
+        }
+
+        void clearPayload() {
+            if (mPayloads != null) {
+                mPayloads.clear();
+            }
+            mFlags = mFlags & ~FLAG_ADAPTER_FULLUPDATE;
+        }
+
+        List<Object> getUnmodifiedPayloads() {
+            if ((mFlags & FLAG_ADAPTER_FULLUPDATE) == 0) {
+                if (mPayloads == null || mPayloads.size() == 0) {
+                    // Initial state,  no update being called.
+                    return FULLUPDATE_PAYLOADS;
+                }
+                // there are none-null payloads
+                return mUnmodifiedPayloads;
+            } else {
+                // a full update has been called.
+                return FULLUPDATE_PAYLOADS;
+            }
+        }
+
+        void resetInternal() {
+            mFlags = 0;
+            mPosition = NO_POSITION;
+            mOldPosition = NO_POSITION;
+            mItemId = NO_ID;
+            mPreLayoutPosition = NO_POSITION;
+            mIsRecyclableCount = 0;
+            mShadowedHolder = null;
+            mShadowingHolder = null;
+            clearPayload();
+            mWasImportantForAccessibilityBeforeHidden = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+            mPendingAccessibilityState = PENDING_ACCESSIBILITY_STATE_NOT_SET;
+            clearNestedRecyclerViewIfNotNested(this);
+        }
+
+        /**
+         * Called when the child view enters the hidden state
+         */
+        private void onEnteredHiddenState(RecyclerView parent) {
+            // While the view item is in hidden state, make it invisible for the accessibility.
+            mWasImportantForAccessibilityBeforeHidden =
+                    itemView.getImportantForAccessibility();
+            parent.setChildImportantForAccessibilityInternal(this,
+                    View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+        }
+
+        /**
+         * Called when the child view leaves the hidden state
+         */
+        private void onLeftHiddenState(RecyclerView parent) {
+            parent.setChildImportantForAccessibilityInternal(this,
+                    mWasImportantForAccessibilityBeforeHidden);
+            mWasImportantForAccessibilityBeforeHidden = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder("ViewHolder{"
+                    + Integer.toHexString(hashCode()) + " position=" + mPosition + " id=" + mItemId
+                    + ", oldPos=" + mOldPosition + ", pLpos:" + mPreLayoutPosition);
+            if (isScrap()) {
+                sb.append(" scrap ")
+                        .append(mInChangeScrap ? "[changeScrap]" : "[attachedScrap]");
+            }
+            if (isInvalid()) sb.append(" invalid");
+            if (!isBound()) sb.append(" unbound");
+            if (needsUpdate()) sb.append(" update");
+            if (isRemoved()) sb.append(" removed");
+            if (shouldIgnore()) sb.append(" ignored");
+            if (isTmpDetached()) sb.append(" tmpDetached");
+            if (!isRecyclable()) sb.append(" not recyclable(" + mIsRecyclableCount + ")");
+            if (isAdapterPositionUnknown()) sb.append(" undefined adapter position");
+
+            if (itemView.getParent() == null) sb.append(" no parent");
+            sb.append("}");
+            return sb.toString();
+        }
+
+        /**
+         * Informs the recycler whether this item can be recycled. Views which are not
+         * recyclable will not be reused for other items until setIsRecyclable() is
+         * later set to true. Calls to setIsRecyclable() should always be paired (one
+         * call to setIsRecyclabe(false) should always be matched with a later call to
+         * setIsRecyclable(true)). Pairs of calls may be nested, as the state is internally
+         * reference-counted.
+         *
+         * @param recyclable Whether this item is available to be recycled. Default value
+         * is true.
+         *
+         * @see #isRecyclable()
+         */
+        public final void setIsRecyclable(boolean recyclable) {
+            mIsRecyclableCount = recyclable ? mIsRecyclableCount - 1 : mIsRecyclableCount + 1;
+            if (mIsRecyclableCount < 0) {
+                mIsRecyclableCount = 0;
+                if (DEBUG) {
+                    throw new RuntimeException("isRecyclable decremented below 0: "
+                            + "unmatched pair of setIsRecyable() calls for " + this);
+                }
+                Log.e(VIEW_LOG_TAG, "isRecyclable decremented below 0: "
+                        + "unmatched pair of setIsRecyable() calls for " + this);
+            } else if (!recyclable && mIsRecyclableCount == 1) {
+                mFlags |= FLAG_NOT_RECYCLABLE;
+            } else if (recyclable && mIsRecyclableCount == 0) {
+                mFlags &= ~FLAG_NOT_RECYCLABLE;
+            }
+            if (DEBUG) {
+                Log.d(TAG, "setIsRecyclable val:" + recyclable + ":" + this);
+            }
+        }
+
+        /**
+         * @return true if this item is available to be recycled, false otherwise.
+         *
+         * @see #setIsRecyclable(boolean)
+         */
+        public final boolean isRecyclable() {
+            return (mFlags & FLAG_NOT_RECYCLABLE) == 0
+                    && !itemView.hasTransientState();
+        }
+
+        /**
+         * Returns whether we have animations referring to this view holder or not.
+         * This is similar to isRecyclable flag but does not check transient state.
+         */
+        private boolean shouldBeKeptAsChild() {
+            return (mFlags & FLAG_NOT_RECYCLABLE) != 0;
+        }
+
+        /**
+         * @return True if ViewHolder is not referenced by RecyclerView animations but has
+         * transient state which will prevent it from being recycled.
+         */
+        private boolean doesTransientStatePreventRecycling() {
+            return (mFlags & FLAG_NOT_RECYCLABLE) == 0 && itemView.hasTransientState();
+        }
+
+        boolean isUpdated() {
+            return (mFlags & FLAG_UPDATE) != 0;
+        }
+    }
+
+    /**
+     * This method is here so that we can control the important for a11y changes and test it.
+     */
+    @VisibleForTesting
+    boolean setChildImportantForAccessibilityInternal(ViewHolder viewHolder,
+            int importantForAccessibility) {
+        if (isComputingLayout()) {
+            viewHolder.mPendingAccessibilityState = importantForAccessibility;
+            mPendingAccessibilityImportanceChange.add(viewHolder);
+            return false;
+        }
+        viewHolder.itemView.setImportantForAccessibility(importantForAccessibility);
+        return true;
+    }
+
+    void dispatchPendingImportantForAccessibilityChanges() {
+        for (int i = mPendingAccessibilityImportanceChange.size() - 1; i >= 0; i--) {
+            ViewHolder viewHolder = mPendingAccessibilityImportanceChange.get(i);
+            if (viewHolder.itemView.getParent() != this || viewHolder.shouldIgnore()) {
+                continue;
+            }
+            int state = viewHolder.mPendingAccessibilityState;
+            if (state != ViewHolder.PENDING_ACCESSIBILITY_STATE_NOT_SET) {
+                //noinspection WrongConstant
+                viewHolder.itemView.setImportantForAccessibility(state);
+                viewHolder.mPendingAccessibilityState =
+                        ViewHolder.PENDING_ACCESSIBILITY_STATE_NOT_SET;
+            }
+        }
+        mPendingAccessibilityImportanceChange.clear();
+    }
+
+    int getAdapterPositionFor(ViewHolder viewHolder) {
+        if (viewHolder.hasAnyOfTheFlags(ViewHolder.FLAG_INVALID
+                | ViewHolder.FLAG_REMOVED | ViewHolder.FLAG_ADAPTER_POSITION_UNKNOWN)
+                || !viewHolder.isBound()) {
+            return RecyclerView.NO_POSITION;
+        }
+        return mAdapterHelper.applyPendingUpdatesToPosition(viewHolder.mPosition);
+    }
+
+    /**
+     * {@link android.view.ViewGroup.MarginLayoutParams LayoutParams} subclass for children of
+     * {@link RecyclerView}. Custom {@link LayoutManager layout managers} are encouraged
+     * to create their own subclass of this <code>LayoutParams</code> class
+     * to store any additional required per-child view metadata about the layout.
+     */
+    public static class LayoutParams extends android.view.ViewGroup.MarginLayoutParams {
+        ViewHolder mViewHolder;
+        final Rect mDecorInsets = new Rect();
+        boolean mInsetsDirty = true;
+        // Flag is set to true if the view is bound while it is detached from RV.
+        // In this case, we need to manually call invalidate after view is added to guarantee that
+        // invalidation is populated through the View hierarchy
+        boolean mPendingInvalidate = false;
+
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+        }
+
+        public LayoutParams(int width, int height) {
+            super(width, height);
+        }
+
+        public LayoutParams(MarginLayoutParams source) {
+            super(source);
+        }
+
+        public LayoutParams(ViewGroup.LayoutParams source) {
+            super(source);
+        }
+
+        public LayoutParams(LayoutParams source) {
+            super((ViewGroup.LayoutParams) source);
+        }
+
+        /**
+         * Returns true if the view this LayoutParams is attached to needs to have its content
+         * updated from the corresponding adapter.
+         *
+         * @return true if the view should have its content updated
+         */
+        public boolean viewNeedsUpdate() {
+            return mViewHolder.needsUpdate();
+        }
+
+        /**
+         * Returns true if the view this LayoutParams is attached to is now representing
+         * potentially invalid data. A LayoutManager should scrap/recycle it.
+         *
+         * @return true if the view is invalid
+         */
+        public boolean isViewInvalid() {
+            return mViewHolder.isInvalid();
+        }
+
+        /**
+         * Returns true if the adapter data item corresponding to the view this LayoutParams
+         * is attached to has been removed from the data set. A LayoutManager may choose to
+         * treat it differently in order to animate its outgoing or disappearing state.
+         *
+         * @return true if the item the view corresponds to was removed from the data set
+         */
+        public boolean isItemRemoved() {
+            return mViewHolder.isRemoved();
+        }
+
+        /**
+         * Returns true if the adapter data item corresponding to the view this LayoutParams
+         * is attached to has been changed in the data set. A LayoutManager may choose to
+         * treat it differently in order to animate its changing state.
+         *
+         * @return true if the item the view corresponds to was changed in the data set
+         */
+        public boolean isItemChanged() {
+            return mViewHolder.isUpdated();
+        }
+
+        /**
+         * @deprecated use {@link #getViewLayoutPosition()} or {@link #getViewAdapterPosition()}
+         */
+        @Deprecated
+        public int getViewPosition() {
+            return mViewHolder.getPosition();
+        }
+
+        /**
+         * Returns the adapter position that the view this LayoutParams is attached to corresponds
+         * to as of latest layout calculation.
+         *
+         * @return the adapter position this view as of latest layout pass
+         */
+        public int getViewLayoutPosition() {
+            return mViewHolder.getLayoutPosition();
+        }
+
+        /**
+         * Returns the up-to-date adapter position that the view this LayoutParams is attached to
+         * corresponds to.
+         *
+         * @return the up-to-date adapter position this view. It may return
+         * {@link RecyclerView#NO_POSITION} if item represented by this View has been removed or
+         * its up-to-date position cannot be calculated.
+         */
+        public int getViewAdapterPosition() {
+            return mViewHolder.getAdapterPosition();
+        }
+    }
+
+    /**
+     * Observer base class for watching changes to an {@link Adapter}.
+     * See {@link Adapter#registerAdapterDataObserver(AdapterDataObserver)}.
+     */
+    public abstract static class AdapterDataObserver {
+        public void onChanged() {
+            // Do nothing
+        }
+
+        public void onItemRangeChanged(int positionStart, int itemCount) {
+            // do nothing
+        }
+
+        public void onItemRangeChanged(int positionStart, int itemCount, Object payload) {
+            // fallback to onItemRangeChanged(positionStart, itemCount) if app
+            // does not override this method.
+            onItemRangeChanged(positionStart, itemCount);
+        }
+
+        public void onItemRangeInserted(int positionStart, int itemCount) {
+            // do nothing
+        }
+
+        public void onItemRangeRemoved(int positionStart, int itemCount) {
+            // do nothing
+        }
+
+        public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
+            // do nothing
+        }
+    }
+
+    /**
+     * <p>Base class for smooth scrolling. Handles basic tracking of the target view position and
+     * provides methods to trigger a programmatic scroll.</p>
+     *
+     * @see LinearSmoothScroller
+     */
+    public abstract static class SmoothScroller {
+
+        private int mTargetPosition = RecyclerView.NO_POSITION;
+
+        private RecyclerView mRecyclerView;
+
+        private LayoutManager mLayoutManager;
+
+        private boolean mPendingInitialRun;
+
+        private boolean mRunning;
+
+        private View mTargetView;
+
+        private final Action mRecyclingAction;
+
+        public SmoothScroller() {
+            mRecyclingAction = new Action(0, 0);
+        }
+
+        /**
+         * Starts a smooth scroll for the given target position.
+         * <p>In each animation step, {@link RecyclerView} will check
+         * for the target view and call either
+         * {@link #onTargetFound(android.view.View, RecyclerView.State, SmoothScroller.Action)} or
+         * {@link #onSeekTargetStep(int, int, RecyclerView.State, SmoothScroller.Action)} until
+         * SmoothScroller is stopped.</p>
+         *
+         * <p>Note that if RecyclerView finds the target view, it will automatically stop the
+         * SmoothScroller. This <b>does not</b> mean that scroll will stop, it only means it will
+         * stop calling SmoothScroller in each animation step.</p>
+         */
+        void start(RecyclerView recyclerView, LayoutManager layoutManager) {
+            mRecyclerView = recyclerView;
+            mLayoutManager = layoutManager;
+            if (mTargetPosition == RecyclerView.NO_POSITION) {
+                throw new IllegalArgumentException("Invalid target position");
+            }
+            mRecyclerView.mState.mTargetPosition = mTargetPosition;
+            mRunning = true;
+            mPendingInitialRun = true;
+            mTargetView = findViewByPosition(getTargetPosition());
+            onStart();
+            mRecyclerView.mViewFlinger.postOnAnimation();
+        }
+
+        public void setTargetPosition(int targetPosition) {
+            mTargetPosition = targetPosition;
+        }
+
+        /**
+         * @return The LayoutManager to which this SmoothScroller is attached. Will return
+         * <code>null</code> after the SmoothScroller is stopped.
+         */
+        @Nullable
+        public LayoutManager getLayoutManager() {
+            return mLayoutManager;
+        }
+
+        /**
+         * Stops running the SmoothScroller in each animation callback. Note that this does not
+         * cancel any existing {@link Action} updated by
+         * {@link #onTargetFound(android.view.View, RecyclerView.State, SmoothScroller.Action)} or
+         * {@link #onSeekTargetStep(int, int, RecyclerView.State, SmoothScroller.Action)}.
+         */
+        protected final void stop() {
+            if (!mRunning) {
+                return;
+            }
+            onStop();
+            mRecyclerView.mState.mTargetPosition = RecyclerView.NO_POSITION;
+            mTargetView = null;
+            mTargetPosition = RecyclerView.NO_POSITION;
+            mPendingInitialRun = false;
+            mRunning = false;
+            // trigger a cleanup
+            mLayoutManager.onSmoothScrollerStopped(this);
+            // clear references to avoid any potential leak by a custom smooth scroller
+            mLayoutManager = null;
+            mRecyclerView = null;
+        }
+
+        /**
+         * Returns true if SmoothScroller has been started but has not received the first
+         * animation
+         * callback yet.
+         *
+         * @return True if this SmoothScroller is waiting to start
+         */
+        public boolean isPendingInitialRun() {
+            return mPendingInitialRun;
+        }
+
+
+        /**
+         * @return True if SmoothScroller is currently active
+         */
+        public boolean isRunning() {
+            return mRunning;
+        }
+
+        /**
+         * Returns the adapter position of the target item
+         *
+         * @return Adapter position of the target item or
+         * {@link RecyclerView#NO_POSITION} if no target view is set.
+         */
+        public int getTargetPosition() {
+            return mTargetPosition;
+        }
+
+        private void onAnimation(int dx, int dy) {
+            final RecyclerView recyclerView = mRecyclerView;
+            if (!mRunning || mTargetPosition == RecyclerView.NO_POSITION || recyclerView == null) {
+                stop();
+            }
+            mPendingInitialRun = false;
+            if (mTargetView != null) {
+                // verify target position
+                if (getChildPosition(mTargetView) == mTargetPosition) {
+                    onTargetFound(mTargetView, recyclerView.mState, mRecyclingAction);
+                    mRecyclingAction.runIfNecessary(recyclerView);
+                    stop();
+                } else {
+                    Log.e(TAG, "Passed over target position while smooth scrolling.");
+                    mTargetView = null;
+                }
+            }
+            if (mRunning) {
+                onSeekTargetStep(dx, dy, recyclerView.mState, mRecyclingAction);
+                boolean hadJumpTarget = mRecyclingAction.hasJumpTarget();
+                mRecyclingAction.runIfNecessary(recyclerView);
+                if (hadJumpTarget) {
+                    // It is not stopped so needs to be restarted
+                    if (mRunning) {
+                        mPendingInitialRun = true;
+                        recyclerView.mViewFlinger.postOnAnimation();
+                    } else {
+                        stop(); // done
+                    }
+                }
+            }
+        }
+
+        /**
+         * @see RecyclerView#getChildLayoutPosition(android.view.View)
+         */
+        public int getChildPosition(View view) {
+            return mRecyclerView.getChildLayoutPosition(view);
+        }
+
+        /**
+         * @see RecyclerView.LayoutManager#getChildCount()
+         */
+        public int getChildCount() {
+            return mRecyclerView.mLayout.getChildCount();
+        }
+
+        /**
+         * @see RecyclerView.LayoutManager#findViewByPosition(int)
+         */
+        public View findViewByPosition(int position) {
+            return mRecyclerView.mLayout.findViewByPosition(position);
+        }
+
+        /**
+         * @see RecyclerView#scrollToPosition(int)
+         * @deprecated Use {@link Action#jumpTo(int)}.
+         */
+        @Deprecated
+        public void instantScrollToPosition(int position) {
+            mRecyclerView.scrollToPosition(position);
+        }
+
+        protected void onChildAttachedToWindow(View child) {
+            if (getChildPosition(child) == getTargetPosition()) {
+                mTargetView = child;
+                if (DEBUG) {
+                    Log.d(TAG, "smooth scroll target view has been attached");
+                }
+            }
+        }
+
+        /**
+         * Normalizes the vector.
+         * @param scrollVector The vector that points to the target scroll position
+         */
+        protected void normalize(PointF scrollVector) {
+            final double magnitude = Math.sqrt(scrollVector.x * scrollVector.x + scrollVector.y
+                    * scrollVector.y);
+            scrollVector.x /= magnitude;
+            scrollVector.y /= magnitude;
+        }
+
+        /**
+         * Called when smooth scroll is started. This might be a good time to do setup.
+         */
+        protected abstract void onStart();
+
+        /**
+         * Called when smooth scroller is stopped. This is a good place to cleanup your state etc.
+         * @see #stop()
+         */
+        protected abstract void onStop();
+
+        /**
+         * <p>RecyclerView will call this method each time it scrolls until it can find the target
+         * position in the layout.</p>
+         * <p>SmoothScroller should check dx, dy and if scroll should be changed, update the
+         * provided {@link Action} to define the next scroll.</p>
+         *
+         * @param dx        Last scroll amount horizontally
+         * @param dy        Last scroll amount vertically
+         * @param state     Transient state of RecyclerView
+         * @param action    If you want to trigger a new smooth scroll and cancel the previous one,
+         *                  update this object.
+         */
+        protected abstract void onSeekTargetStep(int dx, int dy, State state, Action action);
+
+        /**
+         * Called when the target position is laid out. This is the last callback SmoothScroller
+         * will receive and it should update the provided {@link Action} to define the scroll
+         * details towards the target view.
+         * @param targetView    The view element which render the target position.
+         * @param state         Transient state of RecyclerView
+         * @param action        Action instance that you should update to define final scroll action
+         *                      towards the targetView
+         */
+        protected abstract void onTargetFound(View targetView, State state, Action action);
+
+        /**
+         * Holds information about a smooth scroll request by a {@link SmoothScroller}.
+         */
+        public static class Action {
+
+            public static final int UNDEFINED_DURATION = Integer.MIN_VALUE;
+
+            private int mDx;
+
+            private int mDy;
+
+            private int mDuration;
+
+            private int mJumpToPosition = NO_POSITION;
+
+            private Interpolator mInterpolator;
+
+            private boolean mChanged = false;
+
+            // we track this variable to inform custom implementer if they are updating the action
+            // in every animation callback
+            private int mConsecutiveUpdates = 0;
+
+            /**
+             * @param dx Pixels to scroll horizontally
+             * @param dy Pixels to scroll vertically
+             */
+            public Action(int dx, int dy) {
+                this(dx, dy, UNDEFINED_DURATION, null);
+            }
+
+            /**
+             * @param dx       Pixels to scroll horizontally
+             * @param dy       Pixels to scroll vertically
+             * @param duration Duration of the animation in milliseconds
+             */
+            public Action(int dx, int dy, int duration) {
+                this(dx, dy, duration, null);
+            }
+
+            /**
+             * @param dx           Pixels to scroll horizontally
+             * @param dy           Pixels to scroll vertically
+             * @param duration     Duration of the animation in milliseconds
+             * @param interpolator Interpolator to be used when calculating scroll position in each
+             *                     animation step
+             */
+            public Action(int dx, int dy, int duration, Interpolator interpolator) {
+                mDx = dx;
+                mDy = dy;
+                mDuration = duration;
+                mInterpolator = interpolator;
+            }
+
+            /**
+             * Instead of specifying pixels to scroll, use the target position to jump using
+             * {@link RecyclerView#scrollToPosition(int)}.
+             * <p>
+             * You may prefer using this method if scroll target is really far away and you prefer
+             * to jump to a location and smooth scroll afterwards.
+             * <p>
+             * Note that calling this method takes priority over other update methods such as
+             * {@link #update(int, int, int, Interpolator)}, {@link #setX(float)},
+             * {@link #setY(float)} and #{@link #setInterpolator(Interpolator)}. If you call
+             * {@link #jumpTo(int)}, the other changes will not be considered for this animation
+             * frame.
+             *
+             * @param targetPosition The target item position to scroll to using instant scrolling.
+             */
+            public void jumpTo(int targetPosition) {
+                mJumpToPosition = targetPosition;
+            }
+
+            boolean hasJumpTarget() {
+                return mJumpToPosition >= 0;
+            }
+
+            void runIfNecessary(RecyclerView recyclerView) {
+                if (mJumpToPosition >= 0) {
+                    final int position = mJumpToPosition;
+                    mJumpToPosition = NO_POSITION;
+                    recyclerView.jumpToPositionForSmoothScroller(position);
+                    mChanged = false;
+                    return;
+                }
+                if (mChanged) {
+                    validate();
+                    if (mInterpolator == null) {
+                        if (mDuration == UNDEFINED_DURATION) {
+                            recyclerView.mViewFlinger.smoothScrollBy(mDx, mDy);
+                        } else {
+                            recyclerView.mViewFlinger.smoothScrollBy(mDx, mDy, mDuration);
+                        }
+                    } else {
+                        recyclerView.mViewFlinger.smoothScrollBy(
+                                mDx, mDy, mDuration, mInterpolator);
+                    }
+                    mConsecutiveUpdates++;
+                    if (mConsecutiveUpdates > 10) {
+                        // A new action is being set in every animation step. This looks like a bad
+                        // implementation. Inform developer.
+                        Log.e(TAG, "Smooth Scroll action is being updated too frequently. Make sure"
+                                + " you are not changing it unless necessary");
+                    }
+                    mChanged = false;
+                } else {
+                    mConsecutiveUpdates = 0;
+                }
+            }
+
+            private void validate() {
+                if (mInterpolator != null && mDuration < 1) {
+                    throw new IllegalStateException("If you provide an interpolator, you must"
+                            + " set a positive duration");
+                } else if (mDuration < 1) {
+                    throw new IllegalStateException("Scroll duration must be a positive number");
+                }
+            }
+
+            public int getDx() {
+                return mDx;
+            }
+
+            public void setDx(int dx) {
+                mChanged = true;
+                mDx = dx;
+            }
+
+            public int getDy() {
+                return mDy;
+            }
+
+            public void setDy(int dy) {
+                mChanged = true;
+                mDy = dy;
+            }
+
+            public int getDuration() {
+                return mDuration;
+            }
+
+            public void setDuration(int duration) {
+                mChanged = true;
+                mDuration = duration;
+            }
+
+            public Interpolator getInterpolator() {
+                return mInterpolator;
+            }
+
+            /**
+             * Sets the interpolator to calculate scroll steps
+             * @param interpolator The interpolator to use. If you specify an interpolator, you must
+             *                     also set the duration.
+             * @see #setDuration(int)
+             */
+            public void setInterpolator(Interpolator interpolator) {
+                mChanged = true;
+                mInterpolator = interpolator;
+            }
+
+            /**
+             * Updates the action with given parameters.
+             * @param dx Pixels to scroll horizontally
+             * @param dy Pixels to scroll vertically
+             * @param duration Duration of the animation in milliseconds
+             * @param interpolator Interpolator to be used when calculating scroll position in each
+             *                     animation step
+             */
+            public void update(int dx, int dy, int duration, Interpolator interpolator) {
+                mDx = dx;
+                mDy = dy;
+                mDuration = duration;
+                mInterpolator = interpolator;
+                mChanged = true;
+            }
+        }
+
+        /**
+         * An interface which is optionally implemented by custom {@link RecyclerView.LayoutManager}
+         * to provide a hint to a {@link SmoothScroller} about the location of the target position.
+         */
+        public interface ScrollVectorProvider {
+            /**
+             * Should calculate the vector that points to the direction where the target position
+             * can be found.
+             * <p>
+             * This method is used by the {@link LinearSmoothScroller} to initiate a scroll towards
+             * the target position.
+             * <p>
+             * The magnitude of the vector is not important. It is always normalized before being
+             * used by the {@link LinearSmoothScroller}.
+             * <p>
+             * LayoutManager should not check whether the position exists in the adapter or not.
+             *
+             * @param targetPosition the target position to which the returned vector should point
+             *
+             * @return the scroll vector for a given position.
+             */
+            PointF computeScrollVectorForPosition(int targetPosition);
+        }
+    }
+
+    static class AdapterDataObservable extends Observable<AdapterDataObserver> {
+        public boolean hasObservers() {
+            return !mObservers.isEmpty();
+        }
+
+        public void notifyChanged() {
+            // since onChanged() is implemented by the app, it could do anything, including
+            // removing itself from {@link mObservers} - and that could cause problems if
+            // an iterator is used on the ArrayList {@link mObservers}.
+            // to avoid such problems, just march thru the list in the reverse order.
+            for (int i = mObservers.size() - 1; i >= 0; i--) {
+                mObservers.get(i).onChanged();
+            }
+        }
+
+        public void notifyItemRangeChanged(int positionStart, int itemCount) {
+            notifyItemRangeChanged(positionStart, itemCount, null);
+        }
+
+        public void notifyItemRangeChanged(int positionStart, int itemCount, Object payload) {
+            // since onItemRangeChanged() is implemented by the app, it could do anything, including
+            // removing itself from {@link mObservers} - and that could cause problems if
+            // an iterator is used on the ArrayList {@link mObservers}.
+            // to avoid such problems, just march thru the list in the reverse order.
+            for (int i = mObservers.size() - 1; i >= 0; i--) {
+                mObservers.get(i).onItemRangeChanged(positionStart, itemCount, payload);
+            }
+        }
+
+        public void notifyItemRangeInserted(int positionStart, int itemCount) {
+            // since onItemRangeInserted() is implemented by the app, it could do anything,
+            // including removing itself from {@link mObservers} - and that could cause problems if
+            // an iterator is used on the ArrayList {@link mObservers}.
+            // to avoid such problems, just march thru the list in the reverse order.
+            for (int i = mObservers.size() - 1; i >= 0; i--) {
+                mObservers.get(i).onItemRangeInserted(positionStart, itemCount);
+            }
+        }
+
+        public void notifyItemRangeRemoved(int positionStart, int itemCount) {
+            // since onItemRangeRemoved() is implemented by the app, it could do anything, including
+            // removing itself from {@link mObservers} - and that could cause problems if
+            // an iterator is used on the ArrayList {@link mObservers}.
+            // to avoid such problems, just march thru the list in the reverse order.
+            for (int i = mObservers.size() - 1; i >= 0; i--) {
+                mObservers.get(i).onItemRangeRemoved(positionStart, itemCount);
+            }
+        }
+
+        public void notifyItemMoved(int fromPosition, int toPosition) {
+            for (int i = mObservers.size() - 1; i >= 0; i--) {
+                mObservers.get(i).onItemRangeMoved(fromPosition, toPosition, 1);
+            }
+        }
+    }
+
+    /**
+     * This is public so that the CREATOR can be access on cold launch.
+     * @hide
+     */
+    public static class SavedState extends AbsSavedState {
+
+        Parcelable mLayoutState;
+
+        /**
+         * called by CREATOR
+         */
+        SavedState(Parcel in) {
+            super(in);
+            mLayoutState = in.readParcelable(LayoutManager.class.getClassLoader());
+        }
+
+        /**
+         * Called by onSaveInstanceState
+         */
+        SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+            dest.writeParcelable(mLayoutState, 0);
+        }
+
+        void copyFrom(SavedState other) {
+            mLayoutState = other.mLayoutState;
+        }
+
+        public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
+                    @Override
+                    public SavedState createFromParcel(Parcel in) {
+                        return new SavedState(in);
+                    }
+
+                    @Override
+                    public SavedState[] newArray(int size) {
+                        return new SavedState[size];
+                    }
+                };
+    }
+    /**
+     * <p>Contains useful information about the current RecyclerView state like target scroll
+     * position or view focus. State object can also keep arbitrary data, identified by resource
+     * ids.</p>
+     * <p>Often times, RecyclerView components will need to pass information between each other.
+     * To provide a well defined data bus between components, RecyclerView passes the same State
+     * object to component callbacks and these components can use it to exchange data.</p>
+     * <p>If you implement custom components, you can use State's put/get/remove methods to pass
+     * data between your components without needing to manage their lifecycles.</p>
+     */
+    public static class State {
+        static final int STEP_START = 1;
+        static final int STEP_LAYOUT = 1 << 1;
+        static final int STEP_ANIMATIONS = 1 << 2;
+
+        void assertLayoutStep(int accepted) {
+            if ((accepted & mLayoutStep) == 0) {
+                throw new IllegalStateException("Layout state should be one of "
+                        + Integer.toBinaryString(accepted) + " but it is "
+                        + Integer.toBinaryString(mLayoutStep));
+            }
+        }
+
+
+        /** Owned by SmoothScroller */
+        private int mTargetPosition = RecyclerView.NO_POSITION;
+
+        private SparseArray<Object> mData;
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // Fields below are carried from one layout pass to the next
+        ////////////////////////////////////////////////////////////////////////////////////////////
+
+        /**
+         * Number of items adapter had in the previous layout.
+         */
+        int mPreviousLayoutItemCount = 0;
+
+        /**
+         * Number of items that were NOT laid out but has been deleted from the adapter after the
+         * previous layout.
+         */
+        int mDeletedInvisibleItemCountSincePreviousLayout = 0;
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // Fields below must be updated or cleared before they are used (generally before a pass)
+        ////////////////////////////////////////////////////////////////////////////////////////////
+
+        @IntDef(flag = true, value = {
+                STEP_START, STEP_LAYOUT, STEP_ANIMATIONS
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        @interface LayoutState {}
+
+        @LayoutState
+        int mLayoutStep = STEP_START;
+
+        /**
+         * Number of items adapter has.
+         */
+        int mItemCount = 0;
+
+        boolean mStructureChanged = false;
+
+        boolean mInPreLayout = false;
+
+        boolean mTrackOldChangeHolders = false;
+
+        boolean mIsMeasuring = false;
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+        // Fields below are always reset outside of the pass (or passes) that use them
+        ////////////////////////////////////////////////////////////////////////////////////////////
+
+        boolean mRunSimpleAnimations = false;
+
+        boolean mRunPredictiveAnimations = false;
+
+        /**
+         * This data is saved before a layout calculation happens. After the layout is finished,
+         * if the previously focused view has been replaced with another view for the same item, we
+         * move the focus to the new item automatically.
+         */
+        int mFocusedItemPosition;
+        long mFocusedItemId;
+        // when a sub child has focus, record its id and see if we can directly request focus on
+        // that one instead
+        int mFocusedSubChildId;
+
+        ////////////////////////////////////////////////////////////////////////////////////////////
+
+        State reset() {
+            mTargetPosition = RecyclerView.NO_POSITION;
+            if (mData != null) {
+                mData.clear();
+            }
+            mItemCount = 0;
+            mStructureChanged = false;
+            mIsMeasuring = false;
+            return this;
+        }
+
+        /**
+         * Prepare for a prefetch occurring on the RecyclerView in between traversals, potentially
+         * prior to any layout passes.
+         *
+         * <p>Don't touch any state stored between layout passes, only reset per-layout state, so
+         * that Recycler#getViewForPosition() can function safely.</p>
+         */
+        void prepareForNestedPrefetch(Adapter adapter) {
+            mLayoutStep = STEP_START;
+            mItemCount = adapter.getItemCount();
+            mStructureChanged = false;
+            mInPreLayout = false;
+            mTrackOldChangeHolders = false;
+            mIsMeasuring = false;
+        }
+
+        /**
+         * Returns true if the RecyclerView is currently measuring the layout. This value is
+         * {@code true} only if the LayoutManager opted into the auto measure API and RecyclerView
+         * has non-exact measurement specs.
+         * <p>
+         * Note that if the LayoutManager supports predictive animations and it is calculating the
+         * pre-layout step, this value will be {@code false} even if the RecyclerView is in
+         * {@code onMeasure} call. This is because pre-layout means the previous state of the
+         * RecyclerView and measurements made for that state cannot change the RecyclerView's size.
+         * LayoutManager is always guaranteed to receive another call to
+         * {@link LayoutManager#onLayoutChildren(Recycler, State)} when this happens.
+         *
+         * @return True if the RecyclerView is currently calculating its bounds, false otherwise.
+         */
+        public boolean isMeasuring() {
+            return mIsMeasuring;
+        }
+
+        /**
+         * Returns true if
+         * @return
+         */
+        public boolean isPreLayout() {
+            return mInPreLayout;
+        }
+
+        /**
+         * Returns whether RecyclerView will run predictive animations in this layout pass
+         * or not.
+         *
+         * @return true if RecyclerView is calculating predictive animations to be run at the end
+         *         of the layout pass.
+         */
+        public boolean willRunPredictiveAnimations() {
+            return mRunPredictiveAnimations;
+        }
+
+        /**
+         * Returns whether RecyclerView will run simple animations in this layout pass
+         * or not.
+         *
+         * @return true if RecyclerView is calculating simple animations to be run at the end of
+         *         the layout pass.
+         */
+        public boolean willRunSimpleAnimations() {
+            return mRunSimpleAnimations;
+        }
+
+        /**
+         * Removes the mapping from the specified id, if there was any.
+         * @param resourceId Id of the resource you want to remove. It is suggested to use R.id.* to
+         *                   preserve cross functionality and avoid conflicts.
+         */
+        public void remove(int resourceId) {
+            if (mData == null) {
+                return;
+            }
+            mData.remove(resourceId);
+        }
+
+        /**
+         * Gets the Object mapped from the specified id, or <code>null</code>
+         * if no such data exists.
+         *
+         * @param resourceId Id of the resource you want to remove. It is suggested to use R.id.*
+         *                   to
+         *                   preserve cross functionality and avoid conflicts.
+         */
+        public <T> T get(int resourceId) {
+            if (mData == null) {
+                return null;
+            }
+            return (T) mData.get(resourceId);
+        }
+
+        /**
+         * Adds a mapping from the specified id to the specified value, replacing the previous
+         * mapping from the specified key if there was one.
+         *
+         * @param resourceId Id of the resource you want to add. It is suggested to use R.id.* to
+         *                   preserve cross functionality and avoid conflicts.
+         * @param data       The data you want to associate with the resourceId.
+         */
+        public void put(int resourceId, Object data) {
+            if (mData == null) {
+                mData = new SparseArray<Object>();
+            }
+            mData.put(resourceId, data);
+        }
+
+        /**
+         * If scroll is triggered to make a certain item visible, this value will return the
+         * adapter index of that item.
+         * @return Adapter index of the target item or
+         * {@link RecyclerView#NO_POSITION} if there is no target
+         * position.
+         */
+        public int getTargetScrollPosition() {
+            return mTargetPosition;
+        }
+
+        /**
+         * Returns if current scroll has a target position.
+         * @return true if scroll is being triggered to make a certain position visible
+         * @see #getTargetScrollPosition()
+         */
+        public boolean hasTargetScrollPosition() {
+            return mTargetPosition != RecyclerView.NO_POSITION;
+        }
+
+        /**
+         * @return true if the structure of the data set has changed since the last call to
+         *         onLayoutChildren, false otherwise
+         */
+        public boolean didStructureChange() {
+            return mStructureChanged;
+        }
+
+        /**
+         * Returns the total number of items that can be laid out. Note that this number is not
+         * necessarily equal to the number of items in the adapter, so you should always use this
+         * number for your position calculations and never access the adapter directly.
+         * <p>
+         * RecyclerView listens for Adapter's notify events and calculates the effects of adapter
+         * data changes on existing Views. These calculations are used to decide which animations
+         * should be run.
+         * <p>
+         * To support predictive animations, RecyclerView may rewrite or reorder Adapter changes to
+         * present the correct state to LayoutManager in pre-layout pass.
+         * <p>
+         * For example, a newly added item is not included in pre-layout item count because
+         * pre-layout reflects the contents of the adapter before the item is added. Behind the
+         * scenes, RecyclerView offsets {@link Recycler#getViewForPosition(int)} calls such that
+         * LayoutManager does not know about the new item's existence in pre-layout. The item will
+         * be available in second layout pass and will be included in the item count. Similar
+         * adjustments are made for moved and removed items as well.
+         * <p>
+         * You can get the adapter's item count via {@link LayoutManager#getItemCount()} method.
+         *
+         * @return The number of items currently available
+         * @see LayoutManager#getItemCount()
+         */
+        public int getItemCount() {
+            return mInPreLayout
+                    ? (mPreviousLayoutItemCount - mDeletedInvisibleItemCountSincePreviousLayout)
+                    : mItemCount;
+        }
+
+        @Override
+        public String toString() {
+            return "State{"
+                    + "mTargetPosition=" + mTargetPosition
+                    + ", mData=" + mData
+                    + ", mItemCount=" + mItemCount
+                    + ", mPreviousLayoutItemCount=" + mPreviousLayoutItemCount
+                    + ", mDeletedInvisibleItemCountSincePreviousLayout="
+                    + mDeletedInvisibleItemCountSincePreviousLayout
+                    + ", mStructureChanged=" + mStructureChanged
+                    + ", mInPreLayout=" + mInPreLayout
+                    + ", mRunSimpleAnimations=" + mRunSimpleAnimations
+                    + ", mRunPredictiveAnimations=" + mRunPredictiveAnimations
+                    + '}';
+        }
+    }
+
+    /**
+     * This class defines the behavior of fling if the developer wishes to handle it.
+     * <p>
+     * Subclasses of {@link OnFlingListener} can be used to implement custom fling behavior.
+     *
+     * @see #setOnFlingListener(OnFlingListener)
+     */
+    public abstract static class OnFlingListener {
+
+        /**
+         * Override this to handle a fling given the velocities in both x and y directions.
+         * Note that this method will only be called if the associated {@link LayoutManager}
+         * supports scrolling and the fling is not handled by nested scrolls first.
+         *
+         * @param velocityX the fling velocity on the X axis
+         * @param velocityY the fling velocity on the Y axis
+         *
+         * @return true if the fling washandled, false otherwise.
+         */
+        public abstract boolean onFling(int velocityX, int velocityY);
+    }
+
+    /**
+     * Internal listener that manages items after animations finish. This is how items are
+     * retained (not recycled) during animations, but allowed to be recycled afterwards.
+     * It depends on the contract with the ItemAnimator to call the appropriate dispatch*Finished()
+     * method on the animator's listener when it is done animating any item.
+     */
+    private class ItemAnimatorRestoreListener implements ItemAnimator.ItemAnimatorListener {
+
+        ItemAnimatorRestoreListener() {
+        }
+
+        @Override
+        public void onAnimationFinished(ViewHolder item) {
+            item.setIsRecyclable(true);
+            if (item.mShadowedHolder != null && item.mShadowingHolder == null) { // old vh
+                item.mShadowedHolder = null;
+            }
+            // always null this because an OldViewHolder can never become NewViewHolder w/o being
+            // recycled.
+            item.mShadowingHolder = null;
+            if (!item.shouldBeKeptAsChild()) {
+                if (!removeAnimatingView(item.itemView) && item.isTmpDetached()) {
+                    removeDetachedView(item.itemView, false);
+                }
+            }
+        }
+    }
+
+    /**
+     * This class defines the animations that take place on items as changes are made
+     * to the adapter.
+     *
+     * Subclasses of ItemAnimator can be used to implement custom animations for actions on
+     * ViewHolder items. The RecyclerView will manage retaining these items while they
+     * are being animated, but implementors must call {@link #dispatchAnimationFinished(ViewHolder)}
+     * when a ViewHolder's animation is finished. In other words, there must be a matching
+     * {@link #dispatchAnimationFinished(ViewHolder)} call for each
+     * {@link #animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo) animateAppearance()},
+     * {@link #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)
+     * animateChange()}
+     * {@link #animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo) animatePersistence()},
+     * and
+     * {@link #animateDisappearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+     * animateDisappearance()} call.
+     *
+     * <p>By default, RecyclerView uses {@link DefaultItemAnimator}.</p>
+     *
+     * @see #setItemAnimator(ItemAnimator)
+     */
+    @SuppressWarnings("UnusedParameters")
+    public abstract static class ItemAnimator {
+
+        /**
+         * The Item represented by this ViewHolder is updated.
+         * <p>
+         * @see #recordPreLayoutInformation(State, ViewHolder, int, List)
+         */
+        public static final int FLAG_CHANGED = ViewHolder.FLAG_UPDATE;
+
+        /**
+         * The Item represented by this ViewHolder is removed from the adapter.
+         * <p>
+         * @see #recordPreLayoutInformation(State, ViewHolder, int, List)
+         */
+        public static final int FLAG_REMOVED = ViewHolder.FLAG_REMOVED;
+
+        /**
+         * Adapter {@link Adapter#notifyDataSetChanged()} has been called and the content
+         * represented by this ViewHolder is invalid.
+         * <p>
+         * @see #recordPreLayoutInformation(State, ViewHolder, int, List)
+         */
+        public static final int FLAG_INVALIDATED = ViewHolder.FLAG_INVALID;
+
+        /**
+         * The position of the Item represented by this ViewHolder has been changed. This flag is
+         * not bound to {@link Adapter#notifyItemMoved(int, int)}. It might be set in response to
+         * any adapter change that may have a side effect on this item. (e.g. The item before this
+         * one has been removed from the Adapter).
+         * <p>
+         * @see #recordPreLayoutInformation(State, ViewHolder, int, List)
+         */
+        public static final int FLAG_MOVED = ViewHolder.FLAG_MOVED;
+
+        /**
+         * This ViewHolder was not laid out but has been added to the layout in pre-layout state
+         * by the {@link LayoutManager}. This means that the item was already in the Adapter but
+         * invisible and it may become visible in the post layout phase. LayoutManagers may prefer
+         * to add new items in pre-layout to specify their virtual location when they are invisible
+         * (e.g. to specify the item should <i>animate in</i> from below the visible area).
+         * <p>
+         * @see #recordPreLayoutInformation(State, ViewHolder, int, List)
+         */
+        public static final int FLAG_APPEARED_IN_PRE_LAYOUT =
+                ViewHolder.FLAG_APPEARED_IN_PRE_LAYOUT;
+
+        /**
+         * The set of flags that might be passed to
+         * {@link #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         */
+        @IntDef(flag = true, value = {
+                FLAG_CHANGED, FLAG_REMOVED, FLAG_MOVED, FLAG_INVALIDATED,
+                FLAG_APPEARED_IN_PRE_LAYOUT
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface AdapterChanges {}
+        private ItemAnimatorListener mListener = null;
+        private ArrayList<ItemAnimatorFinishedListener> mFinishedListeners =
+                new ArrayList<ItemAnimatorFinishedListener>();
+
+        private long mAddDuration = 120;
+        private long mRemoveDuration = 120;
+        private long mMoveDuration = 250;
+        private long mChangeDuration = 250;
+
+        /**
+         * Gets the current duration for which all move animations will run.
+         *
+         * @return The current move duration
+         */
+        public long getMoveDuration() {
+            return mMoveDuration;
+        }
+
+        /**
+         * Sets the duration for which all move animations will run.
+         *
+         * @param moveDuration The move duration
+         */
+        public void setMoveDuration(long moveDuration) {
+            mMoveDuration = moveDuration;
+        }
+
+        /**
+         * Gets the current duration for which all add animations will run.
+         *
+         * @return The current add duration
+         */
+        public long getAddDuration() {
+            return mAddDuration;
+        }
+
+        /**
+         * Sets the duration for which all add animations will run.
+         *
+         * @param addDuration The add duration
+         */
+        public void setAddDuration(long addDuration) {
+            mAddDuration = addDuration;
+        }
+
+        /**
+         * Gets the current duration for which all remove animations will run.
+         *
+         * @return The current remove duration
+         */
+        public long getRemoveDuration() {
+            return mRemoveDuration;
+        }
+
+        /**
+         * Sets the duration for which all remove animations will run.
+         *
+         * @param removeDuration The remove duration
+         */
+        public void setRemoveDuration(long removeDuration) {
+            mRemoveDuration = removeDuration;
+        }
+
+        /**
+         * Gets the current duration for which all change animations will run.
+         *
+         * @return The current change duration
+         */
+        public long getChangeDuration() {
+            return mChangeDuration;
+        }
+
+        /**
+         * Sets the duration for which all change animations will run.
+         *
+         * @param changeDuration The change duration
+         */
+        public void setChangeDuration(long changeDuration) {
+            mChangeDuration = changeDuration;
+        }
+
+        /**
+         * Internal only:
+         * Sets the listener that must be called when the animator is finished
+         * animating the item (or immediately if no animation happens). This is set
+         * internally and is not intended to be set by external code.
+         *
+         * @param listener The listener that must be called.
+         */
+        void setListener(ItemAnimatorListener listener) {
+            mListener = listener;
+        }
+
+        /**
+         * Called by the RecyclerView before the layout begins. Item animator should record
+         * necessary information about the View before it is potentially rebound, moved or removed.
+         * <p>
+         * The data returned from this method will be passed to the related <code>animate**</code>
+         * methods.
+         * <p>
+         * Note that this method may be called after pre-layout phase if LayoutManager adds new
+         * Views to the layout in pre-layout pass.
+         * <p>
+         * The default implementation returns an {@link ItemHolderInfo} which holds the bounds of
+         * the View and the adapter change flags.
+         *
+         * @param state       The current State of RecyclerView which includes some useful data
+         *                    about the layout that will be calculated.
+         * @param viewHolder  The ViewHolder whose information should be recorded.
+         * @param changeFlags Additional information about what changes happened in the Adapter
+         *                    about the Item represented by this ViewHolder. For instance, if
+         *                    item is deleted from the adapter, {@link #FLAG_REMOVED} will be set.
+         * @param payloads    The payload list that was previously passed to
+         *                    {@link Adapter#notifyItemChanged(int, Object)} or
+         *                    {@link Adapter#notifyItemRangeChanged(int, int, Object)}.
+         *
+         * @return An ItemHolderInfo instance that preserves necessary information about the
+         * ViewHolder. This object will be passed back to related <code>animate**</code> methods
+         * after layout is complete.
+         *
+         * @see #recordPostLayoutInformation(State, ViewHolder)
+         * @see #animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * @see #animateDisappearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * @see #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * @see #animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         */
+        public @NonNull ItemHolderInfo recordPreLayoutInformation(@NonNull State state,
+                @NonNull ViewHolder viewHolder, @AdapterChanges int changeFlags,
+                @NonNull List<Object> payloads) {
+            return obtainHolderInfo().setFrom(viewHolder);
+        }
+
+        /**
+         * Called by the RecyclerView after the layout is complete. Item animator should record
+         * necessary information about the View's final state.
+         * <p>
+         * The data returned from this method will be passed to the related <code>animate**</code>
+         * methods.
+         * <p>
+         * The default implementation returns an {@link ItemHolderInfo} which holds the bounds of
+         * the View.
+         *
+         * @param state      The current State of RecyclerView which includes some useful data about
+         *                   the layout that will be calculated.
+         * @param viewHolder The ViewHolder whose information should be recorded.
+         *
+         * @return An ItemHolderInfo that preserves necessary information about the ViewHolder.
+         * This object will be passed back to related <code>animate**</code> methods when
+         * RecyclerView decides how items should be animated.
+         *
+         * @see #recordPreLayoutInformation(State, ViewHolder, int, List)
+         * @see #animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * @see #animateDisappearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * @see #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * @see #animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         */
+        public @NonNull ItemHolderInfo recordPostLayoutInformation(@NonNull State state,
+                @NonNull ViewHolder viewHolder) {
+            return obtainHolderInfo().setFrom(viewHolder);
+        }
+
+        /**
+         * Called by the RecyclerView when a ViewHolder has disappeared from the layout.
+         * <p>
+         * This means that the View was a child of the LayoutManager when layout started but has
+         * been removed by the LayoutManager. It might have been removed from the adapter or simply
+         * become invisible due to other factors. You can distinguish these two cases by checking
+         * the change flags that were passed to
+         * {@link #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         * <p>
+         * Note that when a ViewHolder both changes and disappears in the same layout pass, the
+         * animation callback method which will be called by the RecyclerView depends on the
+         * ItemAnimator's decision whether to re-use the same ViewHolder or not, and also the
+         * LayoutManager's decision whether to layout the changed version of a disappearing
+         * ViewHolder or not. RecyclerView will call
+         * {@link #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateChange} instead of {@code animateDisappearance} if and only if the ItemAnimator
+         * returns {@code false} from
+         * {@link #canReuseUpdatedViewHolder(ViewHolder) canReuseUpdatedViewHolder} and the
+         * LayoutManager lays out a new disappearing view that holds the updated information.
+         * Built-in LayoutManagers try to avoid laying out updated versions of disappearing views.
+         * <p>
+         * If LayoutManager supports predictive animations, it might provide a target disappear
+         * location for the View by laying it out in that location. When that happens,
+         * RecyclerView will call {@link #recordPostLayoutInformation(State, ViewHolder)} and the
+         * response of that call will be passed to this method as the <code>postLayoutInfo</code>.
+         * <p>
+         * ItemAnimator must call {@link #dispatchAnimationFinished(ViewHolder)} when the animation
+         * is complete (or instantly call {@link #dispatchAnimationFinished(ViewHolder)} if it
+         * decides not to animate the view).
+         *
+         * @param viewHolder    The ViewHolder which should be animated
+         * @param preLayoutInfo The information that was returned from
+         *                      {@link #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         * @param postLayoutInfo The information that was returned from
+         *                       {@link #recordPostLayoutInformation(State, ViewHolder)}. Might be
+         *                       null if the LayoutManager did not layout the item.
+         *
+         * @return true if a later call to {@link #runPendingAnimations()} is requested,
+         * false otherwise.
+         */
+        public abstract boolean animateDisappearance(@NonNull ViewHolder viewHolder,
+                @NonNull ItemHolderInfo preLayoutInfo, @Nullable ItemHolderInfo postLayoutInfo);
+
+        /**
+         * Called by the RecyclerView when a ViewHolder is added to the layout.
+         * <p>
+         * In detail, this means that the ViewHolder was <b>not</b> a child when the layout started
+         * but has  been added by the LayoutManager. It might be newly added to the adapter or
+         * simply become visible due to other factors.
+         * <p>
+         * ItemAnimator must call {@link #dispatchAnimationFinished(ViewHolder)} when the animation
+         * is complete (or instantly call {@link #dispatchAnimationFinished(ViewHolder)} if it
+         * decides not to animate the view).
+         *
+         * @param viewHolder     The ViewHolder which should be animated
+         * @param preLayoutInfo  The information that was returned from
+         *                       {@link #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         *                       Might be null if Item was just added to the adapter or
+         *                       LayoutManager does not support predictive animations or it could
+         *                       not predict that this ViewHolder will become visible.
+         * @param postLayoutInfo The information that was returned from {@link
+         *                       #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         *
+         * @return true if a later call to {@link #runPendingAnimations()} is requested,
+         * false otherwise.
+         */
+        public abstract boolean animateAppearance(@NonNull ViewHolder viewHolder,
+                @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo);
+
+        /**
+         * Called by the RecyclerView when a ViewHolder is present in both before and after the
+         * layout and RecyclerView has not received a {@link Adapter#notifyItemChanged(int)} call
+         * for it or a {@link Adapter#notifyDataSetChanged()} call.
+         * <p>
+         * This ViewHolder still represents the same data that it was representing when the layout
+         * started but its position / size may be changed by the LayoutManager.
+         * <p>
+         * If the Item's layout position didn't change, RecyclerView still calls this method because
+         * it does not track this information (or does not necessarily know that an animation is
+         * not required). Your ItemAnimator should handle this case and if there is nothing to
+         * animate, it should call {@link #dispatchAnimationFinished(ViewHolder)} and return
+         * <code>false</code>.
+         * <p>
+         * ItemAnimator must call {@link #dispatchAnimationFinished(ViewHolder)} when the animation
+         * is complete (or instantly call {@link #dispatchAnimationFinished(ViewHolder)} if it
+         * decides not to animate the view).
+         *
+         * @param viewHolder     The ViewHolder which should be animated
+         * @param preLayoutInfo  The information that was returned from
+         *                       {@link #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         * @param postLayoutInfo The information that was returned from {@link
+         *                       #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         *
+         * @return true if a later call to {@link #runPendingAnimations()} is requested,
+         * false otherwise.
+         */
+        public abstract boolean animatePersistence(@NonNull ViewHolder viewHolder,
+                @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo);
+
+        /**
+         * Called by the RecyclerView when an adapter item is present both before and after the
+         * layout and RecyclerView has received a {@link Adapter#notifyItemChanged(int)} call
+         * for it. This method may also be called when
+         * {@link Adapter#notifyDataSetChanged()} is called and adapter has stable ids so that
+         * RecyclerView could still rebind views to the same ViewHolders. If viewType changes when
+         * {@link Adapter#notifyDataSetChanged()} is called, this method <b>will not</b> be called,
+         * instead, {@link #animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)} will be
+         * called for the new ViewHolder and the old one will be recycled.
+         * <p>
+         * If this method is called due to a {@link Adapter#notifyDataSetChanged()} call, there is
+         * a good possibility that item contents didn't really change but it is rebound from the
+         * adapter. {@link DefaultItemAnimator} will skip animating the View if its location on the
+         * screen didn't change and your animator should handle this case as well and avoid creating
+         * unnecessary animations.
+         * <p>
+         * When an item is updated, ItemAnimator has a chance to ask RecyclerView to keep the
+         * previous presentation of the item as-is and supply a new ViewHolder for the updated
+         * presentation (see: {@link #canReuseUpdatedViewHolder(ViewHolder, List)}.
+         * This is useful if you don't know the contents of the Item and would like
+         * to cross-fade the old and the new one ({@link DefaultItemAnimator} uses this technique).
+         * <p>
+         * When you are writing a custom item animator for your layout, it might be more performant
+         * and elegant to re-use the same ViewHolder and animate the content changes manually.
+         * <p>
+         * When {@link Adapter#notifyItemChanged(int)} is called, the Item's view type may change.
+         * If the Item's view type has changed or ItemAnimator returned <code>false</code> for
+         * this ViewHolder when {@link #canReuseUpdatedViewHolder(ViewHolder, List)} was called, the
+         * <code>oldHolder</code> and <code>newHolder</code> will be different ViewHolder instances
+         * which represent the same Item. In that case, only the new ViewHolder is visible
+         * to the LayoutManager but RecyclerView keeps old ViewHolder attached for animations.
+         * <p>
+         * ItemAnimator must call {@link #dispatchAnimationFinished(ViewHolder)} for each distinct
+         * ViewHolder when their animation is complete
+         * (or instantly call {@link #dispatchAnimationFinished(ViewHolder)} if it decides not to
+         * animate the view).
+         * <p>
+         *  If oldHolder and newHolder are the same instance, you should call
+         * {@link #dispatchAnimationFinished(ViewHolder)} <b>only once</b>.
+         * <p>
+         * Note that when a ViewHolder both changes and disappears in the same layout pass, the
+         * animation callback method which will be called by the RecyclerView depends on the
+         * ItemAnimator's decision whether to re-use the same ViewHolder or not, and also the
+         * LayoutManager's decision whether to layout the changed version of a disappearing
+         * ViewHolder or not. RecyclerView will call
+         * {@code animateChange} instead of
+         * {@link #animateDisappearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateDisappearance} if and only if the ItemAnimator returns {@code false} from
+         * {@link #canReuseUpdatedViewHolder(ViewHolder) canReuseUpdatedViewHolder} and the
+         * LayoutManager lays out a new disappearing view that holds the updated information.
+         * Built-in LayoutManagers try to avoid laying out updated versions of disappearing views.
+         *
+         * @param oldHolder     The ViewHolder before the layout is started, might be the same
+         *                      instance with newHolder.
+         * @param newHolder     The ViewHolder after the layout is finished, might be the same
+         *                      instance with oldHolder.
+         * @param preLayoutInfo  The information that was returned from
+         *                       {@link #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         * @param postLayoutInfo The information that was returned from {@link
+         *                       #recordPreLayoutInformation(State, ViewHolder, int, List)}.
+         *
+         * @return true if a later call to {@link #runPendingAnimations()} is requested,
+         * false otherwise.
+         */
+        public abstract boolean animateChange(@NonNull ViewHolder oldHolder,
+                @NonNull ViewHolder newHolder,
+                @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo);
+
+        @AdapterChanges static int buildAdapterChangeFlagsForAnimations(ViewHolder viewHolder) {
+            int flags = viewHolder.mFlags & (FLAG_INVALIDATED | FLAG_REMOVED | FLAG_CHANGED);
+            if (viewHolder.isInvalid()) {
+                return FLAG_INVALIDATED;
+            }
+            if ((flags & FLAG_INVALIDATED) == 0) {
+                final int oldPos = viewHolder.getOldPosition();
+                final int pos = viewHolder.getAdapterPosition();
+                if (oldPos != NO_POSITION && pos != NO_POSITION && oldPos != pos) {
+                    flags |= FLAG_MOVED;
+                }
+            }
+            return flags;
+        }
+
+        /**
+         * Called when there are pending animations waiting to be started. This state
+         * is governed by the return values from
+         * {@link #animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateAppearance()},
+         * {@link #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateChange()}
+         * {@link #animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animatePersistence()}, and
+         * {@link #animateDisappearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateDisappearance()}, which inform the RecyclerView that the ItemAnimator wants to be
+         * called later to start the associated animations. runPendingAnimations() will be scheduled
+         * to be run on the next frame.
+         */
+        public abstract void runPendingAnimations();
+
+        /**
+         * Method called when an animation on a view should be ended immediately.
+         * This could happen when other events, like scrolling, occur, so that
+         * animating views can be quickly put into their proper end locations.
+         * Implementations should ensure that any animations running on the item
+         * are canceled and affected properties are set to their end values.
+         * Also, {@link #dispatchAnimationFinished(ViewHolder)} should be called for each finished
+         * animation since the animations are effectively done when this method is called.
+         *
+         * @param item The item for which an animation should be stopped.
+         */
+        public abstract void endAnimation(ViewHolder item);
+
+        /**
+         * Method called when all item animations should be ended immediately.
+         * This could happen when other events, like scrolling, occur, so that
+         * animating views can be quickly put into their proper end locations.
+         * Implementations should ensure that any animations running on any items
+         * are canceled and affected properties are set to their end values.
+         * Also, {@link #dispatchAnimationFinished(ViewHolder)} should be called for each finished
+         * animation since the animations are effectively done when this method is called.
+         */
+        public abstract void endAnimations();
+
+        /**
+         * Method which returns whether there are any item animations currently running.
+         * This method can be used to determine whether to delay other actions until
+         * animations end.
+         *
+         * @return true if there are any item animations currently running, false otherwise.
+         */
+        public abstract boolean isRunning();
+
+        /**
+         * Method to be called by subclasses when an animation is finished.
+         * <p>
+         * For each call RecyclerView makes to
+         * {@link #animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateAppearance()},
+         * {@link #animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animatePersistence()}, or
+         * {@link #animateDisappearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateDisappearance()}, there
+         * should
+         * be a matching {@link #dispatchAnimationFinished(ViewHolder)} call by the subclass.
+         * <p>
+         * For {@link #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateChange()}, subclass should call this method for both the <code>oldHolder</code>
+         * and <code>newHolder</code>  (if they are not the same instance).
+         *
+         * @param viewHolder The ViewHolder whose animation is finished.
+         * @see #onAnimationFinished(ViewHolder)
+         */
+        public final void dispatchAnimationFinished(ViewHolder viewHolder) {
+            onAnimationFinished(viewHolder);
+            if (mListener != null) {
+                mListener.onAnimationFinished(viewHolder);
+            }
+        }
+
+        /**
+         * Called after {@link #dispatchAnimationFinished(ViewHolder)} is called by the
+         * ItemAnimator.
+         *
+         * @param viewHolder The ViewHolder whose animation is finished. There might still be other
+         *                   animations running on this ViewHolder.
+         * @see #dispatchAnimationFinished(ViewHolder)
+         */
+        public void onAnimationFinished(ViewHolder viewHolder) {
+        }
+
+        /**
+         * Method to be called by subclasses when an animation is started.
+         * <p>
+         * For each call RecyclerView makes to
+         * {@link #animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateAppearance()},
+         * {@link #animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animatePersistence()}, or
+         * {@link #animateDisappearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateDisappearance()}, there should be a matching
+         * {@link #dispatchAnimationStarted(ViewHolder)} call by the subclass.
+         * <p>
+         * For {@link #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)
+         * animateChange()}, subclass should call this method for both the <code>oldHolder</code>
+         * and <code>newHolder</code> (if they are not the same instance).
+         * <p>
+         * If your ItemAnimator decides not to animate a ViewHolder, it should call
+         * {@link #dispatchAnimationFinished(ViewHolder)} <b>without</b> calling
+         * {@link #dispatchAnimationStarted(ViewHolder)}.
+         *
+         * @param viewHolder The ViewHolder whose animation is starting.
+         * @see #onAnimationStarted(ViewHolder)
+         */
+        public final void dispatchAnimationStarted(ViewHolder viewHolder) {
+            onAnimationStarted(viewHolder);
+        }
+
+        /**
+         * Called when a new animation is started on the given ViewHolder.
+         *
+         * @param viewHolder The ViewHolder which started animating. Note that the ViewHolder
+         *                   might already be animating and this might be another animation.
+         * @see #dispatchAnimationStarted(ViewHolder)
+         */
+        public void onAnimationStarted(ViewHolder viewHolder) {
+
+        }
+
+        /**
+         * Like {@link #isRunning()}, this method returns whether there are any item
+         * animations currently running. Additionally, the listener passed in will be called
+         * when there are no item animations running, either immediately (before the method
+         * returns) if no animations are currently running, or when the currently running
+         * animations are {@link #dispatchAnimationsFinished() finished}.
+         *
+         * <p>Note that the listener is transient - it is either called immediately and not
+         * stored at all, or stored only until it is called when running animations
+         * are finished sometime later.</p>
+         *
+         * @param listener A listener to be called immediately if no animations are running
+         * or later when currently-running animations have finished. A null listener is
+         * equivalent to calling {@link #isRunning()}.
+         * @return true if there are any item animations currently running, false otherwise.
+         */
+        public final boolean isRunning(ItemAnimatorFinishedListener listener) {
+            boolean running = isRunning();
+            if (listener != null) {
+                if (!running) {
+                    listener.onAnimationsFinished();
+                } else {
+                    mFinishedListeners.add(listener);
+                }
+            }
+            return running;
+        }
+
+        /**
+         * When an item is changed, ItemAnimator can decide whether it wants to re-use
+         * the same ViewHolder for animations or RecyclerView should create a copy of the
+         * item and ItemAnimator will use both to run the animation (e.g. cross-fade).
+         * <p>
+         * Note that this method will only be called if the {@link ViewHolder} still has the same
+         * type ({@link Adapter#getItemViewType(int)}). Otherwise, ItemAnimator will always receive
+         * both {@link ViewHolder}s in the
+         * {@link #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)} method.
+         * <p>
+         * If your application is using change payloads, you can override
+         * {@link #canReuseUpdatedViewHolder(ViewHolder, List)} to decide based on payloads.
+         *
+         * @param viewHolder The ViewHolder which represents the changed item's old content.
+         *
+         * @return True if RecyclerView should just rebind to the same ViewHolder or false if
+         *         RecyclerView should create a new ViewHolder and pass this ViewHolder to the
+         *         ItemAnimator to animate. Default implementation returns <code>true</code>.
+         *
+         * @see #canReuseUpdatedViewHolder(ViewHolder, List)
+         */
+        public boolean canReuseUpdatedViewHolder(@NonNull ViewHolder viewHolder) {
+            return true;
+        }
+
+        /**
+         * When an item is changed, ItemAnimator can decide whether it wants to re-use
+         * the same ViewHolder for animations or RecyclerView should create a copy of the
+         * item and ItemAnimator will use both to run the animation (e.g. cross-fade).
+         * <p>
+         * Note that this method will only be called if the {@link ViewHolder} still has the same
+         * type ({@link Adapter#getItemViewType(int)}). Otherwise, ItemAnimator will always receive
+         * both {@link ViewHolder}s in the
+         * {@link #animateChange(ViewHolder, ViewHolder, ItemHolderInfo, ItemHolderInfo)} method.
+         *
+         * @param viewHolder The ViewHolder which represents the changed item's old content.
+         * @param payloads A non-null list of merged payloads that were sent with change
+         *                 notifications. Can be empty if the adapter is invalidated via
+         *                 {@link RecyclerView.Adapter#notifyDataSetChanged()}. The same list of
+         *                 payloads will be passed into
+         *                 {@link RecyclerView.Adapter#onBindViewHolder(ViewHolder, int, List)}
+         *                 method <b>if</b> this method returns <code>true</code>.
+         *
+         * @return True if RecyclerView should just rebind to the same ViewHolder or false if
+         *         RecyclerView should create a new ViewHolder and pass this ViewHolder to the
+         *         ItemAnimator to animate. Default implementation calls
+         *         {@link #canReuseUpdatedViewHolder(ViewHolder)}.
+         *
+         * @see #canReuseUpdatedViewHolder(ViewHolder)
+         */
+        public boolean canReuseUpdatedViewHolder(@NonNull ViewHolder viewHolder,
+                @NonNull List<Object> payloads) {
+            return canReuseUpdatedViewHolder(viewHolder);
+        }
+
+        /**
+         * This method should be called by ItemAnimator implementations to notify
+         * any listeners that all pending and active item animations are finished.
+         */
+        public final void dispatchAnimationsFinished() {
+            final int count = mFinishedListeners.size();
+            for (int i = 0; i < count; ++i) {
+                mFinishedListeners.get(i).onAnimationsFinished();
+            }
+            mFinishedListeners.clear();
+        }
+
+        /**
+         * Returns a new {@link ItemHolderInfo} which will be used to store information about the
+         * ViewHolder. This information will later be passed into <code>animate**</code> methods.
+         * <p>
+         * You can override this method if you want to extend {@link ItemHolderInfo} and provide
+         * your own instances.
+         *
+         * @return A new {@link ItemHolderInfo}.
+         */
+        public ItemHolderInfo obtainHolderInfo() {
+            return new ItemHolderInfo();
+        }
+
+        /**
+         * The interface to be implemented by listeners to animation events from this
+         * ItemAnimator. This is used internally and is not intended for developers to
+         * create directly.
+         */
+        interface ItemAnimatorListener {
+            void onAnimationFinished(ViewHolder item);
+        }
+
+        /**
+         * This interface is used to inform listeners when all pending or running animations
+         * in an ItemAnimator are finished. This can be used, for example, to delay an action
+         * in a data set until currently-running animations are complete.
+         *
+         * @see #isRunning(ItemAnimatorFinishedListener)
+         */
+        public interface ItemAnimatorFinishedListener {
+            /**
+             * Notifies when all pending or running animations in an ItemAnimator are finished.
+             */
+            void onAnimationsFinished();
+        }
+
+        /**
+         * A simple data structure that holds information about an item's bounds.
+         * This information is used in calculating item animations. Default implementation of
+         * {@link #recordPreLayoutInformation(RecyclerView.State, ViewHolder, int, List)} and
+         * {@link #recordPostLayoutInformation(RecyclerView.State, ViewHolder)} returns this data
+         * structure. You can extend this class if you would like to keep more information about
+         * the Views.
+         * <p>
+         * If you want to provide your own implementation but still use `super` methods to record
+         * basic information, you can override {@link #obtainHolderInfo()} to provide your own
+         * instances.
+         */
+        public static class ItemHolderInfo {
+
+            /**
+             * The left edge of the View (excluding decorations)
+             */
+            public int left;
+
+            /**
+             * The top edge of the View (excluding decorations)
+             */
+            public int top;
+
+            /**
+             * The right edge of the View (excluding decorations)
+             */
+            public int right;
+
+            /**
+             * The bottom edge of the View (excluding decorations)
+             */
+            public int bottom;
+
+            /**
+             * The change flags that were passed to
+             * {@link #recordPreLayoutInformation(RecyclerView.State, ViewHolder, int, List)}.
+             */
+            @AdapterChanges
+            public int changeFlags;
+
+            public ItemHolderInfo() {
+            }
+
+            /**
+             * Sets the {@link #left}, {@link #top}, {@link #right} and {@link #bottom} values from
+             * the given ViewHolder. Clears all {@link #changeFlags}.
+             *
+             * @param holder The ViewHolder whose bounds should be copied.
+             * @return This {@link ItemHolderInfo}
+             */
+            public ItemHolderInfo setFrom(RecyclerView.ViewHolder holder) {
+                return setFrom(holder, 0);
+            }
+
+            /**
+             * Sets the {@link #left}, {@link #top}, {@link #right} and {@link #bottom} values from
+             * the given ViewHolder and sets the {@link #changeFlags} to the given flags parameter.
+             *
+             * @param holder The ViewHolder whose bounds should be copied.
+             * @param flags  The adapter change flags that were passed into
+             *               {@link #recordPreLayoutInformation(RecyclerView.State, ViewHolder, int,
+             *               List)}.
+             * @return This {@link ItemHolderInfo}
+             */
+            public ItemHolderInfo setFrom(RecyclerView.ViewHolder holder,
+                    @AdapterChanges int flags) {
+                final View view = holder.itemView;
+                this.left = view.getLeft();
+                this.top = view.getTop();
+                this.right = view.getRight();
+                this.bottom = view.getBottom();
+                return this;
+            }
+        }
+    }
+
+    @Override
+    protected int getChildDrawingOrder(int childCount, int i) {
+        if (mChildDrawingOrderCallback == null) {
+            return super.getChildDrawingOrder(childCount, i);
+        } else {
+            return mChildDrawingOrderCallback.onGetChildDrawingOrder(childCount, i);
+        }
+    }
+
+    /**
+     * A callback interface that can be used to alter the drawing order of RecyclerView children.
+     * <p>
+     * It works using the {@link ViewGroup#getChildDrawingOrder(int, int)} method, so any case
+     * that applies to that method also applies to this callback. For example, changing the drawing
+     * order of two views will not have any effect if their elevation values are different since
+     * elevation overrides the result of this callback.
+     */
+    public interface ChildDrawingOrderCallback {
+        /**
+         * Returns the index of the child to draw for this iteration. Override this
+         * if you want to change the drawing order of children. By default, it
+         * returns i.
+         *
+         * @param i The current iteration.
+         * @return The index of the child to draw this iteration.
+         *
+         * @see RecyclerView#setChildDrawingOrderCallback(RecyclerView.ChildDrawingOrderCallback)
+         */
+        int onGetChildDrawingOrder(int childCount, int i);
+    }
+}
diff --git a/core/java/com/android/internal/widget/RecyclerViewAccessibilityDelegate.java b/core/java/com/android/internal/widget/RecyclerViewAccessibilityDelegate.java
new file mode 100644
index 0000000..282da64
--- /dev/null
+++ b/core/java/com/android/internal/widget/RecyclerViewAccessibilityDelegate.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.AccessibilityDelegate;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+
+/**
+ * The AccessibilityDelegate used by RecyclerView.
+ * <p>
+ * This class handles basic accessibility actions and delegates them to LayoutManager.
+ */
+public class RecyclerViewAccessibilityDelegate extends AccessibilityDelegate {
+    final RecyclerView mRecyclerView;
+
+
+    public RecyclerViewAccessibilityDelegate(RecyclerView recyclerView) {
+        mRecyclerView = recyclerView;
+    }
+
+    boolean shouldIgnore() {
+        return mRecyclerView.hasPendingAdapterUpdates();
+    }
+
+    @Override
+    public boolean performAccessibilityAction(View host, int action, Bundle args) {
+        if (super.performAccessibilityAction(host, action, args)) {
+            return true;
+        }
+        if (!shouldIgnore() && mRecyclerView.getLayoutManager() != null) {
+            return mRecyclerView.getLayoutManager().performAccessibilityAction(action, args);
+        }
+
+        return false;
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(host, info);
+        info.setClassName(RecyclerView.class.getName());
+        if (!shouldIgnore() && mRecyclerView.getLayoutManager() != null) {
+            mRecyclerView.getLayoutManager().onInitializeAccessibilityNodeInfo(info);
+        }
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(host, event);
+        event.setClassName(RecyclerView.class.getName());
+        if (host instanceof RecyclerView && !shouldIgnore()) {
+            RecyclerView rv = (RecyclerView) host;
+            if (rv.getLayoutManager() != null) {
+                rv.getLayoutManager().onInitializeAccessibilityEvent(event);
+            }
+        }
+    }
+
+    /**
+     * Gets the AccessibilityDelegate for an individual item in the RecyclerView.
+     * A basic item delegate is provided by default, but you can override this
+     * method to provide a custom per-item delegate.
+     */
+    public AccessibilityDelegate getItemDelegate() {
+        return mItemDelegate;
+    }
+
+    final AccessibilityDelegate mItemDelegate = new AccessibilityDelegate() {
+        @Override
+        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+            super.onInitializeAccessibilityNodeInfo(host, info);
+            if (!shouldIgnore() && mRecyclerView.getLayoutManager() != null) {
+                mRecyclerView.getLayoutManager()
+                        .onInitializeAccessibilityNodeInfoForItem(host, info);
+            }
+        }
+
+        @Override
+        public boolean performAccessibilityAction(View host, int action, Bundle args) {
+            if (super.performAccessibilityAction(host, action, args)) {
+                return true;
+            }
+            if (!shouldIgnore() && mRecyclerView.getLayoutManager() != null) {
+                return mRecyclerView.getLayoutManager()
+                        .performAccessibilityActionForItem(host, action, args);
+            }
+            return false;
+        }
+    };
+}
+
diff --git a/core/java/com/android/internal/widget/ScrollbarHelper.java b/core/java/com/android/internal/widget/ScrollbarHelper.java
new file mode 100644
index 0000000..ae34e4c
--- /dev/null
+++ b/core/java/com/android/internal/widget/ScrollbarHelper.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.view.View;
+
+/**
+ * A helper class to do scroll offset calculations.
+ */
+class ScrollbarHelper {
+
+    /**
+     * @param startChild View closest to start of the list. (top or left)
+     * @param endChild   View closest to end of the list (bottom or right)
+     */
+    static int computeScrollOffset(RecyclerView.State state, OrientationHelper orientation,
+            View startChild, View endChild, RecyclerView.LayoutManager lm,
+            boolean smoothScrollbarEnabled, boolean reverseLayout) {
+        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null
+                || endChild == null) {
+            return 0;
+        }
+        final int minPosition = Math.min(lm.getPosition(startChild),
+                lm.getPosition(endChild));
+        final int maxPosition = Math.max(lm.getPosition(startChild),
+                lm.getPosition(endChild));
+        final int itemsBefore = reverseLayout
+                ? Math.max(0, state.getItemCount() - maxPosition - 1)
+                : Math.max(0, minPosition);
+        if (!smoothScrollbarEnabled) {
+            return itemsBefore;
+        }
+        final int laidOutArea = Math.abs(orientation.getDecoratedEnd(endChild)
+                - orientation.getDecoratedStart(startChild));
+        final int itemRange = Math.abs(lm.getPosition(startChild)
+                - lm.getPosition(endChild)) + 1;
+        final float avgSizePerRow = (float) laidOutArea / itemRange;
+
+        return Math.round(itemsBefore * avgSizePerRow + (orientation.getStartAfterPadding()
+                - orientation.getDecoratedStart(startChild)));
+    }
+
+    /**
+     * @param startChild View closest to start of the list. (top or left)
+     * @param endChild   View closest to end of the list (bottom or right)
+     */
+    static int computeScrollExtent(RecyclerView.State state, OrientationHelper orientation,
+            View startChild, View endChild, RecyclerView.LayoutManager lm,
+            boolean smoothScrollbarEnabled) {
+        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null
+                || endChild == null) {
+            return 0;
+        }
+        if (!smoothScrollbarEnabled) {
+            return Math.abs(lm.getPosition(startChild) - lm.getPosition(endChild)) + 1;
+        }
+        final int extend = orientation.getDecoratedEnd(endChild)
+                - orientation.getDecoratedStart(startChild);
+        return Math.min(orientation.getTotalSpace(), extend);
+    }
+
+    /**
+     * @param startChild View closest to start of the list. (top or left)
+     * @param endChild   View closest to end of the list (bottom or right)
+     */
+    static int computeScrollRange(RecyclerView.State state, OrientationHelper orientation,
+            View startChild, View endChild, RecyclerView.LayoutManager lm,
+            boolean smoothScrollbarEnabled) {
+        if (lm.getChildCount() == 0 || state.getItemCount() == 0 || startChild == null
+                || endChild == null) {
+            return 0;
+        }
+        if (!smoothScrollbarEnabled) {
+            return state.getItemCount();
+        }
+        // smooth scrollbar enabled. try to estimate better.
+        final int laidOutArea = orientation.getDecoratedEnd(endChild)
+                - orientation.getDecoratedStart(startChild);
+        final int laidOutRange = Math.abs(lm.getPosition(startChild)
+                - lm.getPosition(endChild))
+                + 1;
+        // estimate a size for full list.
+        return (int) ((float) laidOutArea / laidOutRange * state.getItemCount());
+    }
+}
diff --git a/core/java/com/android/internal/widget/ScrollingView.java b/core/java/com/android/internal/widget/ScrollingView.java
new file mode 100644
index 0000000..a0205e7
--- /dev/null
+++ b/core/java/com/android/internal/widget/ScrollingView.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+/**
+ * An interface that can be implemented by Views to provide scroll related APIs.
+ */
+public interface ScrollingView {
+    /**
+     * <p>Compute the horizontal range that the horizontal scrollbar
+     * represents.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the
+     * units used by {@link #computeHorizontalScrollExtent()} and
+     * {@link #computeHorizontalScrollOffset()}.</p>
+     *
+     * <p>The default range is the drawing width of this view.</p>
+     *
+     * @return the total horizontal range represented by the horizontal
+     *         scrollbar
+     *
+     * @see #computeHorizontalScrollExtent()
+     * @see #computeHorizontalScrollOffset()
+     * @see android.widget.ScrollBarDrawable
+     */
+    int computeHorizontalScrollRange();
+
+    /**
+     * <p>Compute the horizontal offset of the horizontal scrollbar's thumb
+     * within the horizontal range. This value is used to compute the position
+     * of the thumb within the scrollbar's track.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the
+     * units used by {@link #computeHorizontalScrollRange()} and
+     * {@link #computeHorizontalScrollExtent()}.</p>
+     *
+     * <p>The default offset is the scroll offset of this view.</p>
+     *
+     * @return the horizontal offset of the scrollbar's thumb
+     *
+     * @see #computeHorizontalScrollRange()
+     * @see #computeHorizontalScrollExtent()
+     * @see android.widget.ScrollBarDrawable
+     */
+    int computeHorizontalScrollOffset();
+
+    /**
+     * <p>Compute the horizontal extent of the horizontal scrollbar's thumb
+     * within the horizontal range. This value is used to compute the length
+     * of the thumb within the scrollbar's track.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the
+     * units used by {@link #computeHorizontalScrollRange()} and
+     * {@link #computeHorizontalScrollOffset()}.</p>
+     *
+     * <p>The default extent is the drawing width of this view.</p>
+     *
+     * @return the horizontal extent of the scrollbar's thumb
+     *
+     * @see #computeHorizontalScrollRange()
+     * @see #computeHorizontalScrollOffset()
+     * @see android.widget.ScrollBarDrawable
+     */
+    int computeHorizontalScrollExtent();
+
+    /**
+     * <p>Compute the vertical range that the vertical scrollbar represents.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the
+     * units used by {@link #computeVerticalScrollExtent()} and
+     * {@link #computeVerticalScrollOffset()}.</p>
+     *
+     * @return the total vertical range represented by the vertical scrollbar
+     *
+     * <p>The default range is the drawing height of this view.</p>
+     *
+     * @see #computeVerticalScrollExtent()
+     * @see #computeVerticalScrollOffset()
+     * @see android.widget.ScrollBarDrawable
+     */
+    int computeVerticalScrollRange();
+
+    /**
+     * <p>Compute the vertical offset of the vertical scrollbar's thumb
+     * within the horizontal range. This value is used to compute the position
+     * of the thumb within the scrollbar's track.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the
+     * units used by {@link #computeVerticalScrollRange()} and
+     * {@link #computeVerticalScrollExtent()}.</p>
+     *
+     * <p>The default offset is the scroll offset of this view.</p>
+     *
+     * @return the vertical offset of the scrollbar's thumb
+     *
+     * @see #computeVerticalScrollRange()
+     * @see #computeVerticalScrollExtent()
+     * @see android.widget.ScrollBarDrawable
+     */
+    int computeVerticalScrollOffset();
+
+    /**
+     * <p>Compute the vertical extent of the vertical scrollbar's thumb
+     * within the vertical range. This value is used to compute the length
+     * of the thumb within the scrollbar's track.</p>
+     *
+     * <p>The range is expressed in arbitrary units that must be the same as the
+     * units used by {@link #computeVerticalScrollRange()} and
+     * {@link #computeVerticalScrollOffset()}.</p>
+     *
+     * <p>The default extent is the drawing height of this view.</p>
+     *
+     * @return the vertical extent of the scrollbar's thumb
+     *
+     * @see #computeVerticalScrollRange()
+     * @see #computeVerticalScrollOffset()
+     * @see android.widget.ScrollBarDrawable
+     */
+    int computeVerticalScrollExtent();
+}
diff --git a/core/java/com/android/internal/widget/SimpleItemAnimator.java b/core/java/com/android/internal/widget/SimpleItemAnimator.java
new file mode 100644
index 0000000..f4cc753
--- /dev/null
+++ b/core/java/com/android/internal/widget/SimpleItemAnimator.java
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+import android.view.View;
+
+import com.android.internal.widget.RecyclerView.Adapter;
+import com.android.internal.widget.RecyclerView.ViewHolder;
+
+/**
+ * A wrapper class for ItemAnimator that records View bounds and decides whether it should run
+ * move, change, add or remove animations. This class also replicates the original ItemAnimator
+ * API.
+ * <p>
+ * It uses {@link ItemHolderInfo} to track the bounds information of the Views. If you would like
+ * to
+ * extend this class, you can override {@link #obtainHolderInfo()} method to provide your own info
+ * class that extends {@link ItemHolderInfo}.
+ */
+public abstract class SimpleItemAnimator extends RecyclerView.ItemAnimator {
+
+    private static final boolean DEBUG = false;
+
+    private static final String TAG = "SimpleItemAnimator";
+
+    boolean mSupportsChangeAnimations = true;
+
+    /**
+     * Returns whether this ItemAnimator supports animations of change events.
+     *
+     * @return true if change animations are supported, false otherwise
+     */
+    @SuppressWarnings("unused")
+    public boolean getSupportsChangeAnimations() {
+        return mSupportsChangeAnimations;
+    }
+
+    /**
+     * Sets whether this ItemAnimator supports animations of item change events.
+     * If you set this property to false, actions on the data set which change the
+     * contents of items will not be animated. What those animations do is left
+     * up to the discretion of the ItemAnimator subclass, in its
+     * {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)} implementation.
+     * The value of this property is true by default.
+     *
+     * @param supportsChangeAnimations true if change animations are supported by
+     *                                 this ItemAnimator, false otherwise. If the property is false,
+     *                                 the ItemAnimator
+     *                                 will not receive a call to
+     *                                 {@link #animateChange(ViewHolder, ViewHolder, int, int, int,
+     *                                 int)} when changes occur.
+     * @see Adapter#notifyItemChanged(int)
+     * @see Adapter#notifyItemRangeChanged(int, int)
+     */
+    public void setSupportsChangeAnimations(boolean supportsChangeAnimations) {
+        mSupportsChangeAnimations = supportsChangeAnimations;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @return True if change animations are not supported or the ViewHolder is invalid,
+     * false otherwise.
+     *
+     * @see #setSupportsChangeAnimations(boolean)
+     */
+    @Override
+    public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
+        return !mSupportsChangeAnimations || viewHolder.isInvalid();
+    }
+
+    @Override
+    public boolean animateDisappearance(@NonNull ViewHolder viewHolder,
+            @NonNull ItemHolderInfo preLayoutInfo, @Nullable ItemHolderInfo postLayoutInfo) {
+        int oldLeft = preLayoutInfo.left;
+        int oldTop = preLayoutInfo.top;
+        View disappearingItemView = viewHolder.itemView;
+        int newLeft = postLayoutInfo == null ? disappearingItemView.getLeft() : postLayoutInfo.left;
+        int newTop = postLayoutInfo == null ? disappearingItemView.getTop() : postLayoutInfo.top;
+        if (!viewHolder.isRemoved() && (oldLeft != newLeft || oldTop != newTop)) {
+            disappearingItemView.layout(newLeft, newTop,
+                    newLeft + disappearingItemView.getWidth(),
+                    newTop + disappearingItemView.getHeight());
+            if (DEBUG) {
+                Log.d(TAG, "DISAPPEARING: " + viewHolder + " with view " + disappearingItemView);
+            }
+            return animateMove(viewHolder, oldLeft, oldTop, newLeft, newTop);
+        } else {
+            if (DEBUG) {
+                Log.d(TAG, "REMOVED: " + viewHolder + " with view " + disappearingItemView);
+            }
+            return animateRemove(viewHolder);
+        }
+    }
+
+    @Override
+    public boolean animateAppearance(@NonNull ViewHolder viewHolder,
+            @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
+        if (preLayoutInfo != null && (preLayoutInfo.left != postLayoutInfo.left
+                || preLayoutInfo.top != postLayoutInfo.top)) {
+            // slide items in if before/after locations differ
+            if (DEBUG) {
+                Log.d(TAG, "APPEARING: " + viewHolder + " with view " + viewHolder);
+            }
+            return animateMove(viewHolder, preLayoutInfo.left, preLayoutInfo.top,
+                    postLayoutInfo.left, postLayoutInfo.top);
+        } else {
+            if (DEBUG) {
+                Log.d(TAG, "ADDED: " + viewHolder + " with view " + viewHolder);
+            }
+            return animateAdd(viewHolder);
+        }
+    }
+
+    @Override
+    public boolean animatePersistence(@NonNull ViewHolder viewHolder,
+            @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
+        if (preInfo.left != postInfo.left || preInfo.top != postInfo.top) {
+            if (DEBUG) {
+                Log.d(TAG, "PERSISTENT: " + viewHolder
+                        + " with view " + viewHolder.itemView);
+            }
+            return animateMove(viewHolder,
+                    preInfo.left, preInfo.top, postInfo.left, postInfo.top);
+        }
+        dispatchMoveFinished(viewHolder);
+        return false;
+    }
+
+    @Override
+    public boolean animateChange(@NonNull ViewHolder oldHolder, @NonNull ViewHolder newHolder,
+            @NonNull ItemHolderInfo preInfo, @NonNull ItemHolderInfo postInfo) {
+        if (DEBUG) {
+            Log.d(TAG, "CHANGED: " + oldHolder + " with view " + oldHolder.itemView);
+        }
+        final int fromLeft = preInfo.left;
+        final int fromTop = preInfo.top;
+        final int toLeft, toTop;
+        if (newHolder.shouldIgnore()) {
+            toLeft = preInfo.left;
+            toTop = preInfo.top;
+        } else {
+            toLeft = postInfo.left;
+            toTop = postInfo.top;
+        }
+        return animateChange(oldHolder, newHolder, fromLeft, fromTop, toLeft, toTop);
+    }
+
+    /**
+     * Called when an item is removed from the RecyclerView. Implementors can choose
+     * whether and how to animate that change, but must always call
+     * {@link #dispatchRemoveFinished(ViewHolder)} when done, either
+     * immediately (if no animation will occur) or after the animation actually finishes.
+     * The return value indicates whether an animation has been set up and whether the
+     * ItemAnimator's {@link #runPendingAnimations()} method should be called at the
+     * next opportunity. This mechanism allows ItemAnimator to set up individual animations
+     * as separate calls to {@link #animateAdd(ViewHolder) animateAdd()},
+     * {@link #animateMove(ViewHolder, int, int, int, int) animateMove()},
+     * {@link #animateRemove(ViewHolder) animateRemove()}, and
+     * {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)} come in one by one,
+     * then start the animations together in the later call to {@link #runPendingAnimations()}.
+     *
+     * <p>This method may also be called for disappearing items which continue to exist in the
+     * RecyclerView, but for which the system does not have enough information to animate
+     * them out of view. In that case, the default animation for removing items is run
+     * on those items as well.</p>
+     *
+     * @param holder The item that is being removed.
+     * @return true if a later call to {@link #runPendingAnimations()} is requested,
+     * false otherwise.
+     */
+    public abstract boolean animateRemove(ViewHolder holder);
+
+    /**
+     * Called when an item is added to the RecyclerView. Implementors can choose
+     * whether and how to animate that change, but must always call
+     * {@link #dispatchAddFinished(ViewHolder)} when done, either
+     * immediately (if no animation will occur) or after the animation actually finishes.
+     * The return value indicates whether an animation has been set up and whether the
+     * ItemAnimator's {@link #runPendingAnimations()} method should be called at the
+     * next opportunity. This mechanism allows ItemAnimator to set up individual animations
+     * as separate calls to {@link #animateAdd(ViewHolder) animateAdd()},
+     * {@link #animateMove(ViewHolder, int, int, int, int) animateMove()},
+     * {@link #animateRemove(ViewHolder) animateRemove()}, and
+     * {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)} come in one by one,
+     * then start the animations together in the later call to {@link #runPendingAnimations()}.
+     *
+     * <p>This method may also be called for appearing items which were already in the
+     * RecyclerView, but for which the system does not have enough information to animate
+     * them into view. In that case, the default animation for adding items is run
+     * on those items as well.</p>
+     *
+     * @param holder The item that is being added.
+     * @return true if a later call to {@link #runPendingAnimations()} is requested,
+     * false otherwise.
+     */
+    public abstract boolean animateAdd(ViewHolder holder);
+
+    /**
+     * Called when an item is moved in the RecyclerView. Implementors can choose
+     * whether and how to animate that change, but must always call
+     * {@link #dispatchMoveFinished(ViewHolder)} when done, either
+     * immediately (if no animation will occur) or after the animation actually finishes.
+     * The return value indicates whether an animation has been set up and whether the
+     * ItemAnimator's {@link #runPendingAnimations()} method should be called at the
+     * next opportunity. This mechanism allows ItemAnimator to set up individual animations
+     * as separate calls to {@link #animateAdd(ViewHolder) animateAdd()},
+     * {@link #animateMove(ViewHolder, int, int, int, int) animateMove()},
+     * {@link #animateRemove(ViewHolder) animateRemove()}, and
+     * {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)} come in one by one,
+     * then start the animations together in the later call to {@link #runPendingAnimations()}.
+     *
+     * @param holder The item that is being moved.
+     * @return true if a later call to {@link #runPendingAnimations()} is requested,
+     * false otherwise.
+     */
+    public abstract boolean animateMove(ViewHolder holder, int fromX, int fromY,
+            int toX, int toY);
+
+    /**
+     * Called when an item is changed in the RecyclerView, as indicated by a call to
+     * {@link Adapter#notifyItemChanged(int)} or
+     * {@link Adapter#notifyItemRangeChanged(int, int)}.
+     * <p>
+     * Implementers can choose whether and how to animate changes, but must always call
+     * {@link #dispatchChangeFinished(ViewHolder, boolean)} for each non-null distinct ViewHolder,
+     * either immediately (if no animation will occur) or after the animation actually finishes.
+     * If the {@code oldHolder} is the same ViewHolder as the {@code newHolder}, you must call
+     * {@link #dispatchChangeFinished(ViewHolder, boolean)} once and only once. In that case, the
+     * second parameter of {@code dispatchChangeFinished} is ignored.
+     * <p>
+     * The return value indicates whether an animation has been set up and whether the
+     * ItemAnimator's {@link #runPendingAnimations()} method should be called at the
+     * next opportunity. This mechanism allows ItemAnimator to set up individual animations
+     * as separate calls to {@link #animateAdd(ViewHolder) animateAdd()},
+     * {@link #animateMove(ViewHolder, int, int, int, int) animateMove()},
+     * {@link #animateRemove(ViewHolder) animateRemove()}, and
+     * {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)} come in one by one,
+     * then start the animations together in the later call to {@link #runPendingAnimations()}.
+     *
+     * @param oldHolder The original item that changed.
+     * @param newHolder The new item that was created with the changed content. Might be null
+     * @param fromLeft  Left of the old view holder
+     * @param fromTop   Top of the old view holder
+     * @param toLeft    Left of the new view holder
+     * @param toTop     Top of the new view holder
+     * @return true if a later call to {@link #runPendingAnimations()} is requested,
+     * false otherwise.
+     */
+    public abstract boolean animateChange(ViewHolder oldHolder,
+            ViewHolder newHolder, int fromLeft, int fromTop, int toLeft, int toTop);
+
+    /**
+     * Method to be called by subclasses when a remove animation is done.
+     *
+     * @param item The item which has been removed
+     * @see RecyclerView.ItemAnimator#animateDisappearance(ViewHolder, ItemHolderInfo,
+     * ItemHolderInfo)
+     */
+    public final void dispatchRemoveFinished(ViewHolder item) {
+        onRemoveFinished(item);
+        dispatchAnimationFinished(item);
+    }
+
+    /**
+     * Method to be called by subclasses when a move animation is done.
+     *
+     * @param item The item which has been moved
+     * @see RecyclerView.ItemAnimator#animateDisappearance(ViewHolder, ItemHolderInfo,
+     * ItemHolderInfo)
+     * @see RecyclerView.ItemAnimator#animatePersistence(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+     * @see RecyclerView.ItemAnimator#animateAppearance(ViewHolder, ItemHolderInfo, ItemHolderInfo)
+     */
+    public final void dispatchMoveFinished(ViewHolder item) {
+        onMoveFinished(item);
+        dispatchAnimationFinished(item);
+    }
+
+    /**
+     * Method to be called by subclasses when an add animation is done.
+     *
+     * @param item The item which has been added
+     */
+    public final void dispatchAddFinished(ViewHolder item) {
+        onAddFinished(item);
+        dispatchAnimationFinished(item);
+    }
+
+    /**
+     * Method to be called by subclasses when a change animation is done.
+     *
+     * @param item    The item which has been changed (this method must be called for
+     *                each non-null ViewHolder passed into
+     *                {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)}).
+     * @param oldItem true if this is the old item that was changed, false if
+     *                it is the new item that replaced the old item.
+     * @see #animateChange(ViewHolder, ViewHolder, int, int, int, int)
+     */
+    public final void dispatchChangeFinished(ViewHolder item, boolean oldItem) {
+        onChangeFinished(item, oldItem);
+        dispatchAnimationFinished(item);
+    }
+
+    /**
+     * Method to be called by subclasses when a remove animation is being started.
+     *
+     * @param item The item being removed
+     */
+    public final void dispatchRemoveStarting(ViewHolder item) {
+        onRemoveStarting(item);
+    }
+
+    /**
+     * Method to be called by subclasses when a move animation is being started.
+     *
+     * @param item The item being moved
+     */
+    public final void dispatchMoveStarting(ViewHolder item) {
+        onMoveStarting(item);
+    }
+
+    /**
+     * Method to be called by subclasses when an add animation is being started.
+     *
+     * @param item The item being added
+     */
+    public final void dispatchAddStarting(ViewHolder item) {
+        onAddStarting(item);
+    }
+
+    /**
+     * Method to be called by subclasses when a change animation is being started.
+     *
+     * @param item    The item which has been changed (this method must be called for
+     *                each non-null ViewHolder passed into
+     *                {@link #animateChange(ViewHolder, ViewHolder, int, int, int, int)}).
+     * @param oldItem true if this is the old item that was changed, false if
+     *                it is the new item that replaced the old item.
+     */
+    public final void dispatchChangeStarting(ViewHolder item, boolean oldItem) {
+        onChangeStarting(item, oldItem);
+    }
+
+    /**
+     * Called when a remove animation is being started on the given ViewHolder.
+     * The default implementation does nothing. Subclasses may wish to override
+     * this method to handle any ViewHolder-specific operations linked to animation
+     * lifecycles.
+     *
+     * @param item The ViewHolder being animated.
+     */
+    @SuppressWarnings("UnusedParameters")
+    public void onRemoveStarting(ViewHolder item) {
+    }
+
+    /**
+     * Called when a remove animation has ended on the given ViewHolder.
+     * The default implementation does nothing. Subclasses may wish to override
+     * this method to handle any ViewHolder-specific operations linked to animation
+     * lifecycles.
+     *
+     * @param item The ViewHolder being animated.
+     */
+    public void onRemoveFinished(ViewHolder item) {
+    }
+
+    /**
+     * Called when an add animation is being started on the given ViewHolder.
+     * The default implementation does nothing. Subclasses may wish to override
+     * this method to handle any ViewHolder-specific operations linked to animation
+     * lifecycles.
+     *
+     * @param item The ViewHolder being animated.
+     */
+    @SuppressWarnings("UnusedParameters")
+    public void onAddStarting(ViewHolder item) {
+    }
+
+    /**
+     * Called when an add animation has ended on the given ViewHolder.
+     * The default implementation does nothing. Subclasses may wish to override
+     * this method to handle any ViewHolder-specific operations linked to animation
+     * lifecycles.
+     *
+     * @param item The ViewHolder being animated.
+     */
+    public void onAddFinished(ViewHolder item) {
+    }
+
+    /**
+     * Called when a move animation is being started on the given ViewHolder.
+     * The default implementation does nothing. Subclasses may wish to override
+     * this method to handle any ViewHolder-specific operations linked to animation
+     * lifecycles.
+     *
+     * @param item The ViewHolder being animated.
+     */
+    @SuppressWarnings("UnusedParameters")
+    public void onMoveStarting(ViewHolder item) {
+    }
+
+    /**
+     * Called when a move animation has ended on the given ViewHolder.
+     * The default implementation does nothing. Subclasses may wish to override
+     * this method to handle any ViewHolder-specific operations linked to animation
+     * lifecycles.
+     *
+     * @param item The ViewHolder being animated.
+     */
+    public void onMoveFinished(ViewHolder item) {
+    }
+
+    /**
+     * Called when a change animation is being started on the given ViewHolder.
+     * The default implementation does nothing. Subclasses may wish to override
+     * this method to handle any ViewHolder-specific operations linked to animation
+     * lifecycles.
+     *
+     * @param item    The ViewHolder being animated.
+     * @param oldItem true if this is the old item that was changed, false if
+     *                it is the new item that replaced the old item.
+     */
+    @SuppressWarnings("UnusedParameters")
+    public void onChangeStarting(ViewHolder item, boolean oldItem) {
+    }
+
+    /**
+     * Called when a change animation has ended on the given ViewHolder.
+     * The default implementation does nothing. Subclasses may wish to override
+     * this method to handle any ViewHolder-specific operations linked to animation
+     * lifecycles.
+     *
+     * @param item    The ViewHolder being animated.
+     * @param oldItem true if this is the old item that was changed, false if
+     *                it is the new item that replaced the old item.
+     */
+    public void onChangeFinished(ViewHolder item, boolean oldItem) {
+    }
+}
+
diff --git a/core/java/com/android/internal/widget/ViewInfoStore.java b/core/java/com/android/internal/widget/ViewInfoStore.java
new file mode 100644
index 0000000..6784a85
--- /dev/null
+++ b/core/java/com/android/internal/widget/ViewInfoStore.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.ArrayMap;
+import android.util.LongSparseArray;
+import android.util.Pools;
+
+import static com.android.internal.widget.RecyclerView.ItemAnimator.ItemHolderInfo;
+import static com.android.internal.widget.RecyclerView.ViewHolder;
+import static com.android.internal.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR;
+import static com.android.internal.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR_AND_DISAPPEAR;
+import static com.android.internal.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR_PRE_AND_POST;
+import static com.android.internal.widget.ViewInfoStore.InfoRecord.FLAG_DISAPPEARED;
+import static com.android.internal.widget.ViewInfoStore.InfoRecord.FLAG_POST;
+import static com.android.internal.widget.ViewInfoStore.InfoRecord.FLAG_PRE;
+import static com.android.internal.widget.ViewInfoStore.InfoRecord.FLAG_PRE_AND_POST;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * This class abstracts all tracking for Views to run animations.
+ */
+class ViewInfoStore {
+
+    private static final boolean DEBUG = false;
+
+    /**
+     * View data records for pre-layout
+     */
+    @VisibleForTesting
+    final ArrayMap<ViewHolder, InfoRecord> mLayoutHolderMap = new ArrayMap<>();
+
+    @VisibleForTesting
+    final LongSparseArray<ViewHolder> mOldChangedHolders = new LongSparseArray<>();
+
+    /**
+     * Clears the state and all existing tracking data
+     */
+    void clear() {
+        mLayoutHolderMap.clear();
+        mOldChangedHolders.clear();
+    }
+
+    /**
+     * Adds the item information to the prelayout tracking
+     * @param holder The ViewHolder whose information is being saved
+     * @param info The information to save
+     */
+    void addToPreLayout(ViewHolder holder, ItemHolderInfo info) {
+        InfoRecord record = mLayoutHolderMap.get(holder);
+        if (record == null) {
+            record = InfoRecord.obtain();
+            mLayoutHolderMap.put(holder, record);
+        }
+        record.preInfo = info;
+        record.flags |= FLAG_PRE;
+    }
+
+    boolean isDisappearing(ViewHolder holder) {
+        final InfoRecord record = mLayoutHolderMap.get(holder);
+        return record != null && ((record.flags & FLAG_DISAPPEARED) != 0);
+    }
+
+    /**
+     * Finds the ItemHolderInfo for the given ViewHolder in preLayout list and removes it.
+     *
+     * @param vh The ViewHolder whose information is being queried
+     * @return The ItemHolderInfo for the given ViewHolder or null if it does not exist
+     */
+    @Nullable
+    ItemHolderInfo popFromPreLayout(ViewHolder vh) {
+        return popFromLayoutStep(vh, FLAG_PRE);
+    }
+
+    /**
+     * Finds the ItemHolderInfo for the given ViewHolder in postLayout list and removes it.
+     *
+     * @param vh The ViewHolder whose information is being queried
+     * @return The ItemHolderInfo for the given ViewHolder or null if it does not exist
+     */
+    @Nullable
+    ItemHolderInfo popFromPostLayout(ViewHolder vh) {
+        return popFromLayoutStep(vh, FLAG_POST);
+    }
+
+    private ItemHolderInfo popFromLayoutStep(ViewHolder vh, int flag) {
+        int index = mLayoutHolderMap.indexOfKey(vh);
+        if (index < 0) {
+            return null;
+        }
+        final InfoRecord record = mLayoutHolderMap.valueAt(index);
+        if (record != null && (record.flags & flag) != 0) {
+            record.flags &= ~flag;
+            final ItemHolderInfo info;
+            if (flag == FLAG_PRE) {
+                info = record.preInfo;
+            } else if (flag == FLAG_POST) {
+                info = record.postInfo;
+            } else {
+                throw new IllegalArgumentException("Must provide flag PRE or POST");
+            }
+            // if not pre-post flag is left, clear.
+            if ((record.flags & (FLAG_PRE | FLAG_POST)) == 0) {
+                mLayoutHolderMap.removeAt(index);
+                InfoRecord.recycle(record);
+            }
+            return info;
+        }
+        return null;
+    }
+
+    /**
+     * Adds the given ViewHolder to the oldChangeHolders list
+     * @param key The key to identify the ViewHolder.
+     * @param holder The ViewHolder to store
+     */
+    void addToOldChangeHolders(long key, ViewHolder holder) {
+        mOldChangedHolders.put(key, holder);
+    }
+
+    /**
+     * Adds the given ViewHolder to the appeared in pre layout list. These are Views added by the
+     * LayoutManager during a pre-layout pass. We distinguish them from other views that were
+     * already in the pre-layout so that ItemAnimator can choose to run a different animation for
+     * them.
+     *
+     * @param holder The ViewHolder to store
+     * @param info The information to save
+     */
+    void addToAppearedInPreLayoutHolders(ViewHolder holder, ItemHolderInfo info) {
+        InfoRecord record = mLayoutHolderMap.get(holder);
+        if (record == null) {
+            record = InfoRecord.obtain();
+            mLayoutHolderMap.put(holder, record);
+        }
+        record.flags |= FLAG_APPEAR;
+        record.preInfo = info;
+    }
+
+    /**
+     * Checks whether the given ViewHolder is in preLayout list
+     * @param viewHolder The ViewHolder to query
+     *
+     * @return True if the ViewHolder is present in preLayout, false otherwise
+     */
+    boolean isInPreLayout(ViewHolder viewHolder) {
+        final InfoRecord record = mLayoutHolderMap.get(viewHolder);
+        return record != null && (record.flags & FLAG_PRE) != 0;
+    }
+
+    /**
+     * Queries the oldChangeHolder list for the given key. If they are not tracked, simply returns
+     * null.
+     * @param key The key to be used to find the ViewHolder.
+     *
+     * @return A ViewHolder if exists or null if it does not exist.
+     */
+    ViewHolder getFromOldChangeHolders(long key) {
+        return mOldChangedHolders.get(key);
+    }
+
+    /**
+     * Adds the item information to the post layout list
+     * @param holder The ViewHolder whose information is being saved
+     * @param info The information to save
+     */
+    void addToPostLayout(ViewHolder holder, ItemHolderInfo info) {
+        InfoRecord record = mLayoutHolderMap.get(holder);
+        if (record == null) {
+            record = InfoRecord.obtain();
+            mLayoutHolderMap.put(holder, record);
+        }
+        record.postInfo = info;
+        record.flags |= FLAG_POST;
+    }
+
+    /**
+     * A ViewHolder might be added by the LayoutManager just to animate its disappearance.
+     * This list holds such items so that we can animate / recycle these ViewHolders properly.
+     *
+     * @param holder The ViewHolder which disappeared during a layout.
+     */
+    void addToDisappearedInLayout(ViewHolder holder) {
+        InfoRecord record = mLayoutHolderMap.get(holder);
+        if (record == null) {
+            record = InfoRecord.obtain();
+            mLayoutHolderMap.put(holder, record);
+        }
+        record.flags |= FLAG_DISAPPEARED;
+    }
+
+    /**
+     * Removes a ViewHolder from disappearing list.
+     * @param holder The ViewHolder to be removed from the disappearing list.
+     */
+    void removeFromDisappearedInLayout(ViewHolder holder) {
+        InfoRecord record = mLayoutHolderMap.get(holder);
+        if (record == null) {
+            return;
+        }
+        record.flags &= ~FLAG_DISAPPEARED;
+    }
+
+    void process(ProcessCallback callback) {
+        for (int index = mLayoutHolderMap.size() - 1; index >= 0; index--) {
+            final ViewHolder viewHolder = mLayoutHolderMap.keyAt(index);
+            final InfoRecord record = mLayoutHolderMap.removeAt(index);
+            if ((record.flags & FLAG_APPEAR_AND_DISAPPEAR) == FLAG_APPEAR_AND_DISAPPEAR) {
+                // Appeared then disappeared. Not useful for animations.
+                callback.unused(viewHolder);
+            } else if ((record.flags & FLAG_DISAPPEARED) != 0) {
+                // Set as "disappeared" by the LayoutManager (addDisappearingView)
+                if (record.preInfo == null) {
+                    // similar to appear disappear but happened between different layout passes.
+                    // this can happen when the layout manager is using auto-measure
+                    callback.unused(viewHolder);
+                } else {
+                    callback.processDisappeared(viewHolder, record.preInfo, record.postInfo);
+                }
+            } else if ((record.flags & FLAG_APPEAR_PRE_AND_POST) == FLAG_APPEAR_PRE_AND_POST) {
+                // Appeared in the layout but not in the adapter (e.g. entered the viewport)
+                callback.processAppeared(viewHolder, record.preInfo, record.postInfo);
+            } else if ((record.flags & FLAG_PRE_AND_POST) == FLAG_PRE_AND_POST) {
+                // Persistent in both passes. Animate persistence
+                callback.processPersistent(viewHolder, record.preInfo, record.postInfo);
+            } else if ((record.flags & FLAG_PRE) != 0) {
+                // Was in pre-layout, never been added to post layout
+                callback.processDisappeared(viewHolder, record.preInfo, null);
+            } else if ((record.flags & FLAG_POST) != 0) {
+                // Was not in pre-layout, been added to post layout
+                callback.processAppeared(viewHolder, record.preInfo, record.postInfo);
+            } else if ((record.flags & FLAG_APPEAR) != 0) {
+                // Scrap view. RecyclerView will handle removing/recycling this.
+            } else if (DEBUG) {
+                throw new IllegalStateException("record without any reasonable flag combination:/");
+            }
+            InfoRecord.recycle(record);
+        }
+    }
+
+    /**
+     * Removes the ViewHolder from all list
+     * @param holder The ViewHolder which we should stop tracking
+     */
+    void removeViewHolder(ViewHolder holder) {
+        for (int i = mOldChangedHolders.size() - 1; i >= 0; i--) {
+            if (holder == mOldChangedHolders.valueAt(i)) {
+                mOldChangedHolders.removeAt(i);
+                break;
+            }
+        }
+        final InfoRecord info = mLayoutHolderMap.remove(holder);
+        if (info != null) {
+            InfoRecord.recycle(info);
+        }
+    }
+
+    void onDetach() {
+        InfoRecord.drainCache();
+    }
+
+    public void onViewDetached(ViewHolder viewHolder) {
+        removeFromDisappearedInLayout(viewHolder);
+    }
+
+    interface ProcessCallback {
+        void processDisappeared(ViewHolder viewHolder, @NonNull ItemHolderInfo preInfo,
+                @Nullable ItemHolderInfo postInfo);
+        void processAppeared(ViewHolder viewHolder, @Nullable ItemHolderInfo preInfo,
+                ItemHolderInfo postInfo);
+        void processPersistent(ViewHolder viewHolder, @NonNull ItemHolderInfo preInfo,
+                @NonNull ItemHolderInfo postInfo);
+        void unused(ViewHolder holder);
+    }
+
+    static class InfoRecord {
+        // disappearing list
+        static final int FLAG_DISAPPEARED = 1;
+        // appear in pre layout list
+        static final int FLAG_APPEAR = 1 << 1;
+        // pre layout, this is necessary to distinguish null item info
+        static final int FLAG_PRE = 1 << 2;
+        // post layout, this is necessary to distinguish null item info
+        static final int FLAG_POST = 1 << 3;
+        static final int FLAG_APPEAR_AND_DISAPPEAR = FLAG_APPEAR | FLAG_DISAPPEARED;
+        static final int FLAG_PRE_AND_POST = FLAG_PRE | FLAG_POST;
+        static final int FLAG_APPEAR_PRE_AND_POST = FLAG_APPEAR | FLAG_PRE | FLAG_POST;
+        int flags;
+        @Nullable ItemHolderInfo preInfo;
+        @Nullable ItemHolderInfo postInfo;
+        static Pools.Pool<InfoRecord> sPool = new Pools.SimplePool<>(20);
+
+        private InfoRecord() {
+        }
+
+        static InfoRecord obtain() {
+            InfoRecord record = sPool.acquire();
+            return record == null ? new InfoRecord() : record;
+        }
+
+        static void recycle(InfoRecord record) {
+            record.flags = 0;
+            record.preInfo = null;
+            record.postInfo = null;
+            sPool.release(record);
+        }
+
+        static void drainCache() {
+            //noinspection StatementWithEmptyBody
+            while (sPool.acquire() != null);
+        }
+    }
+}
diff --git a/core/java/com/android/internal/widget/helper/ItemTouchHelper.java b/core/java/com/android/internal/widget/helper/ItemTouchHelper.java
new file mode 100644
index 0000000..9636ed8
--- /dev/null
+++ b/core/java/com/android/internal/widget/helper/ItemTouchHelper.java
@@ -0,0 +1,2391 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget.helper;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.annotation.Nullable;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.os.Build;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewParent;
+import android.view.animation.Interpolator;
+
+import com.android.internal.R;
+import com.android.internal.widget.LinearLayoutManager;
+import com.android.internal.widget.RecyclerView;
+import com.android.internal.widget.RecyclerView.OnItemTouchListener;
+import com.android.internal.widget.RecyclerView.ViewHolder;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is a utility class to add swipe to dismiss and drag & drop support to RecyclerView.
+ * <p>
+ * It works with a RecyclerView and a Callback class, which configures what type of interactions
+ * are enabled and also receives events when user performs these actions.
+ * <p>
+ * Depending on which functionality you support, you should override
+ * {@link Callback#onMove(RecyclerView, ViewHolder, ViewHolder)} and / or
+ * {@link Callback#onSwiped(ViewHolder, int)}.
+ * <p>
+ * This class is designed to work with any LayoutManager but for certain situations, it can be
+ * optimized for your custom LayoutManager by extending methods in the
+ * {@link ItemTouchHelper.Callback} class or implementing {@link ItemTouchHelper.ViewDropHandler}
+ * interface in your LayoutManager.
+ * <p>
+ * By default, ItemTouchHelper moves the items' translateX/Y properties to reposition them. On
+ * platforms older than Honeycomb, ItemTouchHelper uses canvas translations and View's visibility
+ * property to move items in response to touch events. You can customize these behaviors by
+ * overriding {@link Callback#onChildDraw(Canvas, RecyclerView, ViewHolder, float, float, int,
+ * boolean)}
+ * or {@link Callback#onChildDrawOver(Canvas, RecyclerView, ViewHolder, float, float, int,
+ * boolean)}.
+ * <p/>
+ * Most of the time, you only need to override <code>onChildDraw</code> but due to limitations of
+ * platform prior to Honeycomb, you may need to implement <code>onChildDrawOver</code> as well.
+ */
+public class ItemTouchHelper extends RecyclerView.ItemDecoration
+        implements RecyclerView.OnChildAttachStateChangeListener {
+
+    /**
+     * Up direction, used for swipe & drag control.
+     */
+    public static final int UP = 1;
+
+    /**
+     * Down direction, used for swipe & drag control.
+     */
+    public static final int DOWN = 1 << 1;
+
+    /**
+     * Left direction, used for swipe & drag control.
+     */
+    public static final int LEFT = 1 << 2;
+
+    /**
+     * Right direction, used for swipe & drag control.
+     */
+    public static final int RIGHT = 1 << 3;
+
+    // If you change these relative direction values, update Callback#convertToAbsoluteDirection,
+    // Callback#convertToRelativeDirection.
+    /**
+     * Horizontal start direction. Resolved to LEFT or RIGHT depending on RecyclerView's layout
+     * direction. Used for swipe & drag control.
+     */
+    public static final int START = LEFT << 2;
+
+    /**
+     * Horizontal end direction. Resolved to LEFT or RIGHT depending on RecyclerView's layout
+     * direction. Used for swipe & drag control.
+     */
+    public static final int END = RIGHT << 2;
+
+    /**
+     * ItemTouchHelper is in idle state. At this state, either there is no related motion event by
+     * the user or latest motion events have not yet triggered a swipe or drag.
+     */
+    public static final int ACTION_STATE_IDLE = 0;
+
+    /**
+     * A View is currently being swiped.
+     */
+    public static final int ACTION_STATE_SWIPE = 1;
+
+    /**
+     * A View is currently being dragged.
+     */
+    public static final int ACTION_STATE_DRAG = 2;
+
+    /**
+     * Animation type for views which are swiped successfully.
+     */
+    public static final int ANIMATION_TYPE_SWIPE_SUCCESS = 1 << 1;
+
+    /**
+     * Animation type for views which are not completely swiped thus will animate back to their
+     * original position.
+     */
+    public static final int ANIMATION_TYPE_SWIPE_CANCEL = 1 << 2;
+
+    /**
+     * Animation type for views that were dragged and now will animate to their final position.
+     */
+    public static final int ANIMATION_TYPE_DRAG = 1 << 3;
+
+    static final String TAG = "ItemTouchHelper";
+
+    static final boolean DEBUG = false;
+
+    static final int ACTIVE_POINTER_ID_NONE = -1;
+
+    static final int DIRECTION_FLAG_COUNT = 8;
+
+    private static final int ACTION_MODE_IDLE_MASK = (1 << DIRECTION_FLAG_COUNT) - 1;
+
+    static final int ACTION_MODE_SWIPE_MASK = ACTION_MODE_IDLE_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
+     */
+    private static final int PIXELS_PER_SECOND = 1000;
+
+    /**
+     * Views, whose state should be cleared after they are detached from RecyclerView.
+     * This is necessary after swipe dismissing an item. We wait until animator finishes its job
+     * to clean these views.
+     */
+    final List<View> mPendingCleanup = new ArrayList<View>();
+
+    /**
+     * Re-use array to calculate dx dy for a ViewHolder
+     */
+    private final float[] mTmpPosition = new float[2];
+
+    /**
+     * Currently selected view holder
+     */
+    ViewHolder mSelected = null;
+
+    /**
+     * The reference coordinates for the action start. For drag & drop, this is the time long
+     * press is completed vs for swipe, this is the initial touch point.
+     */
+    float mInitialTouchX;
+
+    float mInitialTouchY;
+
+    /**
+     * Set when ItemTouchHelper is assigned to a RecyclerView.
+     */
+    float mSwipeEscapeVelocity;
+
+    /**
+     * Set when ItemTouchHelper is assigned to a RecyclerView.
+     */
+    float mMaxSwipeVelocity;
+
+    /**
+     * The diff between the last event and initial touch.
+     */
+    float mDx;
+
+    float mDy;
+
+    /**
+     * The coordinates of the selected view at the time it is selected. We record these values
+     * when action starts so that we can consistently position it even if LayoutManager moves the
+     * View.
+     */
+    float mSelectedStartX;
+
+    float mSelectedStartY;
+
+    /**
+     * The pointer we are tracking.
+     */
+    int mActivePointerId = ACTIVE_POINTER_ID_NONE;
+
+    /**
+     * Developer callback which controls the behavior of ItemTouchHelper.
+     */
+    Callback mCallback;
+
+    /**
+     * Current mode.
+     */
+    int mActionState = ACTION_STATE_IDLE;
+
+    /**
+     * The direction flags obtained from unmasking
+     * {@link Callback#getAbsoluteMovementFlags(RecyclerView, ViewHolder)} for the current
+     * action state.
+     */
+    int mSelectedFlags;
+
+    /**
+     * When a View is dragged or swiped and needs to go back to where it was, we create a Recover
+     * Animation and animate it to its location using this custom Animator, instead of using
+     * framework Animators.
+     * Using framework animators has the side effect of clashing with ItemAnimator, creating
+     * jumpy UIs.
+     */
+    List<RecoverAnimation> mRecoverAnimations = new ArrayList<RecoverAnimation>();
+
+    private int mSlop;
+
+    RecyclerView mRecyclerView;
+
+    /**
+     * When user drags a view to the edge, we start scrolling the LayoutManager as long as View
+     * is partially out of bounds.
+     */
+    final Runnable mScrollRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (mSelected != null && scrollIfNecessary()) {
+                if (mSelected != null) { //it might be lost during scrolling
+                    moveIfNecessary(mSelected);
+                }
+                mRecyclerView.removeCallbacks(mScrollRunnable);
+                mRecyclerView.postOnAnimation(this);
+            }
+        }
+    };
+
+    /**
+     * Used for detecting fling swipe
+     */
+    VelocityTracker mVelocityTracker;
+
+    //re-used list for selecting a swap target
+    private List<ViewHolder> mSwapTargets;
+
+    //re used for for sorting swap targets
+    private List<Integer> mDistances;
+
+    /**
+     * If drag & drop is supported, we use child drawing order to bring them to front.
+     */
+    private RecyclerView.ChildDrawingOrderCallback mChildDrawingOrderCallback = null;
+
+    /**
+     * This keeps a reference to the child dragged by the user. Even after user stops dragging,
+     * until view reaches its final position (end of recover animation), we keep a reference so
+     * that it can be drawn above other children.
+     */
+    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.
+     */
+    int mOverdrawChildPosition = -1;
+
+    /**
+     * Used to detect long press.
+     */
+    GestureDetector mGestureDetector;
+
+    private final OnItemTouchListener mOnItemTouchListener = new OnItemTouchListener() {
+        @Override
+        public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent event) {
+            mGestureDetector.onTouchEvent(event);
+            if (DEBUG) {
+                Log.d(TAG, "intercept: x:" + event.getX() + ",y:" + event.getY() + ", " + event);
+            }
+            final int action = event.getActionMasked();
+            if (action == MotionEvent.ACTION_DOWN) {
+                mActivePointerId = event.getPointerId(0);
+                mInitialTouchX = event.getX();
+                mInitialTouchY = event.getY();
+                obtainVelocityTracker();
+                if (mSelected == null) {
+                    final RecoverAnimation animation = findAnimation(event);
+                    if (animation != null) {
+                        mInitialTouchX -= animation.mX;
+                        mInitialTouchY -= animation.mY;
+                        endRecoverAnimation(animation.mViewHolder, true);
+                        if (mPendingCleanup.remove(animation.mViewHolder.itemView)) {
+                            mCallback.clearView(mRecyclerView, animation.mViewHolder);
+                        }
+                        select(animation.mViewHolder, animation.mActionState);
+                        updateDxDy(event, mSelectedFlags, 0);
+                    }
+                }
+            } else if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
+                mActivePointerId = ACTIVE_POINTER_ID_NONE;
+                select(null, ACTION_STATE_IDLE);
+            } else if (mActivePointerId != ACTIVE_POINTER_ID_NONE) {
+                // in a non scroll orientation, if distance change is above threshold, we
+                // can select the item
+                final int index = event.findPointerIndex(mActivePointerId);
+                if (DEBUG) {
+                    Log.d(TAG, "pointer index " + index);
+                }
+                if (index >= 0) {
+                    checkSelectForSwipe(action, event, index);
+                }
+            }
+            if (mVelocityTracker != null) {
+                mVelocityTracker.addMovement(event);
+            }
+            return mSelected != null;
+        }
+
+        @Override
+        public void onTouchEvent(RecyclerView recyclerView, MotionEvent event) {
+            mGestureDetector.onTouchEvent(event);
+            if (DEBUG) {
+                Log.d(TAG,
+                        "on touch: x:" + mInitialTouchX + ",y:" + mInitialTouchY + ", :" + event);
+            }
+            if (mVelocityTracker != null) {
+                mVelocityTracker.addMovement(event);
+            }
+            if (mActivePointerId == ACTIVE_POINTER_ID_NONE) {
+                return;
+            }
+            final int action = event.getActionMasked();
+            final int activePointerIndex = event.findPointerIndex(mActivePointerId);
+            if (activePointerIndex >= 0) {
+                checkSelectForSwipe(action, event, activePointerIndex);
+            }
+            ViewHolder viewHolder = mSelected;
+            if (viewHolder == null) {
+                return;
+            }
+            switch (action) {
+                case MotionEvent.ACTION_MOVE: {
+                    // Find the index of the active pointer and fetch its position
+                    if (activePointerIndex >= 0) {
+                        updateDxDy(event, mSelectedFlags, activePointerIndex);
+                        moveIfNecessary(viewHolder);
+                        mRecyclerView.removeCallbacks(mScrollRunnable);
+                        mScrollRunnable.run();
+                        mRecyclerView.invalidate();
+                    }
+                    break;
+                }
+                case MotionEvent.ACTION_CANCEL:
+                    if (mVelocityTracker != null) {
+                        mVelocityTracker.clear();
+                    }
+                    // fall through
+                case MotionEvent.ACTION_UP:
+                    select(null, ACTION_STATE_IDLE);
+                    mActivePointerId = ACTIVE_POINTER_ID_NONE;
+                    break;
+                case MotionEvent.ACTION_POINTER_UP: {
+                    final int pointerIndex = event.getActionIndex();
+                    final int pointerId = event.getPointerId(pointerIndex);
+                    if (pointerId == mActivePointerId) {
+                        // This was our active pointer going up. Choose a new
+                        // active pointer and adjust accordingly.
+                        final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+                        mActivePointerId = event.getPointerId(newPointerIndex);
+                        updateDxDy(event, mSelectedFlags, pointerIndex);
+                    }
+                    break;
+                }
+            }
+        }
+
+        @Override
+        public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+            if (!disallowIntercept) {
+                return;
+            }
+            select(null, ACTION_STATE_IDLE);
+        }
+    };
+
+    /**
+     * Temporary rect instance that is used when we need to lookup Item decorations.
+     */
+    private Rect mTmpRect;
+
+    /**
+     * When user started to drag scroll. Reset when we don't scroll
+     */
+    private long mDragScrollStartTimeInMs;
+
+    /**
+     * Creates an ItemTouchHelper that will work with the given Callback.
+     * <p>
+     * You can attach ItemTouchHelper to a RecyclerView via
+     * {@link #attachToRecyclerView(RecyclerView)}. Upon attaching, it will add an item decoration,
+     * an onItemTouchListener and a Child attach / detach listener to the RecyclerView.
+     *
+     * @param callback The Callback which controls the behavior of this touch helper.
+     */
+    public ItemTouchHelper(Callback callback) {
+        mCallback = callback;
+    }
+
+    private static boolean hitTest(View child, float x, float y, float left, float top) {
+        return x >= left
+                && x <= left + child.getWidth()
+                && y >= top
+                && y <= top + child.getHeight();
+    }
+
+    /**
+     * Attaches the ItemTouchHelper to the provided RecyclerView. If TouchHelper is already
+     * attached to a RecyclerView, it will first detach from the previous one. You can call this
+     * method with {@code null} to detach it from the current RecyclerView.
+     *
+     * @param recyclerView The RecyclerView instance to which you want to add this helper or
+     *                     {@code null} if you want to remove ItemTouchHelper from the current
+     *                     RecyclerView.
+     */
+    public void attachToRecyclerView(@Nullable RecyclerView recyclerView) {
+        if (mRecyclerView == recyclerView) {
+            return; // nothing to do
+        }
+        if (mRecyclerView != null) {
+            destroyCallbacks();
+        }
+        mRecyclerView = recyclerView;
+        if (mRecyclerView != null) {
+            final Resources resources = recyclerView.getResources();
+            mSwipeEscapeVelocity = resources
+                    .getDimension(R.dimen.item_touch_helper_swipe_escape_velocity);
+            mMaxSwipeVelocity = resources
+                    .getDimension(R.dimen.item_touch_helper_swipe_escape_max_velocity);
+            setupCallbacks();
+        }
+    }
+
+    private void setupCallbacks() {
+        ViewConfiguration vc = ViewConfiguration.get(mRecyclerView.getContext());
+        mSlop = vc.getScaledTouchSlop();
+        mRecyclerView.addItemDecoration(this);
+        mRecyclerView.addOnItemTouchListener(mOnItemTouchListener);
+        mRecyclerView.addOnChildAttachStateChangeListener(this);
+        initGestureDetector();
+    }
+
+    private void destroyCallbacks() {
+        mRecyclerView.removeItemDecoration(this);
+        mRecyclerView.removeOnItemTouchListener(mOnItemTouchListener);
+        mRecyclerView.removeOnChildAttachStateChangeListener(this);
+        // clean all attached
+        final int recoverAnimSize = mRecoverAnimations.size();
+        for (int i = recoverAnimSize - 1; i >= 0; i--) {
+            final RecoverAnimation recoverAnimation = mRecoverAnimations.get(0);
+            mCallback.clearView(mRecyclerView, recoverAnimation.mViewHolder);
+        }
+        mRecoverAnimations.clear();
+        mOverdrawChild = null;
+        mOverdrawChildPosition = -1;
+        releaseVelocityTracker();
+    }
+
+    private void initGestureDetector() {
+        if (mGestureDetector != null) {
+            return;
+        }
+        mGestureDetector = new GestureDetector(mRecyclerView.getContext(),
+                new ItemTouchHelperGestureListener());
+    }
+
+    private void getSelectedDxDy(float[] outPosition) {
+        if ((mSelectedFlags & (LEFT | RIGHT)) != 0) {
+            outPosition[0] = mSelectedStartX + mDx - mSelected.itemView.getLeft();
+        } else {
+            outPosition[0] = mSelected.itemView.getTranslationX();
+        }
+        if ((mSelectedFlags & (UP | DOWN)) != 0) {
+            outPosition[1] = mSelectedStartY + mDy - mSelected.itemView.getTop();
+        } else {
+            outPosition[1] = mSelected.itemView.getTranslationY();
+        }
+    }
+
+    @Override
+    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
+        float dx = 0, dy = 0;
+        if (mSelected != null) {
+            getSelectedDxDy(mTmpPosition);
+            dx = mTmpPosition[0];
+            dy = mTmpPosition[1];
+        }
+        mCallback.onDrawOver(c, parent, mSelected,
+                mRecoverAnimations, mActionState, dx, dy);
+    }
+
+    @Override
+    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
+        // we don't know if RV changed something so we should invalidate this index.
+        mOverdrawChildPosition = -1;
+        float dx = 0, dy = 0;
+        if (mSelected != null) {
+            getSelectedDxDy(mTmpPosition);
+            dx = mTmpPosition[0];
+            dy = mTmpPosition[1];
+        }
+        mCallback.onDraw(c, parent, mSelected,
+                mRecoverAnimations, mActionState, dx, dy);
+    }
+
+    /**
+     * Starts dragging or swiping the given View. Call with null if you want to clear it.
+     *
+     * @param selected    The ViewHolder to drag or swipe. Can be null if you want to cancel the
+     *                    current action
+     * @param actionState The type of action
+     */
+    void select(ViewHolder selected, int actionState) {
+        if (selected == mSelected && actionState == mActionState) {
+            return;
+        }
+        mDragScrollStartTimeInMs = Long.MIN_VALUE;
+        final int prevActionState = mActionState;
+        // prevent duplicate animations
+        endRecoverAnimation(selected, true);
+        mActionState = actionState;
+        if (actionState == ACTION_STATE_DRAG) {
+            // we remove after animation is complete. this means we only elevate the last drag
+            // child but that should perform good enough as it is very hard to start dragging a
+            // new child before the previous one settles.
+            mOverdrawChild = selected.itemView;
+            addChildDrawingOrderCallback();
+        }
+        int actionStateMask = (1 << (DIRECTION_FLAG_COUNT + DIRECTION_FLAG_COUNT * actionState))
+                - 1;
+        boolean preventLayout = false;
+
+        if (mSelected != null) {
+            final ViewHolder prevSelected = mSelected;
+            if (prevSelected.itemView.getParent() != null) {
+                final int swipeDir = prevActionState == ACTION_STATE_DRAG ? 0
+                        : swipeIfNecessary(prevSelected);
+                releaseVelocityTracker();
+                // find where we should animate to
+                final float targetTranslateX, targetTranslateY;
+                int animationType;
+                switch (swipeDir) {
+                    case LEFT:
+                    case RIGHT:
+                    case START:
+                    case END:
+                        targetTranslateY = 0;
+                        targetTranslateX = Math.signum(mDx) * mRecyclerView.getWidth();
+                        break;
+                    case UP:
+                    case DOWN:
+                        targetTranslateX = 0;
+                        targetTranslateY = Math.signum(mDy) * mRecyclerView.getHeight();
+                        break;
+                    default:
+                        targetTranslateX = 0;
+                        targetTranslateY = 0;
+                }
+                if (prevActionState == ACTION_STATE_DRAG) {
+                    animationType = ANIMATION_TYPE_DRAG;
+                } else if (swipeDir > 0) {
+                    animationType = ANIMATION_TYPE_SWIPE_SUCCESS;
+                } else {
+                    animationType = ANIMATION_TYPE_SWIPE_CANCEL;
+                }
+                getSelectedDxDy(mTmpPosition);
+                final float currentTranslateX = mTmpPosition[0];
+                final float currentTranslateY = mTmpPosition[1];
+                final RecoverAnimation rv = new RecoverAnimation(prevSelected, animationType,
+                        prevActionState, currentTranslateX, currentTranslateY,
+                        targetTranslateX, targetTranslateY) {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        super.onAnimationEnd(animation);
+                        if (this.mOverridden) {
+                            return;
+                        }
+                        if (swipeDir <= 0) {
+                            // this is a drag or failed swipe. recover immediately
+                            mCallback.clearView(mRecyclerView, prevSelected);
+                            // full cleanup will happen on onDrawOver
+                        } else {
+                            // wait until remove animation is complete.
+                            mPendingCleanup.add(prevSelected.itemView);
+                            mIsPendingCleanup = true;
+                            if (swipeDir > 0) {
+                                // Animation might be ended by other animators during a layout.
+                                // We defer callback to avoid editing adapter during a layout.
+                                postDispatchSwipe(this, swipeDir);
+                            }
+                        }
+                        // removed from the list after it is drawn for the last time
+                        if (mOverdrawChild == prevSelected.itemView) {
+                            removeChildDrawingOrderCallbackIfNecessary(prevSelected.itemView);
+                        }
+                    }
+                };
+                final long duration = mCallback.getAnimationDuration(mRecyclerView, animationType,
+                        targetTranslateX - currentTranslateX, targetTranslateY - currentTranslateY);
+                rv.setDuration(duration);
+                mRecoverAnimations.add(rv);
+                rv.start();
+                preventLayout = true;
+            } else {
+                removeChildDrawingOrderCallbackIfNecessary(prevSelected.itemView);
+                mCallback.clearView(mRecyclerView, prevSelected);
+            }
+            mSelected = null;
+        }
+        if (selected != null) {
+            mSelectedFlags =
+                    (mCallback.getAbsoluteMovementFlags(mRecyclerView, selected) & actionStateMask)
+                            >> (mActionState * DIRECTION_FLAG_COUNT);
+            mSelectedStartX = selected.itemView.getLeft();
+            mSelectedStartY = selected.itemView.getTop();
+            mSelected = selected;
+
+            if (actionState == ACTION_STATE_DRAG) {
+                mSelected.itemView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+            }
+        }
+        final ViewParent rvParent = mRecyclerView.getParent();
+        if (rvParent != null) {
+            rvParent.requestDisallowInterceptTouchEvent(mSelected != null);
+        }
+        if (!preventLayout) {
+            mRecyclerView.getLayoutManager().requestSimpleAnimationsInNextLayout();
+        }
+        mCallback.onSelectedChanged(mSelected, mActionState);
+        mRecyclerView.invalidate();
+    }
+
+    void postDispatchSwipe(final RecoverAnimation anim, final int swipeDir) {
+        // wait until animations are complete.
+        mRecyclerView.post(new Runnable() {
+            @Override
+            public void run() {
+                if (mRecyclerView != null && mRecyclerView.isAttachedToWindow()
+                        && !anim.mOverridden
+                        && anim.mViewHolder.getAdapterPosition() != RecyclerView.NO_POSITION) {
+                    final RecyclerView.ItemAnimator animator = mRecyclerView.getItemAnimator();
+                    // if animator is running or we have other active recover animations, we try
+                    // not to call onSwiped because DefaultItemAnimator is not good at merging
+                    // animations. Instead, we wait and batch.
+                    if ((animator == null || !animator.isRunning(null))
+                            && !hasRunningRecoverAnim()) {
+                        mCallback.onSwiped(anim.mViewHolder, swipeDir);
+                    } else {
+                        mRecyclerView.post(this);
+                    }
+                }
+            }
+        });
+    }
+
+    boolean hasRunningRecoverAnim() {
+        final int size = mRecoverAnimations.size();
+        for (int i = 0; i < size; i++) {
+            if (!mRecoverAnimations.get(i).mEnded) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * If user drags the view to the edge, trigger a scroll if necessary.
+     */
+    boolean scrollIfNecessary() {
+        if (mSelected == null) {
+            mDragScrollStartTimeInMs = Long.MIN_VALUE;
+            return false;
+        }
+        final long now = System.currentTimeMillis();
+        final long scrollDuration = mDragScrollStartTimeInMs
+                == Long.MIN_VALUE ? 0 : now - mDragScrollStartTimeInMs;
+        RecyclerView.LayoutManager lm = mRecyclerView.getLayoutManager();
+        if (mTmpRect == null) {
+            mTmpRect = new Rect();
+        }
+        int scrollX = 0;
+        int scrollY = 0;
+        lm.calculateItemDecorationsForChild(mSelected.itemView, mTmpRect);
+        if (lm.canScrollHorizontally()) {
+            int curX = (int) (mSelectedStartX + mDx);
+            final int leftDiff = curX - mTmpRect.left - mRecyclerView.getPaddingLeft();
+            if (mDx < 0 && leftDiff < 0) {
+                scrollX = leftDiff;
+            } else if (mDx > 0) {
+                final int rightDiff =
+                        curX + mSelected.itemView.getWidth() + mTmpRect.right
+                                - (mRecyclerView.getWidth() - mRecyclerView.getPaddingRight());
+                if (rightDiff > 0) {
+                    scrollX = rightDiff;
+                }
+            }
+        }
+        if (lm.canScrollVertically()) {
+            int curY = (int) (mSelectedStartY + mDy);
+            final int topDiff = curY - mTmpRect.top - mRecyclerView.getPaddingTop();
+            if (mDy < 0 && topDiff < 0) {
+                scrollY = topDiff;
+            } else if (mDy > 0) {
+                final int bottomDiff = curY + mSelected.itemView.getHeight() + mTmpRect.bottom
+                        - (mRecyclerView.getHeight() - mRecyclerView.getPaddingBottom());
+                if (bottomDiff > 0) {
+                    scrollY = bottomDiff;
+                }
+            }
+        }
+        if (scrollX != 0) {
+            scrollX = mCallback.interpolateOutOfBoundsScroll(mRecyclerView,
+                    mSelected.itemView.getWidth(), scrollX,
+                    mRecyclerView.getWidth(), scrollDuration);
+        }
+        if (scrollY != 0) {
+            scrollY = mCallback.interpolateOutOfBoundsScroll(mRecyclerView,
+                    mSelected.itemView.getHeight(), scrollY,
+                    mRecyclerView.getHeight(), scrollDuration);
+        }
+        if (scrollX != 0 || scrollY != 0) {
+            if (mDragScrollStartTimeInMs == Long.MIN_VALUE) {
+                mDragScrollStartTimeInMs = now;
+            }
+            mRecyclerView.scrollBy(scrollX, scrollY);
+            return true;
+        }
+        mDragScrollStartTimeInMs = Long.MIN_VALUE;
+        return false;
+    }
+
+    private List<ViewHolder> findSwapTargets(ViewHolder viewHolder) {
+        if (mSwapTargets == null) {
+            mSwapTargets = new ArrayList<ViewHolder>();
+            mDistances = new ArrayList<Integer>();
+        } else {
+            mSwapTargets.clear();
+            mDistances.clear();
+        }
+        final int margin = mCallback.getBoundingBoxMargin();
+        final int left = Math.round(mSelectedStartX + mDx) - margin;
+        final int top = Math.round(mSelectedStartY + mDy) - margin;
+        final int right = left + viewHolder.itemView.getWidth() + 2 * margin;
+        final int bottom = top + viewHolder.itemView.getHeight() + 2 * margin;
+        final int centerX = (left + right) / 2;
+        final int centerY = (top + bottom) / 2;
+        final RecyclerView.LayoutManager lm = mRecyclerView.getLayoutManager();
+        final int childCount = lm.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View other = lm.getChildAt(i);
+            if (other == viewHolder.itemView) {
+                continue; //myself!
+            }
+            if (other.getBottom() < top || other.getTop() > bottom
+                    || other.getRight() < left || other.getLeft() > right) {
+                continue;
+            }
+            final ViewHolder otherVh = mRecyclerView.getChildViewHolder(other);
+            if (mCallback.canDropOver(mRecyclerView, mSelected, otherVh)) {
+                // find the index to add
+                final int dx = Math.abs(centerX - (other.getLeft() + other.getRight()) / 2);
+                final int dy = Math.abs(centerY - (other.getTop() + other.getBottom()) / 2);
+                final int dist = dx * dx + dy * dy;
+
+                int pos = 0;
+                final int cnt = mSwapTargets.size();
+                for (int j = 0; j < cnt; j++) {
+                    if (dist > mDistances.get(j)) {
+                        pos++;
+                    } else {
+                        break;
+                    }
+                }
+                mSwapTargets.add(pos, otherVh);
+                mDistances.add(pos, dist);
+            }
+        }
+        return mSwapTargets;
+    }
+
+    /**
+     * Checks if we should swap w/ another view holder.
+     */
+    void moveIfNecessary(ViewHolder viewHolder) {
+        if (mRecyclerView.isLayoutRequested()) {
+            return;
+        }
+        if (mActionState != ACTION_STATE_DRAG) {
+            return;
+        }
+
+        final float threshold = mCallback.getMoveThreshold(viewHolder);
+        final int x = (int) (mSelectedStartX + mDx);
+        final int y = (int) (mSelectedStartY + mDy);
+        if (Math.abs(y - viewHolder.itemView.getTop()) < viewHolder.itemView.getHeight() * threshold
+                && Math.abs(x - viewHolder.itemView.getLeft())
+                < viewHolder.itemView.getWidth() * threshold) {
+            return;
+        }
+        List<ViewHolder> swapTargets = findSwapTargets(viewHolder);
+        if (swapTargets.size() == 0) {
+            return;
+        }
+        // may swap.
+        ViewHolder target = mCallback.chooseDropTarget(viewHolder, swapTargets, x, y);
+        if (target == null) {
+            mSwapTargets.clear();
+            mDistances.clear();
+            return;
+        }
+        final int toPosition = target.getAdapterPosition();
+        final int fromPosition = viewHolder.getAdapterPosition();
+        if (mCallback.onMove(mRecyclerView, viewHolder, target)) {
+            // keep target visible
+            mCallback.onMoved(mRecyclerView, viewHolder, fromPosition,
+                    target, toPosition, x, y);
+        }
+    }
+
+    @Override
+    public void onChildViewAttachedToWindow(View view) {
+    }
+
+    @Override
+    public void onChildViewDetachedFromWindow(View view) {
+        removeChildDrawingOrderCallbackIfNecessary(view);
+        final ViewHolder holder = mRecyclerView.getChildViewHolder(view);
+        if (holder == null) {
+            return;
+        }
+        if (mSelected != null && holder == mSelected) {
+            select(null, ACTION_STATE_IDLE);
+        } else {
+            endRecoverAnimation(holder, false); // this may push it into pending cleanup list.
+            if (mPendingCleanup.remove(holder.itemView)) {
+                mCallback.clearView(mRecyclerView, holder);
+            }
+        }
+    }
+
+    /**
+     * Returns the animation type or 0 if cannot be found.
+     */
+    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);
+            if (anim.mViewHolder == viewHolder) {
+                anim.mOverridden |= override;
+                if (!anim.mEnded) {
+                    anim.cancel();
+                }
+                mRecoverAnimations.remove(i);
+                return anim.mAnimationType;
+            }
+        }
+        return 0;
+    }
+
+    @Override
+    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
+            RecyclerView.State state) {
+        outRect.setEmpty();
+    }
+
+    void obtainVelocityTracker() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+        }
+        mVelocityTracker = VelocityTracker.obtain();
+    }
+
+    private void releaseVelocityTracker() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    private ViewHolder findSwipedView(MotionEvent motionEvent) {
+        final RecyclerView.LayoutManager lm = mRecyclerView.getLayoutManager();
+        if (mActivePointerId == ACTIVE_POINTER_ID_NONE) {
+            return null;
+        }
+        final int pointerIndex = motionEvent.findPointerIndex(mActivePointerId);
+        final float dx = motionEvent.getX(pointerIndex) - mInitialTouchX;
+        final float dy = motionEvent.getY(pointerIndex) - mInitialTouchY;
+        final float absDx = Math.abs(dx);
+        final float absDy = Math.abs(dy);
+
+        if (absDx < mSlop && absDy < mSlop) {
+            return null;
+        }
+        if (absDx > absDy && lm.canScrollHorizontally()) {
+            return null;
+        } else if (absDy > absDx && lm.canScrollVertically()) {
+            return null;
+        }
+        View child = findChildView(motionEvent);
+        if (child == null) {
+            return null;
+        }
+        return mRecyclerView.getChildViewHolder(child);
+    }
+
+    /**
+     * Checks whether we should select a View for swiping.
+     */
+    boolean checkSelectForSwipe(int action, MotionEvent motionEvent, int pointerIndex) {
+        if (mSelected != null || action != MotionEvent.ACTION_MOVE
+                || mActionState == ACTION_STATE_DRAG || !mCallback.isItemViewSwipeEnabled()) {
+            return false;
+        }
+        if (mRecyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
+            return false;
+        }
+        final ViewHolder vh = findSwipedView(motionEvent);
+        if (vh == null) {
+            return false;
+        }
+        final int movementFlags = mCallback.getAbsoluteMovementFlags(mRecyclerView, vh);
+
+        final int swipeFlags = (movementFlags & ACTION_MODE_SWIPE_MASK)
+                >> (DIRECTION_FLAG_COUNT * ACTION_STATE_SWIPE);
+
+        if (swipeFlags == 0) {
+            return false;
+        }
+
+        // mDx and mDy are only set in allowed directions. We use custom x/y here instead of
+        // updateDxDy to avoid swiping if user moves more in the other direction
+        final float x = motionEvent.getX(pointerIndex);
+        final float y = motionEvent.getY(pointerIndex);
+
+        // Calculate the distance moved
+        final float dx = x - mInitialTouchX;
+        final float dy = y - mInitialTouchY;
+        // swipe target is chose w/o applying flags so it does not really check if swiping in that
+        // direction is allowed. This why here, we use mDx mDy to check slope value again.
+        final float absDx = Math.abs(dx);
+        final float absDy = Math.abs(dy);
+
+        if (absDx < mSlop && absDy < mSlop) {
+            return false;
+        }
+        if (absDx > absDy) {
+            if (dx < 0 && (swipeFlags & LEFT) == 0) {
+                return false;
+            }
+            if (dx > 0 && (swipeFlags & RIGHT) == 0) {
+                return false;
+            }
+        } else {
+            if (dy < 0 && (swipeFlags & UP) == 0) {
+                return false;
+            }
+            if (dy > 0 && (swipeFlags & DOWN) == 0) {
+                return false;
+            }
+        }
+        mDx = mDy = 0f;
+        mActivePointerId = motionEvent.getPointerId(0);
+        select(vh, ACTION_STATE_SWIPE);
+        return true;
+    }
+
+    View findChildView(MotionEvent event) {
+        // first check elevated views, if none, then call RV
+        final float x = event.getX();
+        final float y = event.getY();
+        if (mSelected != null) {
+            final View selectedView = mSelected.itemView;
+            if (hitTest(selectedView, x, y, mSelectedStartX + mDx, mSelectedStartY + mDy)) {
+                return selectedView;
+            }
+        }
+        for (int i = mRecoverAnimations.size() - 1; i >= 0; i--) {
+            final RecoverAnimation anim = mRecoverAnimations.get(i);
+            final View view = anim.mViewHolder.itemView;
+            if (hitTest(view, x, y, anim.mX, anim.mY)) {
+                return view;
+            }
+        }
+        return mRecyclerView.findChildViewUnder(x, y);
+    }
+
+    /**
+     * Starts dragging the provided ViewHolder. By default, ItemTouchHelper starts a drag when a
+     * View is long pressed. You can disable that behavior by overriding
+     * {@link ItemTouchHelper.Callback#isLongPressDragEnabled()}.
+     * <p>
+     * For this method to work:
+     * <ul>
+     * <li>The provided ViewHolder must be a child of the RecyclerView to which this
+     * ItemTouchHelper
+     * is attached.</li>
+     * <li>{@link ItemTouchHelper.Callback} must have dragging enabled.</li>
+     * <li>There must be a previous touch event that was reported to the ItemTouchHelper
+     * through RecyclerView's ItemTouchListener mechanism. As long as no other ItemTouchListener
+     * grabs previous events, this should work as expected.</li>
+     * </ul>
+     *
+     * For example, if you would like to let your user to be able to drag an Item by touching one
+     * of its descendants, you may implement it as follows:
+     * <pre>
+     *     viewHolder.dragButton.setOnTouchListener(new View.OnTouchListener() {
+     *         public boolean onTouch(View v, MotionEvent event) {
+     *             if (MotionEvent.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
+     *                 mItemTouchHelper.startDrag(viewHolder);
+     *             }
+     *             return false;
+     *         }
+     *     });
+     * </pre>
+     * <p>
+     *
+     * @param viewHolder The ViewHolder to start dragging. It must be a direct child of
+     *                   RecyclerView.
+     * @see ItemTouchHelper.Callback#isItemViewSwipeEnabled()
+     */
+    public void startDrag(ViewHolder viewHolder) {
+        if (!mCallback.hasDragFlag(mRecyclerView, viewHolder)) {
+            Log.e(TAG, "Start drag has been called but dragging is not enabled");
+            return;
+        }
+        if (viewHolder.itemView.getParent() != mRecyclerView) {
+            Log.e(TAG, "Start drag has been called with a view holder which is not a child of "
+                    + "the RecyclerView which is controlled by this ItemTouchHelper.");
+            return;
+        }
+        obtainVelocityTracker();
+        mDx = mDy = 0f;
+        select(viewHolder, ACTION_STATE_DRAG);
+    }
+
+    /**
+     * Starts swiping the provided ViewHolder. By default, ItemTouchHelper starts swiping a View
+     * when user swipes their finger (or mouse pointer) over the View. You can disable this
+     * behavior
+     * by overriding {@link ItemTouchHelper.Callback}
+     * <p>
+     * For this method to work:
+     * <ul>
+     * <li>The provided ViewHolder must be a child of the RecyclerView to which this
+     * ItemTouchHelper is attached.</li>
+     * <li>{@link ItemTouchHelper.Callback} must have swiping enabled.</li>
+     * <li>There must be a previous touch event that was reported to the ItemTouchHelper
+     * through RecyclerView's ItemTouchListener mechanism. As long as no other ItemTouchListener
+     * grabs previous events, this should work as expected.</li>
+     * </ul>
+     *
+     * For example, if you would like to let your user to be able to swipe an Item by touching one
+     * of its descendants, you may implement it as follows:
+     * <pre>
+     *     viewHolder.dragButton.setOnTouchListener(new View.OnTouchListener() {
+     *         public boolean onTouch(View v, MotionEvent event) {
+     *             if (MotionEvent.getActionMasked(event) == MotionEvent.ACTION_DOWN) {
+     *                 mItemTouchHelper.startSwipe(viewHolder);
+     *             }
+     *             return false;
+     *         }
+     *     });
+     * </pre>
+     *
+     * @param viewHolder The ViewHolder to start swiping. It must be a direct child of
+     *                   RecyclerView.
+     */
+    public void startSwipe(ViewHolder viewHolder) {
+        if (!mCallback.hasSwipeFlag(mRecyclerView, viewHolder)) {
+            Log.e(TAG, "Start swipe has been called but swiping is not enabled");
+            return;
+        }
+        if (viewHolder.itemView.getParent() != mRecyclerView) {
+            Log.e(TAG, "Start swipe has been called with a view holder which is not a child of "
+                    + "the RecyclerView controlled by this ItemTouchHelper.");
+            return;
+        }
+        obtainVelocityTracker();
+        mDx = mDy = 0f;
+        select(viewHolder, ACTION_STATE_SWIPE);
+    }
+
+    RecoverAnimation findAnimation(MotionEvent event) {
+        if (mRecoverAnimations.isEmpty()) {
+            return null;
+        }
+        View target = findChildView(event);
+        for (int i = mRecoverAnimations.size() - 1; i >= 0; i--) {
+            final RecoverAnimation anim = mRecoverAnimations.get(i);
+            if (anim.mViewHolder.itemView == target) {
+                return anim;
+            }
+        }
+        return null;
+    }
+
+    void updateDxDy(MotionEvent ev, int directionFlags, int pointerIndex) {
+        final float x = ev.getX(pointerIndex);
+        final float y = ev.getY(pointerIndex);
+
+        // Calculate the distance moved
+        mDx = x - mInitialTouchX;
+        mDy = y - mInitialTouchY;
+        if ((directionFlags & LEFT) == 0) {
+            mDx = Math.max(0, mDx);
+        }
+        if ((directionFlags & RIGHT) == 0) {
+            mDx = Math.min(0, mDx);
+        }
+        if ((directionFlags & UP) == 0) {
+            mDy = Math.max(0, mDy);
+        }
+        if ((directionFlags & DOWN) == 0) {
+            mDy = Math.min(0, mDy);
+        }
+    }
+
+    private int swipeIfNecessary(ViewHolder viewHolder) {
+        if (mActionState == ACTION_STATE_DRAG) {
+            return 0;
+        }
+        final int originalMovementFlags = mCallback.getMovementFlags(mRecyclerView, viewHolder);
+        final int absoluteMovementFlags = mCallback.convertToAbsoluteDirection(
+                originalMovementFlags,
+                mRecyclerView.getLayoutDirection());
+        final int flags = (absoluteMovementFlags
+                & ACTION_MODE_SWIPE_MASK) >> (ACTION_STATE_SWIPE * DIRECTION_FLAG_COUNT);
+        if (flags == 0) {
+            return 0;
+        }
+        final int originalFlags = (originalMovementFlags
+                & ACTION_MODE_SWIPE_MASK) >> (ACTION_STATE_SWIPE * DIRECTION_FLAG_COUNT);
+        int swipeDir;
+        if (Math.abs(mDx) > Math.abs(mDy)) {
+            if ((swipeDir = checkHorizontalSwipe(viewHolder, flags)) > 0) {
+                // if swipe dir is not in original flags, it should be the relative direction
+                if ((originalFlags & swipeDir) == 0) {
+                    // convert to relative
+                    return Callback.convertToRelativeDirection(swipeDir,
+                            mRecyclerView.getLayoutDirection());
+                }
+                return swipeDir;
+            }
+            if ((swipeDir = checkVerticalSwipe(viewHolder, flags)) > 0) {
+                return swipeDir;
+            }
+        } else {
+            if ((swipeDir = checkVerticalSwipe(viewHolder, flags)) > 0) {
+                return swipeDir;
+            }
+            if ((swipeDir = checkHorizontalSwipe(viewHolder, flags)) > 0) {
+                // if swipe dir is not in original flags, it should be the relative direction
+                if ((originalFlags & swipeDir) == 0) {
+                    // convert to relative
+                    return Callback.convertToRelativeDirection(swipeDir,
+                            mRecyclerView.getLayoutDirection());
+                }
+                return swipeDir;
+            }
+        }
+        return 0;
+    }
+
+    private int checkHorizontalSwipe(ViewHolder viewHolder, int flags) {
+        if ((flags & (LEFT | RIGHT)) != 0) {
+            final int dirFlag = mDx > 0 ? RIGHT : LEFT;
+            if (mVelocityTracker != null && mActivePointerId > -1) {
+                mVelocityTracker.computeCurrentVelocity(PIXELS_PER_SECOND,
+                        mCallback.getSwipeVelocityThreshold(mMaxSwipeVelocity));
+                final float xVelocity = mVelocityTracker.getXVelocity(mActivePointerId);
+                final float yVelocity = mVelocityTracker.getYVelocity(mActivePointerId);
+                final int velDirFlag = xVelocity > 0f ? RIGHT : LEFT;
+                final float absXVelocity = Math.abs(xVelocity);
+                if ((velDirFlag & flags) != 0 && dirFlag == velDirFlag
+                        && absXVelocity >= mCallback.getSwipeEscapeVelocity(mSwipeEscapeVelocity)
+                        && absXVelocity > Math.abs(yVelocity)) {
+                    return velDirFlag;
+                }
+            }
+
+            final float threshold = mRecyclerView.getWidth() * mCallback
+                    .getSwipeThreshold(viewHolder);
+
+            if ((flags & dirFlag) != 0 && Math.abs(mDx) > threshold) {
+                return dirFlag;
+            }
+        }
+        return 0;
+    }
+
+    private int checkVerticalSwipe(ViewHolder viewHolder, int flags) {
+        if ((flags & (UP | DOWN)) != 0) {
+            final int dirFlag = mDy > 0 ? DOWN : UP;
+            if (mVelocityTracker != null && mActivePointerId > -1) {
+                mVelocityTracker.computeCurrentVelocity(PIXELS_PER_SECOND,
+                        mCallback.getSwipeVelocityThreshold(mMaxSwipeVelocity));
+                final float xVelocity = mVelocityTracker.getXVelocity(mActivePointerId);
+                final float yVelocity = mVelocityTracker.getYVelocity(mActivePointerId);
+                final int velDirFlag = yVelocity > 0f ? DOWN : UP;
+                final float absYVelocity = Math.abs(yVelocity);
+                if ((velDirFlag & flags) != 0 && velDirFlag == dirFlag
+                        && absYVelocity >= mCallback.getSwipeEscapeVelocity(mSwipeEscapeVelocity)
+                        && absYVelocity > Math.abs(xVelocity)) {
+                    return velDirFlag;
+                }
+            }
+
+            final float threshold = mRecyclerView.getHeight() * mCallback
+                    .getSwipeThreshold(viewHolder);
+            if ((flags & dirFlag) != 0 && Math.abs(mDy) > threshold) {
+                return dirFlag;
+            }
+        }
+        return 0;
+    }
+
+    private void addChildDrawingOrderCallback() {
+        if (Build.VERSION.SDK_INT >= 21) {
+            return; // we use elevation on Lollipop
+        }
+        if (mChildDrawingOrderCallback == null) {
+            mChildDrawingOrderCallback = new RecyclerView.ChildDrawingOrderCallback() {
+                @Override
+                public int onGetChildDrawingOrder(int childCount, int i) {
+                    if (mOverdrawChild == null) {
+                        return i;
+                    }
+                    int childPosition = mOverdrawChildPosition;
+                    if (childPosition == -1) {
+                        childPosition = mRecyclerView.indexOfChild(mOverdrawChild);
+                        mOverdrawChildPosition = childPosition;
+                    }
+                    if (i == childCount - 1) {
+                        return childPosition;
+                    }
+                    return i < childPosition ? i : i + 1;
+                }
+            };
+        }
+        mRecyclerView.setChildDrawingOrderCallback(mChildDrawingOrderCallback);
+    }
+
+    void removeChildDrawingOrderCallbackIfNecessary(View view) {
+        if (view == mOverdrawChild) {
+            mOverdrawChild = null;
+            // only remove if we've added
+            if (mChildDrawingOrderCallback != null) {
+                mRecyclerView.setChildDrawingOrderCallback(null);
+            }
+        }
+    }
+
+    /**
+     * An interface which can be implemented by LayoutManager for better integration with
+     * {@link ItemTouchHelper}.
+     */
+    public interface ViewDropHandler {
+
+        /**
+         * Called by the {@link ItemTouchHelper} after a View is dropped over another View.
+         * <p>
+         * A LayoutManager should implement this interface to get ready for the upcoming move
+         * operation.
+         * <p>
+         * For example, LinearLayoutManager sets up a "scrollToPositionWithOffset" calls so that
+         * the View under drag will be used as an anchor View while calculating the next layout,
+         * making layout stay consistent.
+         *
+         * @param view   The View which is being dragged. It is very likely that user is still
+         *               dragging this View so there might be other
+         *               {@link #prepareForDrop(View, View, int, int)} after this one.
+         * @param target The target view which is being dropped on.
+         * @param x      The <code>left</code> offset of the View that is being dragged. This value
+         *               includes the movement caused by the user.
+         * @param y      The <code>top</code> offset of the View that is being dragged. This value
+         *               includes the movement caused by the user.
+         */
+        void prepareForDrop(View view, View target, int x, int y);
+    }
+
+    /**
+     * This class is the contract between ItemTouchHelper and your application. It lets you control
+     * which touch behaviors are enabled per each ViewHolder and also receive callbacks when user
+     * performs these actions.
+     * <p>
+     * To control which actions user can take on each view, you should override
+     * {@link #getMovementFlags(RecyclerView, ViewHolder)} and return appropriate set
+     * of direction flags. ({@link #LEFT}, {@link #RIGHT}, {@link #START}, {@link #END},
+     * {@link #UP}, {@link #DOWN}). You can use
+     * {@link #makeMovementFlags(int, int)} to easily construct it. Alternatively, you can use
+     * {@link SimpleCallback}.
+     * <p>
+     * If user drags an item, ItemTouchHelper will call
+     * {@link Callback#onMove(RecyclerView, ViewHolder, ViewHolder)
+     * onMove(recyclerView, dragged, target)}.
+     * Upon receiving this callback, you should move the item from the old position
+     * ({@code dragged.getAdapterPosition()}) to new position ({@code target.getAdapterPosition()})
+     * in your adapter and also call {@link RecyclerView.Adapter#notifyItemMoved(int, int)}.
+     * To control where a View can be dropped, you can override
+     * {@link #canDropOver(RecyclerView, ViewHolder, ViewHolder)}. When a
+     * dragging View overlaps multiple other views, Callback chooses the closest View with which
+     * dragged View might have changed positions. Although this approach works for many use cases,
+     * if you have a custom LayoutManager, you can override
+     * {@link #chooseDropTarget(ViewHolder, java.util.List, int, int)} to select a
+     * custom drop target.
+     * <p>
+     * When a View is swiped, ItemTouchHelper animates it until it goes out of bounds, then calls
+     * {@link #onSwiped(ViewHolder, int)}. At this point, you should update your
+     * adapter (e.g. remove the item) and call related Adapter#notify event.
+     */
+    @SuppressWarnings("UnusedParameters")
+    public abstract static class Callback {
+
+        public static final int DEFAULT_DRAG_ANIMATION_DURATION = 200;
+
+        public static final int DEFAULT_SWIPE_ANIMATION_DURATION = 250;
+
+        static final int RELATIVE_DIR_FLAGS = START | END
+                | ((START | END) << DIRECTION_FLAG_COUNT)
+                | ((START | END) << (2 * DIRECTION_FLAG_COUNT));
+
+        private static final ItemTouchUIUtil sUICallback = new ItemTouchUIUtilImpl();
+
+        private static final int ABS_HORIZONTAL_DIR_FLAGS = LEFT | RIGHT
+                | ((LEFT | RIGHT) << DIRECTION_FLAG_COUNT)
+                | ((LEFT | RIGHT) << (2 * DIRECTION_FLAG_COUNT));
+
+        private static final Interpolator sDragScrollInterpolator = new Interpolator() {
+            @Override
+            public float getInterpolation(float t) {
+                return t * t * t * t * t;
+            }
+        };
+
+        private static final Interpolator sDragViewScrollCapInterpolator = new Interpolator() {
+            @Override
+            public float getInterpolation(float t) {
+                t -= 1.0f;
+                return t * t * t * t * t + 1.0f;
+            }
+        };
+
+        /**
+         * Drag scroll speed keeps accelerating until this many milliseconds before being capped.
+         */
+        private static final long DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000;
+
+        private int mCachedMaxScrollSpeed = -1;
+
+        /**
+         * Returns the {@link ItemTouchUIUtil} that is used by the {@link Callback} class for
+         * visual
+         * changes on Views in response to user interactions. {@link ItemTouchUIUtil} has different
+         * implementations for different platform versions.
+         * <p>
+         * By default, {@link Callback} applies these changes on
+         * {@link RecyclerView.ViewHolder#itemView}.
+         * <p>
+         * For example, if you have a use case where you only want the text to move when user
+         * swipes over the view, you can do the following:
+         * <pre>
+         *     public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder){
+         *         getDefaultUIUtil().clearView(((ItemTouchViewHolder) viewHolder).textView);
+         *     }
+         *     public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
+         *         if (viewHolder != null){
+         *             getDefaultUIUtil().onSelected(((ItemTouchViewHolder) viewHolder).textView);
+         *         }
+         *     }
+         *     public void onChildDraw(Canvas c, RecyclerView recyclerView,
+         *             RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState,
+         *             boolean isCurrentlyActive) {
+         *         getDefaultUIUtil().onDraw(c, recyclerView,
+         *                 ((ItemTouchViewHolder) viewHolder).textView, dX, dY,
+         *                 actionState, isCurrentlyActive);
+         *         return true;
+         *     }
+         *     public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
+         *             RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState,
+         *             boolean isCurrentlyActive) {
+         *         getDefaultUIUtil().onDrawOver(c, recyclerView,
+         *                 ((ItemTouchViewHolder) viewHolder).textView, dX, dY,
+         *                 actionState, isCurrentlyActive);
+         *         return true;
+         *     }
+         * </pre>
+         *
+         * @return The {@link ItemTouchUIUtil} instance that is used by the {@link Callback}
+         */
+        public static ItemTouchUIUtil getDefaultUIUtil() {
+            return sUICallback;
+        }
+
+        /**
+         * Replaces a movement direction with its relative version by taking layout direction into
+         * account.
+         *
+         * @param flags           The flag value that include any number of movement flags.
+         * @param layoutDirection The layout direction of the View. Can be obtained from
+         *                        {@link View#getLayoutDirection()}.
+         * @return Updated flags which uses relative flags ({@link #START}, {@link #END}) instead
+         * of {@link #LEFT}, {@link #RIGHT}.
+         * @see #convertToAbsoluteDirection(int, int)
+         */
+        public static int convertToRelativeDirection(int flags, int layoutDirection) {
+            int masked = flags & ABS_HORIZONTAL_DIR_FLAGS;
+            if (masked == 0) {
+                return flags; // does not have any abs flags, good.
+            }
+            flags &= ~masked; //remove left / right.
+            if (layoutDirection == View.LAYOUT_DIRECTION_LTR) {
+                // no change. just OR with 2 bits shifted mask and return
+                flags |= masked << 2; // START is 2 bits after LEFT, END is 2 bits after RIGHT.
+                return flags;
+            } else {
+                // add RIGHT flag as START
+                flags |= ((masked << 1) & ~ABS_HORIZONTAL_DIR_FLAGS);
+                // first clean RIGHT bit then add LEFT flag as END
+                flags |= ((masked << 1) & ABS_HORIZONTAL_DIR_FLAGS) << 2;
+            }
+            return flags;
+        }
+
+        /**
+         * Convenience method to create movement flags.
+         * <p>
+         * For instance, if you want to let your items be drag & dropped vertically and swiped
+         * left to be dismissed, you can call this method with:
+         * <code>makeMovementFlags(UP | DOWN, LEFT);</code>
+         *
+         * @param dragFlags  The directions in which the item can be dragged.
+         * @param swipeFlags The directions in which the item can be swiped.
+         * @return Returns an integer composed of the given drag and swipe flags.
+         */
+        public static int makeMovementFlags(int dragFlags, int swipeFlags) {
+            return makeFlag(ACTION_STATE_IDLE, swipeFlags | dragFlags)
+                    | makeFlag(ACTION_STATE_SWIPE, swipeFlags)
+                    | makeFlag(ACTION_STATE_DRAG, dragFlags);
+        }
+
+        /**
+         * Shifts the given direction flags to the offset of the given action state.
+         *
+         * @param actionState The action state you want to get flags in. Should be one of
+         *                    {@link #ACTION_STATE_IDLE}, {@link #ACTION_STATE_SWIPE} or
+         *                    {@link #ACTION_STATE_DRAG}.
+         * @param directions  The direction flags. Can be composed from {@link #UP}, {@link #DOWN},
+         *                    {@link #RIGHT}, {@link #LEFT} {@link #START} and {@link #END}.
+         * @return And integer that represents the given directions in the provided actionState.
+         */
+        public static int makeFlag(int actionState, int directions) {
+            return directions << (actionState * DIRECTION_FLAG_COUNT);
+        }
+
+        /**
+         * Should return a composite flag which defines the enabled move directions in each state
+         * (idle, swiping, dragging).
+         * <p>
+         * Instead of composing this flag manually, you can use {@link #makeMovementFlags(int,
+         * int)}
+         * or {@link #makeFlag(int, int)}.
+         * <p>
+         * This flag is composed of 3 sets of 8 bits, where first 8 bits are for IDLE state, next
+         * 8 bits are for SWIPE state and third 8 bits are for DRAG state.
+         * Each 8 bit sections can be constructed by simply OR'ing direction flags defined in
+         * {@link ItemTouchHelper}.
+         * <p>
+         * For example, if you want it to allow swiping LEFT and RIGHT but only allow starting to
+         * swipe by swiping RIGHT, you can return:
+         * <pre>
+         *      makeFlag(ACTION_STATE_IDLE, RIGHT) | makeFlag(ACTION_STATE_SWIPE, LEFT | RIGHT);
+         * </pre>
+         * This means, allow right movement while IDLE and allow right and left movement while
+         * swiping.
+         *
+         * @param recyclerView The RecyclerView to which ItemTouchHelper is attached.
+         * @param viewHolder   The ViewHolder for which the movement information is necessary.
+         * @return flags specifying which movements are allowed on this ViewHolder.
+         * @see #makeMovementFlags(int, int)
+         * @see #makeFlag(int, int)
+         */
+        public abstract int getMovementFlags(RecyclerView recyclerView,
+                ViewHolder viewHolder);
+
+        /**
+         * Converts a given set of flags to absolution direction which means {@link #START} and
+         * {@link #END} are replaced with {@link #LEFT} and {@link #RIGHT} depending on the layout
+         * direction.
+         *
+         * @param flags           The flag value that include any number of movement flags.
+         * @param layoutDirection The layout direction of the RecyclerView.
+         * @return Updated flags which includes only absolute direction values.
+         */
+        public int convertToAbsoluteDirection(int flags, int layoutDirection) {
+            int masked = flags & RELATIVE_DIR_FLAGS;
+            if (masked == 0) {
+                return flags; // does not have any relative flags, good.
+            }
+            flags &= ~masked; //remove start / end
+            if (layoutDirection == View.LAYOUT_DIRECTION_LTR) {
+                // no change. just OR with 2 bits shifted mask and return
+                flags |= masked >> 2; // START is 2 bits after LEFT, END is 2 bits after RIGHT.
+                return flags;
+            } else {
+                // add START flag as RIGHT
+                flags |= ((masked >> 1) & ~RELATIVE_DIR_FLAGS);
+                // first clean start bit then add END flag as LEFT
+                flags |= ((masked >> 1) & RELATIVE_DIR_FLAGS) >> 2;
+            }
+            return flags;
+        }
+
+        final int getAbsoluteMovementFlags(RecyclerView recyclerView,
+                ViewHolder viewHolder) {
+            final int flags = getMovementFlags(recyclerView, viewHolder);
+            return convertToAbsoluteDirection(flags, recyclerView.getLayoutDirection());
+        }
+
+        boolean hasDragFlag(RecyclerView recyclerView, ViewHolder viewHolder) {
+            final int flags = getAbsoluteMovementFlags(recyclerView, viewHolder);
+            return (flags & ACTION_MODE_DRAG_MASK) != 0;
+        }
+
+        boolean hasSwipeFlag(RecyclerView recyclerView,
+                ViewHolder viewHolder) {
+            final int flags = getAbsoluteMovementFlags(recyclerView, viewHolder);
+            return (flags & ACTION_MODE_SWIPE_MASK) != 0;
+        }
+
+        /**
+         * Return true if the current ViewHolder can be dropped over the the target ViewHolder.
+         * <p>
+         * This method is used when selecting drop target for the dragged View. After Views are
+         * eliminated either via bounds check or via this method, resulting set of views will be
+         * passed to {@link #chooseDropTarget(ViewHolder, java.util.List, int, int)}.
+         * <p>
+         * Default implementation returns true.
+         *
+         * @param recyclerView The RecyclerView to which ItemTouchHelper is attached to.
+         * @param current      The ViewHolder that user is dragging.
+         * @param target       The ViewHolder which is below the dragged ViewHolder.
+         * @return True if the dragged ViewHolder can be replaced with the target ViewHolder, false
+         * otherwise.
+         */
+        public boolean canDropOver(RecyclerView recyclerView, ViewHolder current,
+                ViewHolder target) {
+            return true;
+        }
+
+        /**
+         * Called when ItemTouchHelper wants to move the dragged item from its old position to
+         * the new position.
+         * <p>
+         * If this method returns true, ItemTouchHelper assumes {@code viewHolder} has been moved
+         * to the adapter position of {@code target} ViewHolder
+         * ({@link ViewHolder#getAdapterPosition()
+         * ViewHolder#getAdapterPosition()}).
+         * <p>
+         * If you don't support drag & drop, this method will never be called.
+         *
+         * @param recyclerView The RecyclerView to which ItemTouchHelper is attached to.
+         * @param viewHolder   The ViewHolder which is being dragged by the user.
+         * @param target       The ViewHolder over which the currently active item is being
+         *                     dragged.
+         * @return True if the {@code viewHolder} has been moved to the adapter position of
+         * {@code target}.
+         * @see #onMoved(RecyclerView, ViewHolder, int, ViewHolder, int, int, int)
+         */
+        public abstract boolean onMove(RecyclerView recyclerView,
+                ViewHolder viewHolder, ViewHolder target);
+
+        /**
+         * Returns whether ItemTouchHelper should start a drag and drop operation if an item is
+         * long pressed.
+         * <p>
+         * Default value returns true but you may want to disable this if you want to start
+         * dragging on a custom view touch using {@link #startDrag(ViewHolder)}.
+         *
+         * @return True if ItemTouchHelper should start dragging an item when it is long pressed,
+         * false otherwise. Default value is <code>true</code>.
+         * @see #startDrag(ViewHolder)
+         */
+        public boolean isLongPressDragEnabled() {
+            return true;
+        }
+
+        /**
+         * Returns whether ItemTouchHelper should start a swipe operation if a pointer is swiped
+         * over the View.
+         * <p>
+         * Default value returns true but you may want to disable this if you want to start
+         * swiping on a custom view touch using {@link #startSwipe(ViewHolder)}.
+         *
+         * @return True if ItemTouchHelper should start swiping an item when user swipes a pointer
+         * over the View, false otherwise. Default value is <code>true</code>.
+         * @see #startSwipe(ViewHolder)
+         */
+        public boolean isItemViewSwipeEnabled() {
+            return true;
+        }
+
+        /**
+         * When finding views under a dragged view, by default, ItemTouchHelper searches for views
+         * that overlap with the dragged View. By overriding this method, you can extend or shrink
+         * the search box.
+         *
+         * @return The extra margin to be added to the hit box of the dragged View.
+         */
+        public int getBoundingBoxMargin() {
+            return 0;
+        }
+
+        /**
+         * Returns the fraction that the user should move the View to be considered as swiped.
+         * The fraction is calculated with respect to RecyclerView's bounds.
+         * <p>
+         * Default value is .5f, which means, to swipe a View, user must move the View at least
+         * half of RecyclerView's width or height, depending on the swipe direction.
+         *
+         * @param viewHolder The ViewHolder that is being dragged.
+         * @return A float value that denotes the fraction of the View size. Default value
+         * is .5f .
+         */
+        public float getSwipeThreshold(ViewHolder viewHolder) {
+            return .5f;
+        }
+
+        /**
+         * Returns the fraction that the user should move the View to be considered as it is
+         * dragged. After a view is moved this amount, ItemTouchHelper starts checking for Views
+         * below it for a possible drop.
+         *
+         * @param viewHolder The ViewHolder that is being dragged.
+         * @return A float value that denotes the fraction of the View size. Default value is
+         * .5f .
+         */
+        public float getMoveThreshold(ViewHolder viewHolder) {
+            return .5f;
+        }
+
+        /**
+         * Defines the minimum velocity which will be considered as a swipe action by the user.
+         * <p>
+         * You can increase this value to make it harder to swipe or decrease it to make it easier.
+         * Keep in mind that ItemTouchHelper also checks the perpendicular velocity and makes sure
+         * current direction velocity is larger then the perpendicular one. Otherwise, user's
+         * movement is ambiguous. You can change the threshold by overriding
+         * {@link #getSwipeVelocityThreshold(float)}.
+         * <p>
+         * The velocity is calculated in pixels per second.
+         * <p>
+         * The default framework value is passed as a parameter so that you can modify it with a
+         * multiplier.
+         *
+         * @param defaultValue The default value (in pixels per second) used by the
+         *                     ItemTouchHelper.
+         * @return The minimum swipe velocity. The default implementation returns the
+         * <code>defaultValue</code> parameter.
+         * @see #getSwipeVelocityThreshold(float)
+         * @see #getSwipeThreshold(ViewHolder)
+         */
+        public float getSwipeEscapeVelocity(float defaultValue) {
+            return defaultValue;
+        }
+
+        /**
+         * Defines the maximum velocity ItemTouchHelper will ever calculate for pointer movements.
+         * <p>
+         * To consider a movement as swipe, ItemTouchHelper requires it to be larger than the
+         * perpendicular movement. If both directions reach to the max threshold, none of them will
+         * be considered as a swipe because it is usually an indication that user rather tried to
+         * scroll then swipe.
+         * <p>
+         * The velocity is calculated in pixels per second.
+         * <p>
+         * You can customize this behavior by changing this method. If you increase the value, it
+         * will be easier for the user to swipe diagonally and if you decrease the value, user will
+         * need to make a rather straight finger movement to trigger a swipe.
+         *
+         * @param defaultValue The default value(in pixels per second) used by the ItemTouchHelper.
+         * @return The velocity cap for pointer movements. The default implementation returns the
+         * <code>defaultValue</code> parameter.
+         * @see #getSwipeEscapeVelocity(float)
+         */
+        public float getSwipeVelocityThreshold(float defaultValue) {
+            return defaultValue;
+        }
+
+        /**
+         * Called by ItemTouchHelper to select a drop target from the list of ViewHolders that
+         * are under the dragged View.
+         * <p>
+         * Default implementation filters the View with which dragged item have changed position
+         * in the drag direction. For instance, if the view is dragged UP, it compares the
+         * <code>view.getTop()</code> of the two views before and after drag started. If that value
+         * is different, the target view passes the filter.
+         * <p>
+         * Among these Views which pass the test, the one closest to the dragged view is chosen.
+         * <p>
+         * This method is called on the main thread every time user moves the View. If you want to
+         * override it, make sure it does not do any expensive operations.
+         *
+         * @param selected    The ViewHolder being dragged by the user.
+         * @param dropTargets The list of ViewHolder that are under the dragged View and
+         *                    candidate as a drop.
+         * @param curX        The updated left value of the dragged View after drag translations
+         *                    are applied. This value does not include margins added by
+         *                    {@link RecyclerView.ItemDecoration}s.
+         * @param curY        The updated top value of the dragged View after drag translations
+         *                    are applied. This value does not include margins added by
+         *                    {@link RecyclerView.ItemDecoration}s.
+         * @return A ViewHolder to whose position the dragged ViewHolder should be
+         * moved to.
+         */
+        public ViewHolder chooseDropTarget(ViewHolder selected,
+                List<ViewHolder> dropTargets, int curX, int curY) {
+            int right = curX + selected.itemView.getWidth();
+            int bottom = curY + selected.itemView.getHeight();
+            ViewHolder winner = null;
+            int winnerScore = -1;
+            final int dx = curX - selected.itemView.getLeft();
+            final int dy = curY - selected.itemView.getTop();
+            final int targetsSize = dropTargets.size();
+            for (int i = 0; i < targetsSize; i++) {
+                final ViewHolder target = dropTargets.get(i);
+                if (dx > 0) {
+                    int diff = target.itemView.getRight() - right;
+                    if (diff < 0 && target.itemView.getRight() > selected.itemView.getRight()) {
+                        final int score = Math.abs(diff);
+                        if (score > winnerScore) {
+                            winnerScore = score;
+                            winner = target;
+                        }
+                    }
+                }
+                if (dx < 0) {
+                    int diff = target.itemView.getLeft() - curX;
+                    if (diff > 0 && target.itemView.getLeft() < selected.itemView.getLeft()) {
+                        final int score = Math.abs(diff);
+                        if (score > winnerScore) {
+                            winnerScore = score;
+                            winner = target;
+                        }
+                    }
+                }
+                if (dy < 0) {
+                    int diff = target.itemView.getTop() - curY;
+                    if (diff > 0 && target.itemView.getTop() < selected.itemView.getTop()) {
+                        final int score = Math.abs(diff);
+                        if (score > winnerScore) {
+                            winnerScore = score;
+                            winner = target;
+                        }
+                    }
+                }
+
+                if (dy > 0) {
+                    int diff = target.itemView.getBottom() - bottom;
+                    if (diff < 0 && target.itemView.getBottom() > selected.itemView.getBottom()) {
+                        final int score = Math.abs(diff);
+                        if (score > winnerScore) {
+                            winnerScore = score;
+                            winner = target;
+                        }
+                    }
+                }
+            }
+            return winner;
+        }
+
+        /**
+         * Called when a ViewHolder is swiped by the user.
+         * <p>
+         * If you are returning relative directions ({@link #START} , {@link #END}) from the
+         * {@link #getMovementFlags(RecyclerView, ViewHolder)} method, this method
+         * will also use relative directions. Otherwise, it will use absolute directions.
+         * <p>
+         * If you don't support swiping, this method will never be called.
+         * <p>
+         * ItemTouchHelper will keep a reference to the View until it is detached from
+         * RecyclerView.
+         * As soon as it is detached, ItemTouchHelper will call
+         * {@link #clearView(RecyclerView, ViewHolder)}.
+         *
+         * @param viewHolder The ViewHolder which has been swiped by the user.
+         * @param direction  The direction to which the ViewHolder is swiped. It is one of
+         *                   {@link #UP}, {@link #DOWN},
+         *                   {@link #LEFT} or {@link #RIGHT}. If your
+         *                   {@link #getMovementFlags(RecyclerView, ViewHolder)}
+         *                   method
+         *                   returned relative flags instead of {@link #LEFT} / {@link #RIGHT};
+         *                   `direction` will be relative as well. ({@link #START} or {@link
+         *                   #END}).
+         */
+        public abstract void onSwiped(ViewHolder viewHolder, int direction);
+
+        /**
+         * Called when the ViewHolder swiped or dragged by the ItemTouchHelper is changed.
+         * <p/>
+         * If you override this method, you should call super.
+         *
+         * @param viewHolder  The new ViewHolder that is being swiped or dragged. Might be null if
+         *                    it is cleared.
+         * @param actionState One of {@link ItemTouchHelper#ACTION_STATE_IDLE},
+         *                    {@link ItemTouchHelper#ACTION_STATE_SWIPE} or
+         *                    {@link ItemTouchHelper#ACTION_STATE_DRAG}.
+         * @see #clearView(RecyclerView, RecyclerView.ViewHolder)
+         */
+        public void onSelectedChanged(ViewHolder viewHolder, int actionState) {
+            if (viewHolder != null) {
+                sUICallback.onSelected(viewHolder.itemView);
+            }
+        }
+
+        private int getMaxDragScroll(RecyclerView recyclerView) {
+            if (mCachedMaxScrollSpeed == -1) {
+                mCachedMaxScrollSpeed = recyclerView.getResources().getDimensionPixelSize(
+                        R.dimen.item_touch_helper_max_drag_scroll_per_frame);
+            }
+            return mCachedMaxScrollSpeed;
+        }
+
+        /**
+         * Called when {@link #onMove(RecyclerView, ViewHolder, ViewHolder)} returns true.
+         * <p>
+         * ItemTouchHelper does not create an extra Bitmap or View while dragging, instead, it
+         * modifies the existing View. Because of this reason, it is important that the View is
+         * still part of the layout after it is moved. This may not work as intended when swapped
+         * Views are close to RecyclerView bounds or there are gaps between them (e.g. other Views
+         * which were not eligible for dropping over).
+         * <p>
+         * This method is responsible to give necessary hint to the LayoutManager so that it will
+         * keep the View in visible area. For example, for LinearLayoutManager, this is as simple
+         * as calling {@link LinearLayoutManager#scrollToPositionWithOffset(int, int)}.
+         *
+         * Default implementation calls {@link RecyclerView#scrollToPosition(int)} if the View's
+         * new position is likely to be out of bounds.
+         * <p>
+         * It is important to ensure the ViewHolder will stay visible as otherwise, it might be
+         * removed by the LayoutManager if the move causes the View to go out of bounds. In that
+         * case, drag will end prematurely.
+         *
+         * @param recyclerView The RecyclerView controlled by the ItemTouchHelper.
+         * @param viewHolder   The ViewHolder under user's control.
+         * @param fromPos      The previous adapter position of the dragged item (before it was
+         *                     moved).
+         * @param target       The ViewHolder on which the currently active item has been dropped.
+         * @param toPos        The new adapter position of the dragged item.
+         * @param x            The updated left value of the dragged View after drag translations
+         *                     are applied. This value does not include margins added by
+         *                     {@link RecyclerView.ItemDecoration}s.
+         * @param y            The updated top value of the dragged View after drag translations
+         *                     are applied. This value does not include margins added by
+         *                     {@link RecyclerView.ItemDecoration}s.
+         */
+        public void onMoved(final RecyclerView recyclerView,
+                final ViewHolder viewHolder, int fromPos, final ViewHolder target, int toPos, int x,
+                int y) {
+            final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
+            if (layoutManager instanceof ViewDropHandler) {
+                ((ViewDropHandler) layoutManager).prepareForDrop(viewHolder.itemView,
+                        target.itemView, x, y);
+                return;
+            }
+
+            // if layout manager cannot handle it, do some guesswork
+            if (layoutManager.canScrollHorizontally()) {
+                final int minLeft = layoutManager.getDecoratedLeft(target.itemView);
+                if (minLeft <= recyclerView.getPaddingLeft()) {
+                    recyclerView.scrollToPosition(toPos);
+                }
+                final int maxRight = layoutManager.getDecoratedRight(target.itemView);
+                if (maxRight >= recyclerView.getWidth() - recyclerView.getPaddingRight()) {
+                    recyclerView.scrollToPosition(toPos);
+                }
+            }
+
+            if (layoutManager.canScrollVertically()) {
+                final int minTop = layoutManager.getDecoratedTop(target.itemView);
+                if (minTop <= recyclerView.getPaddingTop()) {
+                    recyclerView.scrollToPosition(toPos);
+                }
+                final int maxBottom = layoutManager.getDecoratedBottom(target.itemView);
+                if (maxBottom >= recyclerView.getHeight() - recyclerView.getPaddingBottom()) {
+                    recyclerView.scrollToPosition(toPos);
+                }
+            }
+        }
+
+        void onDraw(Canvas c, RecyclerView parent, ViewHolder selected,
+                List<ItemTouchHelper.RecoverAnimation> recoverAnimationList,
+                int actionState, float dX, float dY) {
+            final int recoverAnimSize = recoverAnimationList.size();
+            for (int i = 0; i < recoverAnimSize; i++) {
+                final ItemTouchHelper.RecoverAnimation anim = recoverAnimationList.get(i);
+                anim.update();
+                final int count = c.save();
+                onChildDraw(c, parent, anim.mViewHolder, anim.mX, anim.mY, anim.mActionState,
+                        false);
+                c.restoreToCount(count);
+            }
+            if (selected != null) {
+                final int count = c.save();
+                onChildDraw(c, parent, selected, dX, dY, actionState, true);
+                c.restoreToCount(count);
+            }
+        }
+
+        void onDrawOver(Canvas c, RecyclerView parent, ViewHolder selected,
+                List<ItemTouchHelper.RecoverAnimation> recoverAnimationList,
+                int actionState, float dX, float dY) {
+            final int recoverAnimSize = recoverAnimationList.size();
+            for (int i = 0; i < recoverAnimSize; i++) {
+                final ItemTouchHelper.RecoverAnimation anim = recoverAnimationList.get(i);
+                final int count = c.save();
+                onChildDrawOver(c, parent, anim.mViewHolder, anim.mX, anim.mY, anim.mActionState,
+                        false);
+                c.restoreToCount(count);
+            }
+            if (selected != null) {
+                final int count = c.save();
+                onChildDrawOver(c, parent, selected, dX, dY, actionState, true);
+                c.restoreToCount(count);
+            }
+            boolean hasRunningAnimation = false;
+            for (int i = recoverAnimSize - 1; i >= 0; i--) {
+                final RecoverAnimation anim = recoverAnimationList.get(i);
+                if (anim.mEnded && !anim.mIsPendingCleanup) {
+                    recoverAnimationList.remove(i);
+                } else if (!anim.mEnded) {
+                    hasRunningAnimation = true;
+                }
+            }
+            if (hasRunningAnimation) {
+                parent.invalidate();
+            }
+        }
+
+        /**
+         * Called by the ItemTouchHelper when the user interaction with an element is over and it
+         * also completed its animation.
+         * <p>
+         * This is a good place to clear all changes on the View that was done in
+         * {@link #onSelectedChanged(RecyclerView.ViewHolder, int)},
+         * {@link #onChildDraw(Canvas, RecyclerView, ViewHolder, float, float, int,
+         * boolean)} or
+         * {@link #onChildDrawOver(Canvas, RecyclerView, ViewHolder, float, float, int, boolean)}.
+         *
+         * @param recyclerView The RecyclerView which is controlled by the ItemTouchHelper.
+         * @param viewHolder   The View that was interacted by the user.
+         */
+        public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
+            sUICallback.clearView(viewHolder.itemView);
+        }
+
+        /**
+         * Called by ItemTouchHelper on RecyclerView's onDraw callback.
+         * <p>
+         * If you would like to customize how your View's respond to user interactions, this is
+         * a good place to override.
+         * <p>
+         * Default implementation translates the child by the given <code>dX</code>,
+         * <code>dY</code>.
+         * ItemTouchHelper also takes care of drawing the child after other children if it is being
+         * dragged. This is done using child re-ordering mechanism. On platforms prior to L, this
+         * is
+         * achieved via {@link android.view.ViewGroup#getChildDrawingOrder(int, int)} and on L
+         * and after, it changes View's elevation value to be greater than all other children.)
+         *
+         * @param c                 The canvas which RecyclerView is drawing its children
+         * @param recyclerView      The RecyclerView to which ItemTouchHelper is attached to
+         * @param viewHolder        The ViewHolder which is being interacted by the User or it was
+         *                          interacted and simply animating to its original position
+         * @param dX                The amount of horizontal displacement caused by user's action
+         * @param dY                The amount of vertical displacement caused by user's action
+         * @param actionState       The type of interaction on the View. Is either {@link
+         *                          #ACTION_STATE_DRAG} or {@link #ACTION_STATE_SWIPE}.
+         * @param isCurrentlyActive True if this view is currently being controlled by the user or
+         *                          false it is simply animating back to its original state.
+         * @see #onChildDrawOver(Canvas, RecyclerView, ViewHolder, float, float, int,
+         * boolean)
+         */
+        public void onChildDraw(Canvas c, RecyclerView recyclerView,
+                ViewHolder viewHolder,
+                float dX, float dY, int actionState, boolean isCurrentlyActive) {
+            sUICallback.onDraw(c, recyclerView, viewHolder.itemView, dX, dY, actionState,
+                    isCurrentlyActive);
+        }
+
+        /**
+         * Called by ItemTouchHelper on RecyclerView's onDraw callback.
+         * <p>
+         * If you would like to customize how your View's respond to user interactions, this is
+         * a good place to override.
+         * <p>
+         * Default implementation translates the child by the given <code>dX</code>,
+         * <code>dY</code>.
+         * ItemTouchHelper also takes care of drawing the child after other children if it is being
+         * dragged. This is done using child re-ordering mechanism. On platforms prior to L, this
+         * is
+         * achieved via {@link android.view.ViewGroup#getChildDrawingOrder(int, int)} and on L
+         * and after, it changes View's elevation value to be greater than all other children.)
+         *
+         * @param c                 The canvas which RecyclerView is drawing its children
+         * @param recyclerView      The RecyclerView to which ItemTouchHelper is attached to
+         * @param viewHolder        The ViewHolder which is being interacted by the User or it was
+         *                          interacted and simply animating to its original position
+         * @param dX                The amount of horizontal displacement caused by user's action
+         * @param dY                The amount of vertical displacement caused by user's action
+         * @param actionState       The type of interaction on the View. Is either {@link
+         *                          #ACTION_STATE_DRAG} or {@link #ACTION_STATE_SWIPE}.
+         * @param isCurrentlyActive True if this view is currently being controlled by the user or
+         *                          false it is simply animating back to its original state.
+         * @see #onChildDrawOver(Canvas, RecyclerView, ViewHolder, float, float, int,
+         * boolean)
+         */
+        public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
+                ViewHolder viewHolder,
+                float dX, float dY, int actionState, boolean isCurrentlyActive) {
+            sUICallback.onDrawOver(c, recyclerView, viewHolder.itemView, dX, dY, actionState,
+                    isCurrentlyActive);
+        }
+
+        /**
+         * Called by the ItemTouchHelper when user action finished on a ViewHolder and now the View
+         * will be animated to its final position.
+         * <p>
+         * Default implementation uses ItemAnimator's duration values. If
+         * <code>animationType</code> is {@link #ANIMATION_TYPE_DRAG}, it returns
+         * {@link RecyclerView.ItemAnimator#getMoveDuration()}, otherwise, it returns
+         * {@link RecyclerView.ItemAnimator#getRemoveDuration()}. If RecyclerView does not have
+         * any {@link RecyclerView.ItemAnimator} attached, this method returns
+         * {@code DEFAULT_DRAG_ANIMATION_DURATION} or {@code DEFAULT_SWIPE_ANIMATION_DURATION}
+         * depending on the animation type.
+         *
+         * @param recyclerView  The RecyclerView to which the ItemTouchHelper is attached to.
+         * @param animationType The type of animation. Is one of {@link #ANIMATION_TYPE_DRAG},
+         *                      {@link #ANIMATION_TYPE_SWIPE_CANCEL} or
+         *                      {@link #ANIMATION_TYPE_SWIPE_SUCCESS}.
+         * @param animateDx     The horizontal distance that the animation will offset
+         * @param animateDy     The vertical distance that the animation will offset
+         * @return The duration for the animation
+         */
+        public long getAnimationDuration(RecyclerView recyclerView, int animationType,
+                float animateDx, float animateDy) {
+            final RecyclerView.ItemAnimator itemAnimator = recyclerView.getItemAnimator();
+            if (itemAnimator == null) {
+                return animationType == ANIMATION_TYPE_DRAG ? DEFAULT_DRAG_ANIMATION_DURATION
+                        : DEFAULT_SWIPE_ANIMATION_DURATION;
+            } else {
+                return animationType == ANIMATION_TYPE_DRAG ? itemAnimator.getMoveDuration()
+                        : itemAnimator.getRemoveDuration();
+            }
+        }
+
+        /**
+         * Called by the ItemTouchHelper when user is dragging a view out of bounds.
+         * <p>
+         * You can override this method to decide how much RecyclerView should scroll in response
+         * to this action. Default implementation calculates a value based on the amount of View
+         * out of bounds and the time it spent there. The longer user keeps the View out of bounds,
+         * the faster the list will scroll. Similarly, the larger portion of the View is out of
+         * bounds, the faster the RecyclerView will scroll.
+         *
+         * @param recyclerView        The RecyclerView instance to which ItemTouchHelper is
+         *                            attached to.
+         * @param viewSize            The total size of the View in scroll direction, excluding
+         *                            item decorations.
+         * @param viewSizeOutOfBounds The total size of the View that is out of bounds. This value
+         *                            is negative if the View is dragged towards left or top edge.
+         * @param totalSize           The total size of RecyclerView in the scroll direction.
+         * @param msSinceStartScroll  The time passed since View is kept out of bounds.
+         * @return The amount that RecyclerView should scroll. Keep in mind that this value will
+         * be passed to {@link RecyclerView#scrollBy(int, int)} method.
+         */
+        public int interpolateOutOfBoundsScroll(RecyclerView recyclerView,
+                int viewSize, int viewSizeOutOfBounds,
+                int totalSize, long msSinceStartScroll) {
+            final int maxScroll = getMaxDragScroll(recyclerView);
+            final int absOutOfBounds = Math.abs(viewSizeOutOfBounds);
+            final int direction = (int) Math.signum(viewSizeOutOfBounds);
+            // might be negative if other direction
+            float outOfBoundsRatio = Math.min(1f, 1f * absOutOfBounds / viewSize);
+            final int cappedScroll = (int) (direction * maxScroll
+                    * sDragViewScrollCapInterpolator.getInterpolation(outOfBoundsRatio));
+            final float timeRatio;
+            if (msSinceStartScroll > DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS) {
+                timeRatio = 1f;
+            } else {
+                timeRatio = (float) msSinceStartScroll / DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS;
+            }
+            final int value = (int) (cappedScroll * sDragScrollInterpolator
+                    .getInterpolation(timeRatio));
+            if (value == 0) {
+                return viewSizeOutOfBounds > 0 ? 1 : -1;
+            }
+            return value;
+        }
+    }
+
+    /**
+     * A simple wrapper to the default Callback which you can construct with drag and swipe
+     * directions and this class will handle the flag callbacks. You should still override onMove
+     * or
+     * onSwiped depending on your use case.
+     *
+     * <pre>
+     * ItemTouchHelper mIth = new ItemTouchHelper(
+     *     new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN,
+     *         ItemTouchHelper.LEFT) {
+     *         public abstract boolean onMove(RecyclerView recyclerView,
+     *             ViewHolder viewHolder, ViewHolder target) {
+     *             final int fromPos = viewHolder.getAdapterPosition();
+     *             final int toPos = target.getAdapterPosition();
+     *             // move item in `fromPos` to `toPos` in adapter.
+     *             return true;// true if moved, false otherwise
+     *         }
+     *         public void onSwiped(ViewHolder viewHolder, int direction) {
+     *             // remove from adapter
+     *         }
+     * });
+     * </pre>
+     */
+    public abstract static class SimpleCallback extends Callback {
+
+        private int mDefaultSwipeDirs;
+
+        private int mDefaultDragDirs;
+
+        /**
+         * Creates a Callback for the given drag and swipe allowance. These values serve as
+         * defaults
+         * and if you want to customize behavior per ViewHolder, you can override
+         * {@link #getSwipeDirs(RecyclerView, ViewHolder)}
+         * and / or {@link #getDragDirs(RecyclerView, ViewHolder)}.
+         *
+         * @param dragDirs  Binary OR of direction flags in which the Views can be dragged. Must be
+         *                  composed of {@link #LEFT}, {@link #RIGHT}, {@link #START}, {@link
+         *                  #END},
+         *                  {@link #UP} and {@link #DOWN}.
+         * @param swipeDirs Binary OR of direction flags in which the Views can be swiped. Must be
+         *                  composed of {@link #LEFT}, {@link #RIGHT}, {@link #START}, {@link
+         *                  #END},
+         *                  {@link #UP} and {@link #DOWN}.
+         */
+        public SimpleCallback(int dragDirs, int swipeDirs) {
+            mDefaultSwipeDirs = swipeDirs;
+            mDefaultDragDirs = dragDirs;
+        }
+
+        /**
+         * Updates the default swipe directions. For example, you can use this method to toggle
+         * certain directions depending on your use case.
+         *
+         * @param defaultSwipeDirs Binary OR of directions in which the ViewHolders can be swiped.
+         */
+        public void setDefaultSwipeDirs(int defaultSwipeDirs) {
+            mDefaultSwipeDirs = defaultSwipeDirs;
+        }
+
+        /**
+         * Updates the default drag directions. For example, you can use this method to toggle
+         * certain directions depending on your use case.
+         *
+         * @param defaultDragDirs Binary OR of directions in which the ViewHolders can be dragged.
+         */
+        public void setDefaultDragDirs(int defaultDragDirs) {
+            mDefaultDragDirs = defaultDragDirs;
+        }
+
+        /**
+         * Returns the swipe directions for the provided ViewHolder.
+         * Default implementation returns the swipe directions that was set via constructor or
+         * {@link #setDefaultSwipeDirs(int)}.
+         *
+         * @param recyclerView The RecyclerView to which the ItemTouchHelper is attached to.
+         * @param viewHolder   The RecyclerView for which the swipe direction is queried.
+         * @return A binary OR of direction flags.
+         */
+        public int getSwipeDirs(RecyclerView recyclerView, ViewHolder viewHolder) {
+            return mDefaultSwipeDirs;
+        }
+
+        /**
+         * Returns the drag directions for the provided ViewHolder.
+         * Default implementation returns the drag directions that was set via constructor or
+         * {@link #setDefaultDragDirs(int)}.
+         *
+         * @param recyclerView The RecyclerView to which the ItemTouchHelper is attached to.
+         * @param viewHolder   The RecyclerView for which the swipe direction is queried.
+         * @return A binary OR of direction flags.
+         */
+        public int getDragDirs(RecyclerView recyclerView, ViewHolder viewHolder) {
+            return mDefaultDragDirs;
+        }
+
+        @Override
+        public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) {
+            return makeMovementFlags(getDragDirs(recyclerView, viewHolder),
+                    getSwipeDirs(recyclerView, viewHolder));
+        }
+    }
+
+    private class ItemTouchHelperGestureListener extends GestureDetector.SimpleOnGestureListener {
+
+        ItemTouchHelperGestureListener() {
+        }
+
+        @Override
+        public boolean onDown(MotionEvent e) {
+            return true;
+        }
+
+        @Override
+        public void onLongPress(MotionEvent e) {
+            View child = findChildView(e);
+            if (child != null) {
+                ViewHolder vh = mRecyclerView.getChildViewHolder(child);
+                if (vh != null) {
+                    if (!mCallback.hasDragFlag(mRecyclerView, vh)) {
+                        return;
+                    }
+                    int pointerId = e.getPointerId(0);
+                    // Long press is deferred.
+                    // Check w/ active pointer id to avoid selecting after motion
+                    // event is canceled.
+                    if (pointerId == mActivePointerId) {
+                        final int index = e.findPointerIndex(mActivePointerId);
+                        final float x = e.getX(index);
+                        final float y = e.getY(index);
+                        mInitialTouchX = x;
+                        mInitialTouchY = y;
+                        mDx = mDy = 0f;
+                        if (DEBUG) {
+                            Log.d(TAG,
+                                    "onlong press: x:" + mInitialTouchX + ",y:" + mInitialTouchY);
+                        }
+                        if (mCallback.isLongPressDragEnabled()) {
+                            select(vh, ACTION_STATE_DRAG);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    private class RecoverAnimation implements Animator.AnimatorListener {
+
+        final float mStartDx;
+
+        final float mStartDy;
+
+        final float mTargetX;
+
+        final float mTargetY;
+
+        final ViewHolder mViewHolder;
+
+        final int mActionState;
+
+        private final ValueAnimator mValueAnimator;
+
+        final int mAnimationType;
+
+        public boolean mIsPendingCleanup;
+
+        float mX;
+
+        float mY;
+
+        // if user starts touching a recovering view, we put it into interaction mode again,
+        // instantly.
+        boolean mOverridden = false;
+
+        boolean mEnded = false;
+
+        private float mFraction;
+
+        RecoverAnimation(ViewHolder viewHolder, int animationType,
+                int actionState, float startDx, float startDy, float targetX, float targetY) {
+            mActionState = actionState;
+            mAnimationType = animationType;
+            mViewHolder = viewHolder;
+            mStartDx = startDx;
+            mStartDy = startDy;
+            mTargetX = targetX;
+            mTargetY = targetY;
+            mValueAnimator = ValueAnimator.ofFloat(0f, 1f);
+            mValueAnimator.addUpdateListener(
+                    new ValueAnimator.AnimatorUpdateListener() {
+                        @Override
+                        public void onAnimationUpdate(ValueAnimator animation) {
+                            setFraction(animation.getAnimatedFraction());
+                        }
+                    });
+            mValueAnimator.setTarget(viewHolder.itemView);
+            mValueAnimator.addListener(this);
+            setFraction(0f);
+        }
+
+        public void setDuration(long duration) {
+            mValueAnimator.setDuration(duration);
+        }
+
+        public void start() {
+            mViewHolder.setIsRecyclable(false);
+            mValueAnimator.start();
+        }
+
+        public void cancel() {
+            mValueAnimator.cancel();
+        }
+
+        public void setFraction(float fraction) {
+            mFraction = fraction;
+        }
+
+        /**
+         * We run updates on onDraw method but use the fraction from animator callback.
+         * This way, we can sync translate x/y values w/ the animators to avoid one-off frames.
+         */
+        public void update() {
+            if (mStartDx == mTargetX) {
+                mX = mViewHolder.itemView.getTranslationX();
+            } else {
+                mX = mStartDx + mFraction * (mTargetX - mStartDx);
+            }
+            if (mStartDy == mTargetY) {
+                mY = mViewHolder.itemView.getTranslationY();
+            } else {
+                mY = mStartDy + mFraction * (mTargetY - mStartDy);
+            }
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            if (!mEnded) {
+                mViewHolder.setIsRecyclable(true);
+            }
+            mEnded = true;
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+            setFraction(1f); //make sure we recover the view's state.
+        }
+
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+
+        }
+    }
+}
diff --git a/core/java/com/android/internal/widget/helper/ItemTouchUIUtil.java b/core/java/com/android/internal/widget/helper/ItemTouchUIUtil.java
new file mode 100644
index 0000000..e368a6d
--- /dev/null
+++ b/core/java/com/android/internal/widget/helper/ItemTouchUIUtil.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget.helper;
+
+import android.graphics.Canvas;
+import android.view.View;
+
+import com.android.internal.widget.RecyclerView;
+
+/**
+ * Utility class for {@link ItemTouchHelper} which handles item transformations for different
+ * API versions.
+ * <p/>
+ * This class has methods that map to {@link ItemTouchHelper.Callback}'s drawing methods. Default
+ * implementations in {@link ItemTouchHelper.Callback} call these methods with
+ * {@link RecyclerView.ViewHolder#itemView} and {@link ItemTouchUIUtil} makes necessary changes
+ * on the View depending on the API level. You can access the instance of {@link ItemTouchUIUtil}
+ * via {@link ItemTouchHelper.Callback#getDefaultUIUtil()} and call its methods with the children
+ * of ViewHolder that you want to apply default effects.
+ *
+ * @see ItemTouchHelper.Callback#getDefaultUIUtil()
+ */
+public interface ItemTouchUIUtil {
+
+    /**
+     * The default implementation for {@link ItemTouchHelper.Callback#onChildDraw(Canvas,
+     * RecyclerView, RecyclerView.ViewHolder, float, float, int, boolean)}
+     */
+    void onDraw(Canvas c, RecyclerView recyclerView, View view,
+            float dX, float dY, int actionState, boolean isCurrentlyActive);
+
+    /**
+     * The default implementation for {@link ItemTouchHelper.Callback#onChildDrawOver(Canvas,
+     * RecyclerView, RecyclerView.ViewHolder, float, float, int, boolean)}
+     */
+    void onDrawOver(Canvas c, RecyclerView recyclerView, View view,
+            float dX, float dY, int actionState, boolean isCurrentlyActive);
+
+    /**
+     * The default implementation for {@link ItemTouchHelper.Callback#clearView(RecyclerView,
+     * RecyclerView.ViewHolder)}
+     */
+    void clearView(View view);
+
+    /**
+     * The default implementation for {@link ItemTouchHelper.Callback#onSelectedChanged(
+     * RecyclerView.ViewHolder, int)}
+     */
+    void onSelected(View view);
+}
+
diff --git a/core/java/com/android/internal/widget/helper/ItemTouchUIUtilImpl.java b/core/java/com/android/internal/widget/helper/ItemTouchUIUtilImpl.java
new file mode 100644
index 0000000..0de240b
--- /dev/null
+++ b/core/java/com/android/internal/widget/helper/ItemTouchUIUtilImpl.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.widget.helper;
+
+import android.graphics.Canvas;
+import android.view.View;
+
+import com.android.internal.R;
+import com.android.internal.widget.RecyclerView;
+
+/**
+ * Package private class to keep implementations. Putting them inside ItemTouchUIUtil makes them
+ * public API, which is not desired in this case.
+ */
+class ItemTouchUIUtilImpl implements ItemTouchUIUtil {
+    @Override
+    public void onDraw(Canvas c, RecyclerView recyclerView, View view,
+            float dX, float dY, int actionState, boolean isCurrentlyActive) {
+        if (isCurrentlyActive) {
+            Object originalElevation = view.getTag(
+                    R.id.item_touch_helper_previous_elevation);
+            if (originalElevation == null) {
+                originalElevation = view.getElevation();
+                float newElevation = 1f + findMaxElevation(recyclerView, view);
+                view.setElevation(newElevation);
+                view.setTag(R.id.item_touch_helper_previous_elevation,
+                        originalElevation);
+            }
+        }
+        view.setTranslationX(dX);
+        view.setTranslationY(dY);
+    }
+
+    private float findMaxElevation(RecyclerView recyclerView, View itemView) {
+        final int childCount = recyclerView.getChildCount();
+        float max = 0;
+        for (int i = 0; i < childCount; i++) {
+            final View child = recyclerView.getChildAt(i);
+            if (child == itemView) {
+                continue;
+            }
+            final float elevation = child.getElevation();
+            if (elevation > max) {
+                max = elevation;
+            }
+        }
+        return max;
+    }
+
+    @Override
+    public void clearView(View view) {
+        final Object tag = view.getTag(
+                R.id.item_touch_helper_previous_elevation);
+        if (tag != null && tag instanceof Float) {
+            view.setElevation((Float) tag);
+        }
+        view.setTag(R.id.item_touch_helper_previous_elevation, null);
+        view.setTranslationX(0f);
+        view.setTranslationY(0f);
+    }
+
+    @Override
+    public void onSelected(View view) {
+    }
+
+    @Override
+    public void onDrawOver(Canvas c, RecyclerView recyclerView,
+            View view, float dX, float dY, int actionState, boolean isCurrentlyActive) {
+    }
+}
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 2504e54..ac8f413 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -258,9 +258,9 @@
     gListClassInfo.mGet = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
     gListClassInfo.mSize = GetMethodIDOrDie(env, listClass, "size", "()I");
 
-    jclass axisClass = FindClassOrDie(env, "android/graphics/FontListParser$Axis");
-    gAxisClassInfo.mTag = GetFieldIDOrDie(env, axisClass, "tag", "I");
-    gAxisClassInfo.mStyleValue = GetFieldIDOrDie(env, axisClass, "styleValue", "F");
+    jclass axisClass = FindClassOrDie(env, "android/text/FontConfig$Axis");
+    gAxisClassInfo.mTag = GetFieldIDOrDie(env, axisClass, "mTag", "I");
+    gAxisClassInfo.mStyleValue = GetFieldIDOrDie(env, axisClass, "mStyleValue", "F");
 
     return err;
 }
diff --git a/core/jni/android/graphics/FontUtils.cpp b/core/jni/android/graphics/FontUtils.cpp
new file mode 100644
index 0000000..91fec2a
--- /dev/null
+++ b/core/jni/android/graphics/FontUtils.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#include "FontUtils.h"
+
+#include "JNIHelp.h"
+#include <core_jni_helpers.h>
+
+namespace android {
+namespace {
+
+static struct {
+    jmethodID mGet;
+    jmethodID mSize;
+} gListClassInfo;
+
+static struct {
+    jfieldID mTag;
+    jfieldID mStyleValue;
+} gAxisClassInfo;
+
+}  // namespace
+
+jint ListHelper::size() const {
+    return mEnv->CallIntMethod(mList, gListClassInfo.mSize);
+}
+
+jobject ListHelper::get(jint index) const {
+    return mEnv->CallObjectMethod(mList, gListClassInfo.mGet, index);
+}
+
+jint AxisHelper::getTag() const {
+    return mEnv->GetIntField(mAxis, gAxisClassInfo.mTag);
+}
+
+jfloat AxisHelper::getStyleValue() const {
+    return mEnv->GetFloatField(mAxis, gAxisClassInfo.mStyleValue);
+}
+
+void init_FontUtils(JNIEnv* env) {
+    jclass listClass = FindClassOrDie(env, "java/util/List");
+    gListClassInfo.mGet = GetMethodIDOrDie(env, listClass, "get", "(I)Ljava/lang/Object;");
+    gListClassInfo.mSize = GetMethodIDOrDie(env, listClass, "size", "()I");
+
+    jclass axisClass = FindClassOrDie(env, "android/text/FontConfig$Axis");
+    gAxisClassInfo.mTag = GetFieldIDOrDie(env, axisClass, "mTag", "I");
+    gAxisClassInfo.mStyleValue = GetFieldIDOrDie(env, axisClass, "mStyleValue", "F");
+}
+
+}  // namespace android
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 7c01dea..87c2b25 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -8477,4 +8477,14 @@
         <attr name="font" format="reference" />
         <attr name="fontWeight" format="integer" />
     </declare-styleable>
+
+    <!-- @hide -->
+    <declare-styleable name="RecyclerView">
+        <attr name="layoutManager" format="string" />
+        <attr name="orientation" />
+        <attr name="descendantFocusability" />
+        <attr name="spanCount" format="integer"/>
+        <attr name="reverseLayout" format="boolean" />
+        <attr name="stackFromEnd" format="boolean" />
+    </declare-styleable>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index bd19521..e6358a3 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -509,4 +509,10 @@
     <dimen name="tooltip_precise_anchor_threshold">96dp</dimen>
     <!-- Extra tooltip offset used when anchoring to the mouse/touch position -->
     <dimen name="tooltip_precise_anchor_extra_offset">8dp</dimen>
+
+    <!-- The max amount of scroll ItemTouchHelper will trigger if dragged view is out of
+         RecyclerView's bounds.-->
+    <dimen name="item_touch_helper_max_drag_scroll_per_frame">20dp</dimen>
+    <dimen name="item_touch_helper_swipe_escape_velocity">120dp</dimen>
+    <dimen name="item_touch_helper_swipe_escape_max_velocity">800dp</dimen>
 </resources>
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index 5547706..f351b70 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -131,4 +131,7 @@
   <item type="id" name="cross_task_transition" />
 
   <item type="id" name="accessibilityActionClickOnClickableSpan" />
+
+  <!-- ItemTouchHelper uses this id to save a View's original elevation. -->
+  <item type="id" name="item_touch_helper_previous_elevation"/>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index c370ef7..6eb3bee 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2806,4 +2806,10 @@
   <java-symbol type="string" name="disable_accessibility_shortcut" />
   <java-symbol type="string" name="leave_accessibility_shortcut_on" />
   <java-symbol type="string" name="config_defaultAccessibilityService" />
+
+  <!-- com.android.internal.widget.RecyclerView -->
+  <java-symbol type="id" name="item_touch_helper_previous_elevation"/>
+  <java-symbol type="dimen" name="item_touch_helper_max_drag_scroll_per_frame"/>
+  <java-symbol type="dimen" name="item_touch_helper_swipe_escape_velocity"/>
+  <java-symbol type="dimen" name="item_touch_helper_swipe_escape_max_velocity"/>
 </resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index cba485a..91ce7a4 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1168,6 +1168,7 @@
         <activity android:name="android.app.EmptyActivity">
         </activity>
         <activity android:name="com.android.internal.app.ChooserWrapperActivity"/>
+        <activity android:name="com.android.internal.app.ResolverWrapperActivity"/>
 
         <receiver android:name="android.app.activity.AbortReceiver">
             <intent-filter android:priority="1">
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index aab4698..daebf88 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -222,7 +222,7 @@
     private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
         List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
         for (int i = 0; i < numberOfResults; i++) {
-            infoList.add(ChooserDataProvider.createResolvedComponentInfo(i));
+            infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
         }
         return infoList;
     }
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
index 41016e1..c446f3c 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java
@@ -24,11 +24,10 @@
 
 import static org.mockito.Mockito.mock;
 
-
-/**
- * Simple wrapper around chooser activity to be able to initiate it under test
- */
 public class ChooserWrapperActivity extends ChooserActivity {
+    /*
+     * Simple wrapper around chooser activity to be able to initiate it under test
+     */
     static final OverrideData sOverrides = new OverrideData();
     private UsageStatsManager mUsm;
 
@@ -94,4 +93,4 @@
             resolverListController = mock(ResolverListController.class);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
new file mode 100644
index 0000000..84b844a
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.android.internal.app;
+
+import com.android.internal.R;
+import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+import android.app.usage.UsageStats;
+import android.app.usage.UsageStatsManager;
+import android.content.Intent;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import static android.os.SystemClock.sleep;
+import static android.support.test.espresso.Espresso.onView;
+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.isDisplayed;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static com.android.internal.app.ResolverWrapperActivity.sOverrides;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Resolver activity instrumentation tests
+ */
+@RunWith(AndroidJUnit4.class)
+public class ResolverActivityTest {
+    @Rule
+    public ActivityTestRule<ResolverWrapperActivity> mActivityRule =
+            new ActivityTestRule<>(ResolverWrapperActivity.class, false,
+                    false);
+
+    @Before
+    public void cleanOverrideData() {
+        sOverrides.reset();
+    }
+
+    @Test
+    public void twoOptionsAndUserSelectsOne() throws InterruptedException {
+        Intent sendIntent = createSendImageIntent();
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+
+        final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
+        waitForIdle();
+
+        assertThat(activity.getAdapter().getCount(), is(2));
+
+        ResolveInfo[] chosen = new ResolveInfo[1];
+        sOverrides.onSafelyStartCallback = targetInfo -> {
+            chosen[0] = targetInfo.getResolveInfo();
+            return true;
+        };
+
+        ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
+        onView(withText(toChoose.activityInfo.name))
+                .perform(click());
+        onView(withId(R.id.button_once))
+                .perform(click());
+        waitForIdle();
+        assertThat(chosen[0], is(toChoose));
+    }
+
+    @Test
+    public void hasLastChosenActivity() throws Exception {
+        Intent sendIntent = createSendImageIntent();
+        List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
+
+        when(sOverrides.resolverListController.getResolversForIntent(Mockito.anyBoolean(),
+                Mockito.anyBoolean(),
+                Mockito.isA(List.class))).thenReturn(resolvedComponentInfos);
+        when(sOverrides.resolverListController.getLastChosen())
+                .thenReturn(resolvedComponentInfos.get(0).getResolveInfoAt(0));
+
+        final ResolverWrapperActivity activity = mActivityRule.launchActivity(sendIntent);
+        waitForIdle();
+
+        // The other entry is filtered to the last used slot
+        assertThat(activity.getAdapter().getCount(), is(1));
+
+        ResolveInfo[] chosen = new ResolveInfo[1];
+        sOverrides.onSafelyStartCallback = targetInfo -> {
+            chosen[0] = targetInfo.getResolveInfo();
+            return true;
+        };
+
+        ResolveInfo toChoose = resolvedComponentInfos.get(0).getResolveInfoAt(0);
+        onView(withId(R.id.title)).perform(click());
+        onView(withId(R.id.button_once))
+                .perform(click());
+        waitForIdle();
+        assertThat(chosen[0], is(toChoose));
+    }
+
+    private Intent createSendImageIntent() {
+        Intent sendIntent = new Intent();
+        sendIntent.setAction(Intent.ACTION_SEND);
+        sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
+        sendIntent.setType("image/jpeg");
+        return sendIntent;
+    }
+
+    private List<ResolvedComponentInfo> createResolvedComponentsForTest(int numberOfResults) {
+        List<ResolvedComponentInfo> infoList = new ArrayList<>(numberOfResults);
+        for (int i = 0; i < numberOfResults; i++) {
+            infoList.add(ResolverDataProvider.createResolvedComponentInfo(i));
+        }
+        return infoList;
+    }
+
+    private void waitForIdle() {
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserDataProvider.java b/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
similarity index 94%
rename from core/tests/coretests/src/com/android/internal/app/ChooserDataProvider.java
rename to core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
index f6f63f1..ae06306 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserDataProvider.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverDataProvider.java
@@ -22,16 +22,15 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ResolveInfo;
 import android.os.UserHandle;
-import android.service.chooser.ChooserTarget;
 
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
- * Utility class used by chooser tests to create mock data
+ * Utility class used by resolver tests to create mock data
  */
-class ChooserDataProvider {
+class ResolverDataProvider {
 
     static ResolverActivity.ResolvedComponentInfo createResolvedComponentInfo(int i) {
         return new ResolverActivity.ResolvedComponentInfo(createComponentName(i),
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java
new file mode 100644
index 0000000..163211e
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverWrapperActivity.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.app.usage.UsageStatsManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+
+import java.util.function.Function;
+
+import static org.mockito.Mockito.mock;
+
+
+/*
+ * Simple wrapper around chooser activity to be able to initiate it under test
+ */
+public class ResolverWrapperActivity extends ResolverActivity {
+    static final OverrideData sOverrides = new OverrideData();
+    private UsageStatsManager mUsm;
+
+    ResolveListAdapter getAdapter() {
+        return mAdapter;
+    }
+
+    @Override
+    public boolean isVoiceInteraction() {
+        if (sOverrides.isVoiceInteraction != null) {
+            return sOverrides.isVoiceInteraction;
+        }
+        return super.isVoiceInteraction();
+    }
+
+    @Override
+    public void safelyStartActivity(TargetInfo cti) {
+        if (sOverrides.onSafelyStartCallback != null &&
+                sOverrides.onSafelyStartCallback.apply(cti)) {
+            return;
+        }
+        super.safelyStartActivity(cti);
+    }
+
+    @Override
+    protected ResolverListController createListController() {
+        return sOverrides.resolverListController;
+    }
+
+    @Override
+    public PackageManager getPackageManager() {
+        if (sOverrides.createPackageManager != null) {
+            return sOverrides.createPackageManager.apply(super.getPackageManager());
+        }
+        return super.getPackageManager();
+    }
+
+    /**
+     * We cannot directly mock the activity created since instrumentation creates it.
+     * <p>
+     * Instead, we use static instances of this object to modify behavior.
+     */
+    static class OverrideData {
+        @SuppressWarnings("Since15")
+        public Function<PackageManager, PackageManager> createPackageManager;
+        public Function<TargetInfo, Boolean> onSafelyStartCallback;
+        public ResolverListController resolverListController;
+        public Boolean isVoiceInteraction;
+
+        public void reset() {
+            onSafelyStartCallback = null;
+            isVoiceInteraction = null;
+            createPackageManager = null;
+            resolverListController = mock(ResolverListController.class);
+        }
+    }
+}
\ No newline at end of file
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index cd5071e8..8673e0b 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -17,6 +17,7 @@
 package android.graphics;
 
 import android.content.res.AssetManager;
+import android.text.FontConfig;
 import android.util.Log;
 
 import java.io.FileInputStream;
@@ -80,7 +81,7 @@
         }
     }
 
-    public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List<FontListParser.Axis> axes,
+    public boolean addFontWeightStyle(ByteBuffer font, int ttcIndex, List<FontConfig.Axis> axes,
             int weight, boolean style) {
         return nAddFontWeightStyle(mNativePtr, font, ttcIndex, axes, weight, style);
     }
@@ -94,7 +95,7 @@
     private static native void nUnrefFamily(long nativePtr);
     private static native boolean nAddFont(long nativeFamily, ByteBuffer font, int ttcIndex);
     private static native boolean nAddFontWeightStyle(long nativeFamily, ByteBuffer font,
-            int ttcIndex, List<FontListParser.Axis> listOfAxis,
+            int ttcIndex, List<FontConfig.Axis> listOfAxis,
             int weight, boolean isItalic);
     private static native boolean nAddFontFromAssetManager(long nativeFamily, AssetManager mgr,
             String path, int cookie, boolean isAsset);
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 9490436..4ec564a 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -16,6 +16,7 @@
 
 package android.graphics;
 
+import android.text.FontConfig;
 import android.util.Xml;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -36,61 +37,8 @@
  */
 public class FontListParser {
 
-    public static class Config {
-        Config() {
-            families = new ArrayList<Family>();
-            aliases = new ArrayList<Alias>();
-        }
-        public List<Family> families;
-        public List<Alias> aliases;
-    }
-
-    public static class Axis {
-        Axis(int tag, float styleValue) {
-            this.tag = tag;
-            this.styleValue = styleValue;
-        }
-        public final int tag;
-        public final float styleValue;
-    }
-
-    public static class Font {
-        Font(String fontName, int ttcIndex, List<Axis> axes, int weight, boolean isItalic) {
-            this.fontName = fontName;
-            this.ttcIndex = ttcIndex;
-            this.axes = axes;
-            this.weight = weight;
-            this.isItalic = isItalic;
-        }
-        public String fontName;
-        public int ttcIndex;
-        public final List<Axis> axes;
-        public int weight;
-        public boolean isItalic;
-    }
-
-    public static class Alias {
-        public String name;
-        public String toName;
-        public int weight;
-    }
-
-    public static class Family {
-        public Family(String name, List<Font> fonts, String lang, String variant) {
-            this.name = name;
-            this.fonts = fonts;
-            this.lang = lang;
-            this.variant = variant;
-        }
-
-        public String name;
-        public List<Font> fonts;
-        public String lang;
-        public String variant;
-    }
-
     /* Parse fallback list (no names) */
-    public static Config parse(InputStream in) throws XmlPullParserException, IOException {
+    public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
         try {
             XmlPullParser parser = Xml.newPullParser();
             parser.setInput(in, null);
@@ -104,9 +52,9 @@
     // Note that a well-formed variation contains a four-character tag and a float as styleValue,
     // with spacers in between. The tag is enclosd either by double quotes or single quotes.
     @VisibleForTesting
-    public static Axis[] parseFontVariationSettings(String settings) {
+    public static FontConfig.Axis[] parseFontVariationSettings(String settings) {
         String[] settingList = settings.split(",");
-        ArrayList<Axis> axisList = new ArrayList<>();
+        ArrayList<FontConfig.Axis> axisList = new ArrayList<>();
         settingLoop:
         for (String setting : settingList) {
             int pos = 0;
@@ -148,9 +96,9 @@
             }
             int tag = makeTag(tagString.charAt(0), tagString.charAt(1), tagString.charAt(2),
                     tagString.charAt(3));
-            axisList.add(new Axis(tag, styleValue));
+            axisList.add(new FontConfig.Axis(tag, styleValue));
         }
-        return axisList.toArray(new Axis[axisList.size()]);
+        return axisList.toArray(new FontConfig.Axis[axisList.size()]);
     }
 
     @VisibleForTesting
@@ -162,17 +110,17 @@
         return c == ' ' || c == '\r' || c == '\t' || c == '\n';
     }
 
-    private static Config readFamilies(XmlPullParser parser)
+    private static FontConfig readFamilies(XmlPullParser parser)
             throws XmlPullParserException, IOException {
-        Config config = new Config();
+        FontConfig config = new FontConfig();
         parser.require(XmlPullParser.START_TAG, null, "familyset");
         while (parser.next() != XmlPullParser.END_TAG) {
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
             String tag = parser.getName();
             if (tag.equals("family")) {
-                config.families.add(readFamily(parser));
+                config.getFamilies().add(readFamily(parser));
             } else if (tag.equals("alias")) {
-                config.aliases.add(readAlias(parser));
+                config.getAliases().add(readAlias(parser));
             } else {
                 skip(parser);
             }
@@ -180,12 +128,12 @@
         return config;
     }
 
-    private static Family readFamily(XmlPullParser parser)
+    private static FontConfig.Family readFamily(XmlPullParser parser)
             throws XmlPullParserException, IOException {
         String name = parser.getAttributeValue(null, "name");
         String lang = parser.getAttributeValue(null, "lang");
         String variant = parser.getAttributeValue(null, "variant");
-        List<Font> fonts = new ArrayList<Font>();
+        List<FontConfig.Font> fonts = new ArrayList<FontConfig.Font>();
         while (parser.next() != XmlPullParser.END_TAG) {
             if (parser.getEventType() != XmlPullParser.START_TAG) continue;
             String tag = parser.getName();
@@ -195,18 +143,18 @@
                 skip(parser);
             }
         }
-        return new Family(name, fonts, lang, variant);
+        return new FontConfig.Family(name, fonts, lang, variant);
     }
 
     /** Matches leading and trailing XML whitespace. */
     private static final Pattern FILENAME_WHITESPACE_PATTERN =
             Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$");
 
-    private static Font readFont(XmlPullParser parser)
+    private static FontConfig.Font readFont(XmlPullParser parser)
             throws XmlPullParserException, IOException {
         String indexStr = parser.getAttributeValue(null, "index");
         int index = indexStr == null ? 0 : Integer.parseInt(indexStr);
-        List<Axis> axes = new ArrayList<Axis>();
+        List<FontConfig.Axis> axes = new ArrayList<FontConfig.Axis>();
         String weightStr = parser.getAttributeValue(null, "weight");
         int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
         boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
@@ -225,7 +173,7 @@
         }
         String fullFilename = "/system/fonts/" +
                 FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
-        return new Font(fullFilename, index, axes, weight, isItalic);
+        return new FontConfig.Font(fullFilename, index, axes, weight, isItalic);
     }
 
     /** The 'tag' attribute value is read as four character values between U+0020 and U+007E
@@ -239,7 +187,7 @@
     private static final Pattern STYLE_VALUE_PATTERN =
             Pattern.compile("-?(([0-9]+(\\.[0-9]+)?)|(\\.[0-9]+))");
 
-    private static Axis readAxis(XmlPullParser parser)
+    private static FontConfig.Axis readAxis(XmlPullParser parser)
             throws XmlPullParserException, IOException {
         int tag = 0;
         String tagStr = parser.getAttributeValue(null, "tag");
@@ -258,22 +206,22 @@
         }
 
         skip(parser);  // axis tag is empty, ignore any contents and consume end tag
-        return new Axis(tag, styleValue);
+        return new FontConfig.Axis(tag, styleValue);
     }
 
-    private static Alias readAlias(XmlPullParser parser)
+    private static FontConfig.Alias readAlias(XmlPullParser parser)
             throws XmlPullParserException, IOException {
-        Alias alias = new Alias();
-        alias.name = parser.getAttributeValue(null, "name");
-        alias.toName = parser.getAttributeValue(null, "to");
+        String name = parser.getAttributeValue(null, "name");
+        String toName = parser.getAttributeValue(null, "to");
         String weightStr = parser.getAttributeValue(null, "weight");
+        int weight;
         if (weightStr == null) {
-            alias.weight = 400;
+            weight = 400;
         } else {
-            alias.weight = Integer.parseInt(weightStr);
+            weight = Integer.parseInt(weightStr);
         }
         skip(parser);  // alias tag is empty, ignore any contents and consume end tag
-        return alias;
+        return new FontConfig.Alias(name, toName, weight);
     }
 
     private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index eebe538..0a349e9 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.content.res.AssetManager;
+import android.text.FontConfig;
 import android.util.Log;
 import android.util.LongSparseArray;
 import android.util.LruCache;
@@ -319,25 +320,25 @@
         mStyle = nativeGetStyle(ni);
     }
 
-    private static FontFamily makeFamilyFromParsed(FontListParser.Family family,
+    private static FontFamily makeFamilyFromParsed(FontConfig.Family family,
             Map<String, ByteBuffer> bufferForPath) {
-        FontFamily fontFamily = new FontFamily(family.lang, family.variant);
-        for (FontListParser.Font font : family.fonts) {
-            ByteBuffer fontBuffer = bufferForPath.get(font.fontName);
+        FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
+        for (FontConfig.Font font : family.getFonts()) {
+            ByteBuffer fontBuffer = bufferForPath.get(font.getFontName());
             if (fontBuffer == null) {
-                try (FileInputStream file = new FileInputStream(font.fontName)) {
+                try (FileInputStream file = new FileInputStream(font.getFontName())) {
                     FileChannel fileChannel = file.getChannel();
                     long fontSize = fileChannel.size();
                     fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
-                    bufferForPath.put(font.fontName, fontBuffer);
+                    bufferForPath.put(font.getFontName(), fontBuffer);
                 } catch (IOException e) {
-                    Log.e(TAG, "Error mapping font file " + font.fontName);
+                    Log.e(TAG, "Error mapping font file " + font.getFontName());
                     continue;
                 }
             }
-            if (!fontFamily.addFontWeightStyle(fontBuffer, font.ttcIndex, font.axes,
-                    font.weight, font.isItalic)) {
-                Log.e(TAG, "Error creating font " + font.fontName + "#" + font.ttcIndex);
+            if (!fontFamily.addFontWeightStyle(fontBuffer, font.getTtcIndex(), font.getAxes(),
+                    font.getWeight(), font.isItalic())) {
+                Log.e(TAG, "Error creating font " + font.getFontName() + "#" + font.getTtcIndex());
             }
         }
         return fontFamily;
@@ -354,16 +355,16 @@
         File configFilename = new File(systemFontConfigLocation, FONTS_CONFIG);
         try {
             FileInputStream fontsIn = new FileInputStream(configFilename);
-            FontListParser.Config fontConfig = FontListParser.parse(fontsIn);
+            FontConfig fontConfig = FontListParser.parse(fontsIn);
 
             Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>();
 
             List<FontFamily> familyList = new ArrayList<FontFamily>();
             // Note that the default typeface is always present in the fallback list;
             // this is an enhancement from pre-Minikin behavior.
-            for (int i = 0; i < fontConfig.families.size(); i++) {
-                FontListParser.Family f = fontConfig.families.get(i);
-                if (i == 0 || f.name == null) {
+            for (int i = 0; i < fontConfig.getFamilies().size(); i++) {
+                FontConfig.Family f = fontConfig.getFamilies().get(i);
+                if (i == 0 || f.getName() == null) {
                     familyList.add(makeFamilyFromParsed(f, bufferForPath));
                 }
             }
@@ -371,10 +372,10 @@
             setDefault(Typeface.createFromFamilies(sFallbackFonts));
 
             Map<String, Typeface> systemFonts = new HashMap<String, Typeface>();
-            for (int i = 0; i < fontConfig.families.size(); i++) {
+            for (int i = 0; i < fontConfig.getFamilies().size(); i++) {
                 Typeface typeface;
-                FontListParser.Family f = fontConfig.families.get(i);
-                if (f.name != null) {
+                FontConfig.Family f = fontConfig.getFamilies().get(i);
+                if (f.getName() != null) {
                     if (i == 0) {
                         // The first entry is the default typeface; no sense in
                         // duplicating the corresponding FontFamily.
@@ -384,17 +385,17 @@
                         FontFamily[] families = { fontFamily };
                         typeface = Typeface.createFromFamiliesWithDefault(families);
                     }
-                    systemFonts.put(f.name, typeface);
+                    systemFonts.put(f.getName(), typeface);
                 }
             }
-            for (FontListParser.Alias alias : fontConfig.aliases) {
-                Typeface base = systemFonts.get(alias.toName);
+            for (FontConfig.Alias alias : fontConfig.getAliases()) {
+                Typeface base = systemFonts.get(alias.getToName());
                 Typeface newFace = base;
-                int weight = alias.weight;
+                int weight = alias.getWeight();
                 if (weight != 400) {
                     newFace = new Typeface(nativeCreateWeightAlias(base.native_instance, weight));
                 }
-                systemFonts.put(alias.name, newFace);
+                systemFonts.put(alias.getName(), newFace);
             }
             sSystemFontMap = systemFonts;
 
diff --git a/graphics/tests/graphicstests/src/android/graphics/VariationParserTest.java b/graphics/tests/graphicstests/src/android/graphics/VariationParserTest.java
index d046c11..2b4e6c2 100644
--- a/graphics/tests/graphicstests/src/android/graphics/VariationParserTest.java
+++ b/graphics/tests/graphicstests/src/android/graphics/VariationParserTest.java
@@ -17,50 +17,53 @@
 package android.graphics;
 
 import android.test.suitebuilder.annotation.SmallTest;
+import android.text.FontConfig;
 import junit.framework.TestCase;
 
+import java.util.List;
+
 
 public class VariationParserTest extends TestCase {
 
     @SmallTest
     public void testParseFontVariationSetting() {
         int tag = FontListParser.makeTag('w', 'd', 't', 'h');
-        FontListParser.Axis[] axis = FontListParser.parseFontVariationSettings("'wdth' 1");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(1.0f, axis[0].styleValue);
+        FontConfig.Axis[] axis = FontListParser.parseFontVariationSettings("'wdth' 1");
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(1.0f, axis[0].getStyleValue());
 
         axis = FontListParser.parseFontVariationSettings("\"wdth\" 100");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(100.0f, axis[0].styleValue);
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(100.0f, axis[0].getStyleValue());
 
         axis = FontListParser.parseFontVariationSettings("   'wdth' 100");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(100.0f, axis[0].styleValue);
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(100.0f, axis[0].getStyleValue());
 
         axis = FontListParser.parseFontVariationSettings("\t'wdth' 0.5");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(0.5f, axis[0].styleValue);
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(0.5f, axis[0].getStyleValue());
 
         tag = FontListParser.makeTag('A', 'X', ' ', ' ');
         axis = FontListParser.parseFontVariationSettings("'AX  ' 1");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(1.0f, axis[0].styleValue);
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(1.0f, axis[0].getStyleValue());
 
         axis = FontListParser.parseFontVariationSettings("'AX  '\t1");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(1.0f, axis[0].styleValue);
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(1.0f, axis[0].getStyleValue());
 
         axis = FontListParser.parseFontVariationSettings("'AX  '\n1");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(1.0f, axis[0].styleValue);
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(1.0f, axis[0].getStyleValue());
 
         axis = FontListParser.parseFontVariationSettings("'AX  '\r1");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(1.0f, axis[0].styleValue);
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(1.0f, axis[0].getStyleValue());
 
         axis = FontListParser.parseFontVariationSettings("'AX  '\r\t\n 1");
-        assertEquals(tag, axis[0].tag);
-        assertEquals(1.0f, axis[0].styleValue);
+        assertEquals(tag, axis[0].getTag());
+        assertEquals(1.0f, axis[0].getStyleValue());
 
         // Test for invalid input
         axis = FontListParser.parseFontVariationSettings("");
@@ -87,26 +90,26 @@
 
     @SmallTest
     public void testParseFontVariationStyleSettings() {
-        FontListParser.Axis[] axis =
+        FontConfig.Axis[] axis =
                 FontListParser.parseFontVariationSettings("'wdth' 10,'AX  '\r1");
         int tag1 = FontListParser.makeTag('w', 'd', 't', 'h');
         int tag2 = FontListParser.makeTag('A', 'X', ' ', ' ');
-        assertEquals(tag1, axis[0].tag);
-        assertEquals(10.0f, axis[0].styleValue);
-        assertEquals(tag2, axis[1].tag);
-        assertEquals(1.0f, axis[1].styleValue);
+        assertEquals(tag1, axis[0].getTag());
+        assertEquals(10.0f, axis[0].getStyleValue());
+        assertEquals(tag2, axis[1].getTag());
+        assertEquals(1.0f, axis[1].getStyleValue());
 
         // Test only spacers are allowed before tag
         axis = FontListParser.parseFontVariationSettings("     'wdth' 10,ab'wdth' 1");
         tag1 = FontListParser.makeTag('w', 'd', 't', 'h');
-        assertEquals(tag1, axis[0].tag);
-        assertEquals(10.0f, axis[0].styleValue);
+        assertEquals(tag1, axis[0].getTag());
+        assertEquals(10.0f, axis[0].getStyleValue());
         assertEquals(1, axis.length);
     }
 
     @SmallTest
     public void testInvalidTagCharacters() {
-        FontListParser.Axis[] axis =
+        FontConfig.Axis[] axis =
                 FontListParser.parseFontVariationSettings("'\u0000\u0000\u0000\u0000' 10");
         assertEquals(0, axis.length);
         axis = FontListParser.parseFontVariationSettings("'\u3042\u3044\u3046\u3048' 10");
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index a53a55a..1d8b021 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -180,16 +180,18 @@
         }
     }
 
-    if (!backdrop.isEmpty()) {
-        // content node translation to catch up with backdrop
-        float dx = contentDrawBounds.left - backdrop.left;
-        float dy = contentDrawBounds.top - backdrop.top;
+    if (!nodes[1]->nothingToDraw()) {
+        if (!backdrop.isEmpty()) {
+            // content node translation to catch up with backdrop
+            float dx = contentDrawBounds.left - backdrop.left;
+            float dy = contentDrawBounds.top - backdrop.top;
 
-        Rect contentLocalClip = backdrop;
-        contentLocalClip.translate(dx, dy);
-        deferRenderNode(-dx, -dy, contentLocalClip, *nodes[1]);
-    } else {
-        deferRenderNode(*nodes[1]);
+            Rect contentLocalClip = backdrop;
+            contentLocalClip.translate(dx, dy);
+            deferRenderNode(-dx, -dy, contentLocalClip, *nodes[1]);
+        } else {
+            deferRenderNode(*nodes[1]);
+        }
     }
 
     // remaining overlay nodes, simply defer
diff --git a/libs/hwui/tests/common/LeakChecker.cpp b/libs/hwui/tests/common/LeakChecker.cpp
index d935382..8a0b64b 100644
--- a/libs/hwui/tests/common/LeakChecker.cpp
+++ b/libs/hwui/tests/common/LeakChecker.cpp
@@ -67,6 +67,12 @@
 }
 
 void LeakChecker::checkForLeaks() {
+    // TODO: Re-enable, disabled to workaround b/34586922
+    if ((true)) {
+        cout << "checkForLeaks disabled, see b/34586922" << endl;
+        return;
+    }
+
     // TODO: Until we can shutdown the RT thread we need to do this in
     // two passes as GetUnreachableMemory has limited insight into
     // thread-local caches so some leaks will not be properly tagged as leaks
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 275ce16..79daa3f 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -193,10 +193,9 @@
 }
 
 SkRect TestUtils::getClipBounds(const SkCanvas* canvas) {
-    SkClipStack::BoundsType boundType;
-    SkRect clipBounds;
-    canvas->getClipStack()->getBounds(&clipBounds, &boundType);
-    return clipBounds;
+    SkIRect bounds;
+    (void)canvas->getClipDeviceBounds(&bounds);
+    return SkRect::Make(bounds);
 }
 
 SkRect TestUtils::getLocalClipBounds(const SkCanvas* canvas) {
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index f5ff058..2f1eae3 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -865,10 +865,8 @@
         void onDrawPaint(const SkPaint&) {
             switch (mDrawCounter++) {
             case 0:
-                // While this mirrors FrameBuilder::colorOp_unbounded, this value is different
-                // because there is no root (root is clipped in SkiaPipeline::renderFrame).
-                // SkiaPipeline.clipped and clip_replace verify the root clip.
-                EXPECT_TRUE(TestUtils::getClipBounds(this).isEmpty());
+                EXPECT_EQ(SkRect::MakeWH(CANVAS_WIDTH, CANVAS_HEIGHT),
+                        TestUtils::getClipBounds(this));
                 break;
             case 1:
                 EXPECT_EQ(SkRect::MakeWH(10, 10), TestUtils::getClipBounds(this));
diff --git a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
index 92d9d3d..95c6ed6 100644
--- a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
+++ b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
@@ -87,14 +87,7 @@
     testProperty([](RenderProperties& properties) {
         properties.mutableRevealClip().set(true, 50, 50, 25);
     }, [](const SkCanvas& canvas) {
-        SkClipStack::Iter it(*canvas.getClipStack(), SkClipStack::Iter::kBottom_IterStart);
-        const SkClipStack::Element *top = it.next();
-        ASSERT_NE(nullptr, top);
-        SkPath clip;
-        top->asPath(&clip);
-        SkRect rect;
-        EXPECT_TRUE(clip.isOval(&rect));
-        EXPECT_EQ(SkRect::MakeLTRB(25, 25, 75, 75), rect);
+        EXPECT_EQ(SkRect::MakeLTRB(25, 25, 75, 75), TestUtils::getClipBounds(&canvas));
     });
 }
 
@@ -103,14 +96,7 @@
         properties.mutableOutline().setShouldClip(true);
         properties.mutableOutline().setRoundRect(10, 20, 30, 40, 5.0f, 0.5f);
     }, [](const SkCanvas& canvas) {
-        SkClipStack::Iter it(*canvas.getClipStack(), SkClipStack::Iter::kBottom_IterStart);
-        const SkClipStack::Element *top = it.next();
-        ASSERT_NE(nullptr, top);
-        SkPath clip;
-        top->asPath(&clip);
-        SkRRect rrect;
-        EXPECT_TRUE(clip.isRRect(&rrect));
-        EXPECT_EQ(SkRRect::MakeRectXY(SkRect::MakeLTRB(10, 20, 30, 40), 5.0f, 5.0f), rrect);
+        EXPECT_EQ(SkRect::MakeLTRB(10, 20, 30, 40), TestUtils::getClipBounds(&canvas));
     });
 }
 
diff --git a/preloaded-classes b/preloaded-classes
index 86cbb69..2fad5dd 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -823,11 +823,6 @@
 android.graphics.EmbossMaskFilter
 android.graphics.FontFamily
 android.graphics.FontListParser
-android.graphics.FontListParser$Alias
-android.graphics.FontListParser$Axis
-android.graphics.FontListParser$Config
-android.graphics.FontListParser$Family
-android.graphics.FontListParser$Font
 android.graphics.Insets
 android.graphics.Interpolator
 android.graphics.Interpolator$Result
@@ -1001,10 +996,6 @@
 android.hardware.input.InputDeviceIdentifier$1
 android.hardware.input.InputManager
 android.hardware.input.InputManager$InputDevicesChangedListener
-# These cannot be preloaded and need to be refactored into system server. b/17791590, b/21935130
-# android.hardware.location.ActivityRecognitionHardware
-# android.hardware.location.IActivityRecognitionHardware
-# android.hardware.location.IActivityRecognitionHardware$Stub
 android.hardware.location.ContextHubManager
 android.hardware.location.IContextHubService
 android.hardware.location.IContextHubService$Stub
@@ -1847,6 +1838,11 @@
 android.text.DynamicLayout$ChangeWatcher
 android.text.Editable
 android.text.Editable$Factory
+android.text.FontConfig
+android.text.FontConfig$Alias
+android.text.FontConfig$Axis
+android.text.FontConfig$Family
+android.text.FontConfig$Font
 android.text.GetChars
 android.text.GraphicsOperations
 android.text.Html
diff --git a/services/core/java/com/android/server/FontManagerService.java b/services/core/java/com/android/server/FontManagerService.java
new file mode 100644
index 0000000..593c322
--- /dev/null
+++ b/services/core/java/com/android/server/FontManagerService.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.graphics.FontListParser;
+import android.os.ParcelFileDescriptor;
+import android.text.FontConfig;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.font.IFontManager;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class FontManagerService extends IFontManager.Stub {
+    private static final String TAG = "FontManagerService";
+    private static final String FONTS_CONFIG = "/system/etc/fonts.xml";
+
+    @GuardedBy("mLock")
+    private FontConfig mConfig;
+    private final Object mLock = new Object();
+
+    public static final class Lifecycle extends SystemService {
+        private final FontManagerService mService;
+
+        public Lifecycle(Context context) {
+            super(context);
+            mService = new FontManagerService();
+        }
+
+        @Override
+        public void onStart() {
+            try {
+                publishBinderService(Context.FONT_SERVICE, mService);
+            } catch (Throwable t) {
+                // Starting this service is not critical to the running of this device and should
+                // therefore not crash the device. If it fails, log the error and continue.
+                Slog.e(TAG, "Could not start the FontManagerService.", t);
+            }
+        }
+    }
+
+    @Override
+    public FontConfig getSystemFonts() {
+        synchronized (mLock) {
+            if (mConfig != null) {
+                return new FontConfig(mConfig);
+            }
+
+            FontConfig config = loadFromSystem();
+            if (config == null) {
+                return null;
+            }
+
+            final int size = config.getFamilies().size();
+            for (int i = 0; i < size; ++i) {
+                FontConfig.Family family = config.getFamilies().get(i);
+                for (int j = 0; j < family.getFonts().size(); ++j) {
+                    FontConfig.Font font = family.getFonts().get(j);
+                    File fontFile = new File(font.getFontName());
+                    try {
+                        font.setFd(ParcelFileDescriptor.open(
+                                fontFile, ParcelFileDescriptor.MODE_READ_ONLY));
+                    } catch (IOException e) {
+                        Slog.e(TAG, "Error opening font file " + font.getFontName(), e);
+                    }
+                }
+            }
+
+            mConfig = config;
+            return new FontConfig(mConfig);
+        }
+    }
+
+    private FontConfig loadFromSystem() {
+        File configFilename = new File(FONTS_CONFIG);
+        try {
+            FileInputStream fontsIn = new FileInputStream(configFilename);
+            return FontListParser.parse(fontsIn);
+        } catch (IOException | XmlPullParserException e) {
+            Slog.e(TAG, "Error opening " + configFilename, e);
+        }
+        return null;
+    }
+
+    public FontManagerService() {
+    }
+}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index c9b59ade..6cc72de 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.app.ActivityManager;
 import android.content.pm.PackageManagerInternal;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.location.ProviderProperties;
@@ -138,6 +139,9 @@
     // The maximum interval a location request can have and still be considered "high power".
     private static final long HIGH_POWER_INTERVAL_MS = 5 * 60 * 1000;
 
+    // default background throttling interval if not overriden in settings
+    private static final long DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS = 30 * 1000;
+
     // Location Providers may sometimes deliver location updates
     // slightly faster that requested - provide grace period so
     // we don't unnecessarily filter events that are otherwise on
@@ -157,6 +161,7 @@
     private GeofenceManager mGeofenceManager;
     private PackageManager mPackageManager;
     private PowerManager mPowerManager;
+    private ActivityManager mActivityManager;
     private UserManager mUserManager;
     private GeocoderProxy mGeocodeProvider;
     private IGnssStatusProvider mGnssStatusProvider;
@@ -171,47 +176,47 @@
     // --- fields below are protected by mLock ---
     // Set of providers that are explicitly enabled
     // Only used by passive, fused & test.  Network & GPS are controlled separately, and not listed.
-    private final Set<String> mEnabledProviders = new HashSet<String>();
+    private final Set<String> mEnabledProviders = new HashSet<>();
 
     // Set of providers that are explicitly disabled
-    private final Set<String> mDisabledProviders = new HashSet<String>();
+    private final Set<String> mDisabledProviders = new HashSet<>();
 
     // Mock (test) providers
     private final HashMap<String, MockProvider> mMockProviders =
-            new HashMap<String, MockProvider>();
+            new HashMap<>();
 
     // all receivers
-    private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>();
+    private final HashMap<Object, Receiver> mReceivers = new HashMap<>();
 
     // currently installed providers (with mocks replacing real providers)
     private final ArrayList<LocationProviderInterface> mProviders =
-            new ArrayList<LocationProviderInterface>();
+            new ArrayList<>();
 
     // real providers, saved here when mocked out
     private final HashMap<String, LocationProviderInterface> mRealProviders =
-            new HashMap<String, LocationProviderInterface>();
+            new HashMap<>();
 
     // mapping from provider name to provider
     private final HashMap<String, LocationProviderInterface> mProvidersByName =
-            new HashMap<String, LocationProviderInterface>();
+            new HashMap<>();
 
     // mapping from provider name to all its UpdateRecords
     private final HashMap<String, ArrayList<UpdateRecord>> mRecordsByProvider =
-            new HashMap<String, ArrayList<UpdateRecord>>();
+            new HashMap<>();
 
     private final LocationRequestStatistics mRequestStatistics = new LocationRequestStatistics();
 
     // mapping from provider name to last known location
-    private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>();
+    private final HashMap<String, Location> mLastLocation = new HashMap<>();
 
     // same as mLastLocation, but is not updated faster than LocationFudger.FASTEST_INTERVAL_MS.
     // locations stored here are not fudged for coarse permissions.
     private final HashMap<String, Location> mLastLocationCoarseInterval =
-            new HashMap<String, Location>();
+            new HashMap<>();
 
     // all providers that operate over proxy, for authorizing incoming location
     private final ArrayList<LocationProviderProxy> mProxyProviders =
-            new ArrayList<LocationProviderProxy>();
+            new ArrayList<>();
 
     // current active user on the device - other users are denied location data
     private int mCurrentUserId = UserHandle.USER_SYSTEM;
@@ -252,6 +257,10 @@
             // fetch power manager
             mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
 
+            // fetch activity manager
+            mActivityManager
+                    = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+
             // prepare worker thread
             mLocationHandler = new LocationWorkerHandler(BackgroundThread.get().getLooper());
 
@@ -286,6 +295,40 @@
             };
             mPackageManager.addOnPermissionsChangeListener(permissionListener);
 
+            // listen for background/foreground changes
+            ActivityManager.OnUidImportanceListener uidImportanceListener
+                    = new ActivityManager.OnUidImportanceListener() {
+                @Override
+                public void onUidImportance(int uid, int importance) {
+                    boolean foreground = isImportanceForeground(importance);
+                    HashSet<String> affectedProviders = new HashSet<>(mRecordsByProvider.size());
+                    synchronized (mLock) {
+                        for (Map.Entry<String, ArrayList<UpdateRecord>> entry
+                                : mRecordsByProvider.entrySet()) {
+                            String provider = entry.getKey();
+                            for (UpdateRecord record : entry.getValue()) {
+                                if (record.mReceiver.mUid == uid
+                                        && record.mIsForegroundUid != foreground) {
+                                    if (D) Log.d(TAG, "request from uid " + uid + " is now "
+                                            + (foreground ? "foreground" : "background)"));
+                                    record.mIsForegroundUid = foreground;
+
+                                    if (!isThrottlingExemptLocked(record.mReceiver)) {
+                                        affectedProviders.add(provider);
+                                    }
+                                }
+                            }
+                        }
+                        for (String provider : affectedProviders) {
+                            applyRequirementsLocked(provider);
+                        }
+                    }
+
+                }
+            };
+            mActivityManager.addOnUidImportanceListener(uidImportanceListener,
+                    ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE);
+
             mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
             updateUserProfiles(mCurrentUserId);
 
@@ -305,6 +348,17 @@
                         }
                     }
                 }, UserHandle.USER_ALL);
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS),
+                true,
+                new ContentObserver(mLocationHandler) {
+                    @Override
+                    public void onChange(boolean selfChange) {
+                        synchronized (mLock) {
+                            updateProvidersLocked();
+                        }
+                    }
+                }, UserHandle.USER_ALL);
         mPackageMonitor.register(mContext, mLocationHandler.getLooper(), true);
 
         // listen for user change
@@ -334,6 +388,10 @@
         }, UserHandle.ALL, intentFilter, null, mLocationHandler);
     }
 
+    private static boolean isImportanceForeground(int importance) {
+        return importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+    }
+
     /**
      * Provides a way for components held by the {@link LocationManagerService} to clean-up
      * gracefully on system's shutdown.
@@ -483,7 +541,7 @@
         that matches the signature of at least one package on this list.
         */
         Resources resources = mContext.getResources();
-        ArrayList<String> providerPackageNames = new ArrayList<String>();
+        ArrayList<String> providerPackageNames = new ArrayList<>();
         String[] pkgs = resources.getStringArray(
                 com.android.internal.R.array.config_locationProviderPackageNames);
         if (D) Log.d(TAG, "certificates for location providers pulled from: " +
@@ -651,7 +709,7 @@
         final boolean mHideFromAppOps; // True if AppOps should not monitor this receiver.
         final Object mKey;
 
-        final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>();
+        final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<>();
 
         // True if app ops has started monitoring this receiver for locations.
         boolean mOpMonitoring;
@@ -691,10 +749,7 @@
 
         @Override
         public boolean equals(Object otherObj) {
-            if (otherObj instanceof Receiver) {
-                return mKey.equals(((Receiver)otherObj).mKey);
-            }
-            return false;
+            return (otherObj instanceof Receiver) && mKey.equals(((Receiver) otherObj).mKey);
         }
 
         @Override
@@ -1011,13 +1066,25 @@
         mProvidersByName.remove(provider.getName());
     }
 
+    private boolean isOverlayProviderPackageLocked(String packageName) {
+        for (LocationProviderInterface provider : mProviders) {
+            if (provider instanceof LocationProviderProxy) {
+                if (packageName.equals(
+                        ((LocationProviderProxy) provider).getConnectedPackageName())) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Returns "true" if access to the specified location provider is allowed by the current
      * user's settings. Access to all location providers is forbidden to non-location-provider
      * processes belonging to background users.
      *
      * @param provider the name of the location provider
-     * @return
      */
     private boolean isAllowedByCurrentUserSettingsLocked(String provider) {
         if (mEnabledProviders.contains(provider)) {
@@ -1039,7 +1106,6 @@
      *
      * @param provider the name of the location provider
      * @param uid the requestor's UID
-     * @return
      */
     private boolean isAllowedByUserSettingsLocked(String provider, int uid) {
         if (!isCurrentProfile(UserHandle.getUserId(uid)) && !isUidALocationProvider(uid)) {
@@ -1197,11 +1263,7 @@
             }
         }
 
-        if (getAllowedResolutionLevel(pid, uid) < allowedResolutionLevel) {
-            return false;
-        }
-
-        return true;
+        return getAllowedResolutionLevel(pid, uid) >= allowedResolutionLevel;
     }
 
     boolean checkLocationAccess(int pid, int uid, String packageName, int allowedResolutionLevel) {
@@ -1212,11 +1274,7 @@
             }
         }
 
-        if (getAllowedResolutionLevel(pid, uid) < allowedResolutionLevel) {
-            return false;
-        }
-
-        return true;
+        return getAllowedResolutionLevel(pid, uid) >= allowedResolutionLevel;
     }
 
     /**
@@ -1228,7 +1286,7 @@
     public List<String> getAllProviders() {
         ArrayList<String> out;
         synchronized (mLock) {
-            out = new ArrayList<String>(mProviders.size());
+            out = new ArrayList<>(mProviders.size());
             for (LocationProviderInterface provider : mProviders) {
                 String name = provider.getName();
                 if (LocationManager.FUSED_PROVIDER.equals(name)) {
@@ -1251,11 +1309,11 @@
     public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
         int allowedResolutionLevel = getCallerAllowedResolutionLevel();
         ArrayList<String> out;
-        int uid = Binder.getCallingUid();;
+        int uid = Binder.getCallingUid();
         long identity = Binder.clearCallingIdentity();
         try {
             synchronized (mLock) {
-                out = new ArrayList<String>(mProviders.size());
+                out = new ArrayList<>(mProviders.size());
                 for (LocationProviderInterface provider : mProviders) {
                     String name = provider.getName();
                     if (LocationManager.FUSED_PROVIDER.equals(name)) {
@@ -1370,14 +1428,12 @@
 
         ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
         if (records != null) {
-            final int N = records.size();
-            for (int i = 0; i < N; i++) {
-                UpdateRecord record = records.get(i);
+            for (UpdateRecord record : records) {
                 if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) {
                     // Sends a notification message to the receiver
                     if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) {
                         if (deadReceivers == null) {
-                            deadReceivers = new ArrayList<Receiver>();
+                            deadReceivers = new ArrayList<>();
                         }
                         deadReceivers.add(record.mReceiver);
                     }
@@ -1410,6 +1466,12 @@
         WorkSource worksource = new WorkSource();
         ProviderRequest providerRequest = new ProviderRequest();
 
+        ContentResolver resolver = mContext.getContentResolver();
+        long backgroundThrottleInterval = Settings.Global.getLong(
+                resolver,
+                Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS,
+                DEFAULT_BACKGROUND_THROTTLE_INTERVAL_MS);
+
         if (records != null) {
             for (UpdateRecord record : records) {
                 if (isCurrentProfile(UserHandle.getUserId(record.mReceiver.mUid))) {
@@ -1419,10 +1481,22 @@
                             record.mReceiver.mPackageName,
                             record.mReceiver.mAllowedResolutionLevel)) {
                         LocationRequest locationRequest = record.mRequest;
+                        long interval = locationRequest.getInterval();
+
+                        if (!isThrottlingExemptLocked(record.mReceiver)) {
+                            if (!record.mIsForegroundUid) {
+                                interval = Math.max(interval, backgroundThrottleInterval);
+                            }
+                            if (interval != locationRequest.getInterval()) {
+                                locationRequest = new LocationRequest(locationRequest);
+                                locationRequest.setInterval(interval);
+                            }
+                        }
+
                         providerRequest.locationRequests.add(locationRequest);
-                        if (locationRequest.getInterval() < providerRequest.interval) {
+                        if (interval < providerRequest.interval) {
                             providerRequest.reportLocation = true;
-                            providerRequest.interval = locationRequest.getInterval();
+                            providerRequest.interval = interval;
                         }
                     }
                 }
@@ -1468,10 +1542,15 @@
         p.setRequest(providerRequest, worksource);
     }
 
+    private boolean isThrottlingExemptLocked(Receiver recevier) {
+        return isOverlayProviderPackageLocked(recevier.mPackageName);
+    }
+
     private class UpdateRecord {
         final String mProvider;
         final LocationRequest mRequest;
         final Receiver mReceiver;
+        boolean mIsForegroundUid;
         Location mLastFixBroadcast;
         long mLastStatusBroadcast;
 
@@ -1482,10 +1561,12 @@
             mProvider = provider;
             mRequest = request;
             mReceiver = receiver;
+            mIsForegroundUid = isImportanceForeground(
+                    mActivityManager.getPackageImportance(mReceiver.mPackageName));
 
             ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
             if (records == null) {
-                records = new ArrayList<UpdateRecord>();
+                records = new ArrayList<>();
                 mRecordsByProvider.put(provider, records);
             }
             if (!records.contains(this)) {
@@ -1517,7 +1598,7 @@
                 receiverRecords.remove(this.mProvider);
 
                 // and also remove the Receiver if it has no more update records
-                if (removeReceiver && receiverRecords.size() == 0) {
+                if (receiverRecords.size() == 0) {
                     removeUpdatesLocked(mReceiver);
                 }
             }
@@ -1525,14 +1606,9 @@
 
         @Override
         public String toString() {
-            StringBuilder s = new StringBuilder();
-            s.append("UpdateRecord[");
-            s.append(mProvider);
-            s.append(' ').append(mReceiver.mPackageName).append('(');
-            s.append(mReceiver.mUid).append(')');
-            s.append(' ').append(mRequest);
-            s.append(']');
-            return s.toString();
+            return "UpdateRecord[" + mProvider + " " + mReceiver.mPackageName
+                    + "(" + mReceiver.mUid + (mIsForegroundUid ? " foreground" : " background")
+                    + ")" + " " + mRequest + "]";
         }
     }
 
@@ -1681,14 +1757,17 @@
             throw new IllegalArgumentException("provider name must not be null");
         }
 
-        if (D) Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver))
-                + " " + name + " " + request + " from " + packageName + "(" + uid + ")");
         LocationProviderInterface provider = mProvidersByName.get(name);
         if (provider == null) {
             throw new IllegalArgumentException("provider doesn't exist: " + name);
         }
 
         UpdateRecord record = new UpdateRecord(name, request, receiver);
+        if (D) Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver))
+                + " " + name + " " + request + " from " + packageName + "(" + uid + " "
+                + (record.mIsForegroundUid ? "foreground" : "background")
+                + (isOverlayProviderPackageLocked(receiver.mPackageName) ? " [whitelisted]" : "") + ")");
+
         UpdateRecord oldRecord = receiver.mUpdateRecords.put(name, record);
         if (oldRecord != null) {
             oldRecord.disposeLocked(false);
@@ -1743,7 +1822,7 @@
         receiver.updateMonitoring(false);
 
         // Record which providers were associated with this listener
-        HashSet<String> providers = new HashSet<String>();
+        HashSet<String> providers = new HashSet<>();
         HashMap<String, UpdateRecord> oldRecords = receiver.mUpdateRecords;
         if (oldRecords != null) {
             // Call dispose() on the obsolete update records.
@@ -2084,9 +2163,7 @@
         try {
             synchronized (mLock) {
                 LocationProviderInterface p = mProvidersByName.get(provider);
-                if (p == null) return false;
-
-                return isAllowedByUserSettingsLocked(provider, uid);
+                return p != null && isAllowedByUserSettingsLocked(provider, uid);
             }
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -2197,11 +2274,7 @@
         }
 
         // Check whether the expiry date has passed
-        if (record.mRequest.getExpireAt() < now) {
-            return false;
-        }
-
-        return true;
+        return record.mRequest.getExpireAt() >= now;
     }
 
     private void handleLocationChangedLocked(Location location, boolean passive) {
@@ -2216,7 +2289,7 @@
 
         // Update last known locations
         Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION);
-        Location lastNoGPSLocation = null;
+        Location lastNoGPSLocation;
         Location lastLocation = mLastLocation.get(provider);
         if (lastLocation == null) {
             lastLocation = new Location(provider);
@@ -2296,7 +2369,7 @@
                 continue;
             }
 
-            Location notifyLocation = null;
+            Location notifyLocation;
             if (receiver.mAllowedResolutionLevel < RESOLUTION_LEVEL_FINE) {
                 notifyLocation = coarseLocation;  // use coarse location
             } else {
@@ -2333,14 +2406,14 @@
             // track expired records
             if (r.mRequest.getNumUpdates() <= 0 || r.mRequest.getExpireAt() < now) {
                 if (deadUpdateRecords == null) {
-                    deadUpdateRecords = new ArrayList<UpdateRecord>();
+                    deadUpdateRecords = new ArrayList<>();
                 }
                 deadUpdateRecords.add(r);
             }
             // track dead receivers
             if (receiverDead) {
                 if (deadReceivers == null) {
-                    deadReceivers = new ArrayList<Receiver>();
+                    deadReceivers = new ArrayList<>();
                 }
                 if (!deadReceivers.contains(receiver)) {
                     deadReceivers.add(receiver);
@@ -2417,7 +2490,7 @@
                 for (Receiver receiver : mReceivers.values()) {
                     if (receiver.mPackageName.equals(packageName)) {
                         if (deadReceivers == null) {
-                            deadReceivers = new ArrayList<Receiver>();
+                            deadReceivers = new ArrayList<>();
                         }
                         deadReceivers.add(receiver);
                     }
@@ -2694,6 +2767,13 @@
                     pw.println("      " + record);
                 }
             }
+            pw.println("  Overlay Provider Packages:");
+            for (LocationProviderInterface provider : mProviders) {
+                if (provider instanceof LocationProviderProxy) {
+                    pw.println("    " + provider.getName() + ": "
+                            + ((LocationProviderProxy) provider).getConnectedPackageName());
+                }
+            }
             pw.println("  Historical Records by Provider:");
             for (Map.Entry<PackageProviderKey, PackageStatistics> entry
                     : mRequestStatistics.statistics.entrySet()) {
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 4b89b40..1bba7ec 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -707,7 +707,7 @@
         try {
             ServiceRecord r = findServiceLocked(className, token, userId);
             if (r != null) {
-                setServiceForegroundInnerLocked(r, userId, notification, flags);
+                setServiceForegroundInnerLocked(r, id, notification, flags);
             }
         } finally {
             Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index ae709fe..56d679e 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -1529,10 +1529,11 @@
         if (UserHandle.getUserId(callingUid) != userId) {
             throw new SecurityException("Invalid user-ID");
         }
-        if (injectGetPackageUid(packageName, userId) == callingUid) {
-            return; // Caller is valid.
+        if (injectGetPackageUid(packageName, userId) != callingUid) {
+            throw new SecurityException("Calling package name mismatch");
         }
-        throw new SecurityException("Calling package name mismatch");
+        Preconditions.checkState(!isEphemeralApp(packageName, userId),
+                "Ephemeral apps can't use ShortcutManager");
     }
 
     // Overridden in unit tests to execute r synchronously.
@@ -3073,6 +3074,10 @@
         return (ai != null) && (ai.flags & ApplicationInfo.FLAG_INSTALLED) != 0;
     }
 
+    private static boolean isEphemeralApp(@Nullable ApplicationInfo ai) {
+        return (ai != null) && ai.isEphemeralApp();
+    }
+
     private static boolean isInstalled(@Nullable PackageInfo pi) {
         return (pi != null) && isInstalled(pi.applicationInfo);
     }
@@ -3097,6 +3102,10 @@
         return getApplicationInfo(packageName, userId) != null;
     }
 
+    boolean isEphemeralApp(String packageName, int userId) {
+        return isEphemeralApp(getApplicationInfo(packageName, userId));
+    }
+
     @Nullable
     XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
         return activityInfo.loadXmlMetaData(mContext.getPackageManager(), key);
diff --git a/services/core/java/com/android/server/webkit/SystemImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java
index 02b46ec..4fd51b2 100644
--- a/services/core/java/com/android/server/webkit/SystemImpl.java
+++ b/services/core/java/com/android/server/webkit/SystemImpl.java
@@ -35,6 +35,7 @@
 import android.provider.Settings;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
+import android.webkit.UserPackage;
 import android.webkit.WebViewFactory;
 import android.webkit.WebViewProviderInfo;
 import android.webkit.WebViewZygote;
@@ -271,6 +272,12 @@
     }
 
     @Override
+    public List<UserPackage> getPackageInfoForProviderAllUsers(Context context,
+            WebViewProviderInfo configInfo) {
+        return UserPackage.getPackageInfosAllUsers(context, configInfo.packageName, PACKAGE_FLAGS);
+    }
+
+    @Override
     public int getMultiProcessSetting(Context context) {
         return Settings.Global.getInt(context.getContentResolver(),
                                       Settings.Global.WEBVIEW_MULTIPROCESS, 0);
diff --git a/services/core/java/com/android/server/webkit/SystemInterface.java b/services/core/java/com/android/server/webkit/SystemInterface.java
index fd137eb..b06f829 100644
--- a/services/core/java/com/android/server/webkit/SystemInterface.java
+++ b/services/core/java/com/android/server/webkit/SystemInterface.java
@@ -20,8 +20,11 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.database.ContentObserver;
+import android.webkit.UserPackage;
 import android.webkit.WebViewProviderInfo;
 
+import java.util.List;
+
 /**
  * System interface for the WebViewUpdateService.
  * This interface provides a way to test the WebView preparation mechanism - during normal use this
@@ -49,6 +52,14 @@
     public boolean systemIsDebuggable();
     public PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo)
             throws NameNotFoundException;
+    /**
+     * Get the PackageInfos of all users for the package represented by {@param configInfo}.
+     * @return an array of UserPackages for a certain package, each UserPackage being belonging to a
+     *         certain user. The returned array can contain null PackageInfos if the given package
+     *         is uninstalled for some user.
+     */
+    public List<UserPackage> getPackageInfoForProviderAllUsers(Context context,
+            WebViewProviderInfo configInfo);
 
     public int getMultiProcessSetting(Context context);
     public void setMultiProcessSetting(Context context, int value);
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 311570e..4a105e1 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -94,6 +94,9 @@
                         case Intent.ACTION_USER_ADDED:
                             mImpl.handleNewUser(userId);
                             break;
+                        case Intent.ACTION_USER_REMOVED:
+                            mImpl.handleUserRemoved(userId);
+                            break;
                     }
                 }
         };
@@ -112,6 +115,7 @@
 
         IntentFilter userAddedFilter = new IntentFilter();
         userAddedFilter.addAction(Intent.ACTION_USER_ADDED);
+        userAddedFilter.addAction(Intent.ACTION_USER_REMOVED);
         getContext().registerReceiverAsUser(mWebViewUpdatedReceiver, UserHandle.ALL,
                 userAddedFilter, null /* broadcast permission */, null /* handler */);
 
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index edfb11c..f016830 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -24,6 +24,7 @@
 import android.os.UserHandle;
 import android.util.Base64;
 import android.util.Slog;
+import android.webkit.UserPackage;
 import android.webkit.WebViewFactory;
 import android.webkit.WebViewProviderInfo;
 import android.webkit.WebViewProviderResponse;
@@ -100,32 +101,41 @@
     private boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) {
         for (WebViewProviderInfo provider : providers) {
             if (provider.availableByDefault && !provider.isFallback) {
-                try {
-                    PackageInfo packageInfo = mSystemInterface.getPackageInfoForProvider(provider);
-                    if (isInstalledPackage(packageInfo) && isEnabledPackage(packageInfo)
-                            && mWebViewUpdater.isValidProvider(provider, packageInfo)) {
-                        return true;
-                    }
-                } catch (NameNotFoundException e) {
-                    // A non-existent provider is neither valid nor enabled
+                // userPackages can contain null objects.
+                List<UserPackage> userPackages =
+                        mSystemInterface.getPackageInfoForProviderAllUsers(mContext, provider);
+                if (isInstalledAndEnabledForAllUsers(userPackages) &&
+                        // Checking validity of the package for the system user (rather than all
+                        // users) since package validity depends not on the user but on the package
+                        // itself.
+                        mWebViewUpdater.isValidProvider(provider,
+                                userPackages.get(UserHandle.USER_SYSTEM).getPackageInfo())) {
+                    return true;
                 }
             }
         }
         return false;
     }
 
-    /**
-     * Called when a new user has been added to update the state of its fallback package.
-     */
     void handleNewUser(int userId) {
-        if (!mSystemInterface.isFallbackLogicEnabled()) return;
+        handleUserChange();
+    }
 
-        WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
-        WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
-        if (fallbackProvider == null) return;
+    void handleUserRemoved(int userId) {
+        handleUserChange();
+    }
 
-        mSystemInterface.enablePackageForUser(fallbackProvider.packageName,
-                !existsValidNonFallbackProvider(webviewProviders), userId);
+    /**
+     * Called when a user was added or removed to ensure fallback logic and WebView preparation are
+     * triggered. This has to be done since the WebView package we use depends on the enabled-state
+     * of packages for all users (so adding or removing a user might cause us to change package).
+     */
+    private void handleUserChange() {
+        if (mSystemInterface.isFallbackLogicEnabled()) {
+            updateFallbackState(mSystemInterface.getWebViewPackages());
+        }
+        // Potentially trigger package-changing logic.
+        mWebViewUpdater.updateCurrentWebViewPackage(null);
     }
 
     void notifyRelroCreationCompleted() {
@@ -141,7 +151,7 @@
     }
 
     WebViewProviderInfo[] getValidWebViewPackages() {
-        return mWebViewUpdater.getValidAndInstalledWebViewPackages();
+        return mWebViewUpdater.getValidWebViewPackages();
     }
 
     WebViewProviderInfo[] getWebViewPackages() {
@@ -160,7 +170,7 @@
         if (!mSystemInterface.isFallbackLogicEnabled()) return;
 
         WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages();
-        updateFallbackState(webviewProviders, true);
+        updateFallbackState(webviewProviders);
     }
 
     /**
@@ -185,35 +195,23 @@
             }
         }
         if (!changedPackageAvailableByDefault) return;
-        updateFallbackState(webviewProviders, false);
+        updateFallbackState(webviewProviders);
     }
 
-    private void updateFallbackState(WebViewProviderInfo[] webviewProviders, boolean isBoot) {
+    private void updateFallbackState(WebViewProviderInfo[] webviewProviders) {
         // If there exists a valid and enabled non-fallback package - disable the fallback
         // package, otherwise, enable it.
         WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders);
         if (fallbackProvider == null) return;
         boolean existsValidNonFallbackProvider = existsValidNonFallbackProvider(webviewProviders);
 
-        boolean isFallbackEnabled = false;
-        try {
-            isFallbackEnabled = isEnabledPackage(
-                    mSystemInterface.getPackageInfoForProvider(fallbackProvider));
-        } catch (NameNotFoundException e) {
-            // No fallback package installed -> early out.
-            return;
-        }
-
-        if (existsValidNonFallbackProvider
-                // During an OTA the primary user's WebView state might differ from other users', so
-                // ignore the state of that user during boot.
-                && (isFallbackEnabled || isBoot)) {
+        List<UserPackage> userPackages =
+                mSystemInterface.getPackageInfoForProviderAllUsers(mContext, fallbackProvider);
+        if (existsValidNonFallbackProvider && !isDisabledForAllUsers(userPackages)) {
             mSystemInterface.uninstallAndDisablePackageForAllUsers(mContext,
                     fallbackProvider.packageName);
         } else if (!existsValidNonFallbackProvider
-                // During an OTA the primary user's WebView state might differ from other users', so
-                // ignore the state of that user during boot.
-                && (!isFallbackEnabled || isBoot)) {
+                && !isInstalledAndEnabledForAllUsers(userPackages)) {
             // Enable the fallback package for all users.
             mSystemInterface.enablePackageForAllUsers(mContext,
                     fallbackProvider.packageName, true);
@@ -376,38 +374,8 @@
          * or the replacement are done).
          */
         public String changeProviderAndSetting(String newProviderName) {
-            PackageInfo oldPackage = null;
-            PackageInfo newPackage = null;
-            boolean providerChanged = false;
-            synchronized(mLock) {
-                oldPackage = mCurrentWebViewPackage;
-                mSystemInterface.updateUserSetting(mContext, newProviderName);
-
-                try {
-                    newPackage = findPreferredWebViewPackage();
-                    providerChanged = (oldPackage == null)
-                            || !newPackage.packageName.equals(oldPackage.packageName);
-                } catch (WebViewPackageMissingException e) {
-                    mCurrentWebViewPackage = null;
-                    Slog.e(TAG, "Tried to change WebView provider but failed to fetch WebView " +
-                            "package " + e);
-                    // If we don't perform the user change but don't have an installed WebView
-                    // package, we will have changed the setting and it will be used when a package
-                    // is available.
-                    return "";
-                }
-                // Perform the provider change if we chose a new provider
-                if (providerChanged) {
-                    onWebViewProviderChanged(newPackage);
-                }
-            }
-            // Kill apps using the old provider only if we changed provider
-            if (providerChanged && oldPackage != null) {
-                mSystemInterface.killPackageDependents(oldPackage.packageName);
-            }
-            // Return the new provider, this is not necessarily the one we were asked to switch to
-            // But the persistent setting will now be pointing to the provider we were asked to
-            // switch to anyway
+            PackageInfo newPackage = updateCurrentWebViewPackage(newProviderName);
+            if (newPackage == null) return "";
             return newPackage.packageName;
         }
 
@@ -437,15 +405,14 @@
             }
         }
 
-        private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos(boolean onlyInstalled) {
+        private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos() {
             WebViewProviderInfo[] allProviders = mSystemInterface.getWebViewPackages();
             List<ProviderAndPackageInfo> providers = new ArrayList<>();
             for(int n = 0; n < allProviders.length; n++) {
                 try {
                     PackageInfo packageInfo =
                         mSystemInterface.getPackageInfoForProvider(allProviders[n]);
-                    if ((!onlyInstalled || isInstalledPackage(packageInfo))
-                            && isValidProvider(allProviders[n], packageInfo)) {
+                    if (isValidProvider(allProviders[n], packageInfo)) {
                         providers.add(new ProviderAndPackageInfo(allProviders[n], packageInfo));
                     }
                 } catch (NameNotFoundException e) {
@@ -458,9 +425,8 @@
         /**
          * Fetch only the currently valid WebView packages.
          **/
-        public WebViewProviderInfo[] getValidAndInstalledWebViewPackages() {
-            ProviderAndPackageInfo[] providersAndPackageInfos =
-                getValidWebViewPackagesAndInfos(true /* only fetch installed packages */);
+        public WebViewProviderInfo[] getValidWebViewPackages() {
+            ProviderAndPackageInfo[] providersAndPackageInfos = getValidWebViewPackagesAndInfos();
             WebViewProviderInfo[] providers =
                 new WebViewProviderInfo[providersAndPackageInfos.length];
             for(int n = 0; n < providersAndPackageInfos.length; n++) {
@@ -487,39 +453,49 @@
          *
          */
         private PackageInfo findPreferredWebViewPackage() throws WebViewPackageMissingException {
-            ProviderAndPackageInfo[] providers =
-                getValidWebViewPackagesAndInfos(false /* onlyInstalled */);
+            ProviderAndPackageInfo[] providers = getValidWebViewPackagesAndInfos();
 
             String userChosenProvider = mSystemInterface.getUserChosenWebViewProvider(mContext);
 
-            // If the user has chosen provider, use that
+            // If the user has chosen provider, use that (if it's installed and enabled for all
+            // users).
             for (ProviderAndPackageInfo providerAndPackage : providers) {
-                if (providerAndPackage.provider.packageName.equals(userChosenProvider)
-                        && isInstalledPackage(providerAndPackage.packageInfo)
-                        && isEnabledPackage(providerAndPackage.packageInfo)) {
-                    return providerAndPackage.packageInfo;
+                if (providerAndPackage.provider.packageName.equals(userChosenProvider)) {
+                    // userPackages can contain null objects.
+                    List<UserPackage> userPackages =
+                            mSystemInterface.getPackageInfoForProviderAllUsers(mContext,
+                                    providerAndPackage.provider);
+                    if (isInstalledAndEnabledForAllUsers(userPackages)) {
+                        return providerAndPackage.packageInfo;
+                    }
                 }
             }
 
             // User did not choose, or the choice failed; use the most stable provider that is
-            // installed and enabled for the device owner, and available by default (not through
+            // installed and enabled for all users, and available by default (not through
             // user choice).
             for (ProviderAndPackageInfo providerAndPackage : providers) {
-                if (providerAndPackage.provider.availableByDefault
-                        && isInstalledPackage(providerAndPackage.packageInfo)
-                        && isEnabledPackage(providerAndPackage.packageInfo)) {
-                    return providerAndPackage.packageInfo;
+                if (providerAndPackage.provider.availableByDefault) {
+                    // userPackages can contain null objects.
+                    List<UserPackage> userPackages =
+                            mSystemInterface.getPackageInfoForProviderAllUsers(mContext,
+                                    providerAndPackage.provider);
+                    if (isInstalledAndEnabledForAllUsers(userPackages)) {
+                        return providerAndPackage.packageInfo;
+                    }
                 }
             }
 
             // Could not find any installed and enabled package either, use the most stable and
             // default-available provider.
+            // TODO(gsennton) remove this when we have a functional WebView stub.
             for (ProviderAndPackageInfo providerAndPackage : providers) {
                 if (providerAndPackage.provider.availableByDefault) {
                     return providerAndPackage.packageInfo;
                 }
             }
 
+            // This should never happen during normal operation (only with modified system images).
             mAnyWebViewInstalled = false;
             throw new WebViewPackageMissingException("Could not find a loadable WebView package");
         }
@@ -702,6 +678,48 @@
                         mAnyWebViewInstalled));
             }
         }
+
+        /**
+         * Update the current WebView package.
+         * @param newProviderName the package to switch to, null if no package has been explicitly
+         * chosen.
+         */
+        public PackageInfo updateCurrentWebViewPackage(String newProviderName) {
+            PackageInfo oldPackage = null;
+            PackageInfo newPackage = null;
+            boolean providerChanged = false;
+            synchronized(mLock) {
+                oldPackage = mCurrentWebViewPackage;
+
+                if (newProviderName != null) {
+                    mSystemInterface.updateUserSetting(mContext, newProviderName);
+                }
+
+                try {
+                    newPackage = findPreferredWebViewPackage();
+                    providerChanged = (oldPackage == null)
+                            || !newPackage.packageName.equals(oldPackage.packageName);
+                } catch (WebViewPackageMissingException e) {
+                    // If updated the Setting but don't have an installed WebView package, the
+                    // Setting will be used when a package is available.
+                    mCurrentWebViewPackage = null;
+                    Slog.e(TAG, "Couldn't find WebView package to use " + e);
+                    return null;
+                }
+                // Perform the provider change if we chose a new provider
+                if (providerChanged) {
+                    onWebViewProviderChanged(newPackage);
+                }
+            }
+            // Kill apps using the old provider only if we changed provider
+            if (providerChanged && oldPackage != null) {
+                mSystemInterface.killPackageDependents(oldPackage.packageName);
+            }
+            // Return the new provider, this is not necessarily the one we were asked to switch to,
+            // but the persistent setting will now be pointing to the provider we were asked to
+            // switch to anyway.
+            return newPackage;
+        }
     }
 
     private static boolean providerHasValidSignature(WebViewProviderInfo provider,
@@ -730,20 +748,27 @@
     }
 
     /**
-     * Returns whether the given package is enabled.
-     * This state can be changed by the user from Settings->Apps
+     * Return true iff {@param packageInfos} point to only installed and enabled packages.
+     * The given packages {@param packageInfos} should all be pointing to the same package, but each
+     * PackageInfo representing a different user's package.
      */
-    private static boolean isEnabledPackage(PackageInfo packageInfo) {
-        return packageInfo.applicationInfo.enabled;
+    private static boolean isInstalledAndEnabledForAllUsers(
+            List<UserPackage> userPackages) {
+        for (UserPackage userPackage : userPackages) {
+            if (!userPackage.isInstalledPackage() || !userPackage.isEnabledPackage()) {
+                return false;
+            }
+        }
+        return true;
     }
 
-    /**
-     * Return true if the package is installed and not hidden
-     */
-    private static boolean isInstalledPackage(PackageInfo packageInfo) {
-        return (((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0)
-            && ((packageInfo.applicationInfo.privateFlags
-                        & ApplicationInfo.PRIVATE_FLAG_HIDDEN) == 0));
+    private static boolean isDisabledForAllUsers(List<UserPackage> userPackages) {
+        for (UserPackage userPackage : userPackages) {
+            if (userPackage.getPackageInfo() != null && userPackage.isEnabledPackage()) {
+                return false;
+            }
+        }
+        return true;
     }
 
     /**
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index cac9853..c3ef23b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -939,6 +939,12 @@
                 traceEnd();
             }
 
+            if (!disableNonCoreServices) {
+                traceBeginAndSlog("StartFontServiceManager");
+                mSystemServiceManager.startService(FontManagerService.Lifecycle.class);
+                traceEnd();
+            }
+
             if (!disableNonCoreServices && !disableTextServices) {
                 traceBeginAndSlog("StartTextServicesManager");
                 mSystemServiceManager.startService(TextServicesManagerService.Lifecycle.class);
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 167b33a..9835c88 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -566,6 +566,7 @@
     protected Map<String, PackageInfo> mInjectedPackages;
 
     protected Set<PackageWithUser> mUninstalledPackages;
+    protected Set<PackageWithUser> mEphemeralPackages;
     protected Set<String> mSystemPackages;
 
     protected PackageManager mMockPackageManager;
@@ -731,6 +732,7 @@
 
         mUninstalledPackages = new HashSet<>();
         mSystemPackages = new HashSet<>();
+        mEphemeralPackages = new HashSet<>();
 
         mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files");
 
@@ -1034,6 +1036,9 @@
         if (mUninstalledPackages.contains(PackageWithUser.of(userId, packageName))) {
             ret.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
         }
+        if (mEphemeralPackages.contains(PackageWithUser.of(userId, packageName))) {
+            ret.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_EPHEMERAL;
+        }
         if (mSystemPackages.contains(packageName)) {
             ret.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
         }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
index 9409b39..e6b4540f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerPresubmitTest.java
@@ -103,12 +103,10 @@
                 // if privapp permissions are enforced, platform permissions must be whitelisted
                 // in SystemConfig
                 if (platformPermission && RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
-                    assertTrue("Permission " + pName
-                                    + " should be declared in "
-                                    + "/etc/permissions/privapp-permissions-platform.xml "
-                                    + "or privapp-permissions-<device>.xml file for package "
+                    assertTrue("Permission " + pName + " should be declared in "
+                                    + "privapp-permissions-<category>.xml file for package "
                                     + packageName,
-                            privAppPermissions.contains(pName));
+                            privAppPermissions != null && privAppPermissions.contains(pName));
                 }
                 assertTrue("Permission " + pName + " should be granted to " + packageName, granted);
             }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index d25923c..562de414 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -46,6 +46,7 @@
 
 import com.android.frameworks.servicestests.R;
 import com.android.server.pm.ShortcutService.ConfigConstants;
+import com.android.server.pm.ShortcutUser.PackageWithUser;
 
 import java.io.File;
 import java.io.FileWriter;
@@ -2037,4 +2038,32 @@
         assertFalse(mService.isUserUnlockedL(USER_0));
         assertFalse(mService.isUserUnlockedL(USER_10));
     }
+
+    public void testEphemeralApp() {
+        mRunningUsers.put(USER_10, true); // this test needs user 10.
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertWith(mManager.getDynamicShortcuts()).isEmpty();
+        });
+        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+            assertWith(mManager.getDynamicShortcuts()).isEmpty();
+        });
+        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+            assertWith(mManager.getDynamicShortcuts()).isEmpty();
+        });
+        // Make package 1 ephemeral.
+        mEphemeralPackages.add(PackageWithUser.of(USER_0, CALLING_PACKAGE_1));
+
+        runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+            assertExpectException(IllegalStateException.class, "Ephemeral apps", () -> {
+                mManager.getDynamicShortcuts();
+            });
+        });
+        runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+            assertWith(mManager.getDynamicShortcuts()).isEmpty();
+        });
+        runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+            assertWith(mManager.getDynamicShortcuts()).isEmpty();
+        });
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
index 83a61ca..67e78d4 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/TestSystemImpl.java
@@ -19,25 +19,39 @@
 import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.webkit.UserPackage;
 import android.webkit.WebViewProviderInfo;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public class TestSystemImpl implements SystemInterface {
     private String mUserProvider = null;
     private final WebViewProviderInfo[] mPackageConfigs;
-    HashMap<String, PackageInfo> mPackages = new HashMap();
+    List<Integer> mUsers = new ArrayList<>();
+    // Package -> [user, package]
+    Map<String, Map<Integer, PackageInfo>> mPackages = new HashMap();
     private boolean mFallbackLogicEnabled;
     private final int mNumRelros;
     private final boolean mIsDebuggable;
     private int mMultiProcessSetting;
 
+    public static final int PRIMARY_USER_ID = 0;
+
     public TestSystemImpl(WebViewProviderInfo[] packageConfigs, boolean fallbackLogicEnabled,
             int numRelros, boolean isDebuggable) {
         mPackageConfigs = packageConfigs;
         mFallbackLogicEnabled = fallbackLogicEnabled;
         mNumRelros = numRelros;
         mIsDebuggable = isDebuggable;
+        mUsers.add(PRIMARY_USER_ID);
+    }
+
+    public void addUser(int userId) {
+        mUsers.add(userId);
     }
 
     @Override
@@ -78,17 +92,20 @@
 
     @Override
     public void enablePackageForAllUsers(Context context, String packageName, boolean enable) {
-        enablePackageForUser(packageName, enable, 0);
+        for(int userId : mUsers) {
+            enablePackageForUser(packageName, enable, userId);
+        }
     }
 
     @Override
     public void enablePackageForUser(String packageName, boolean enable, int userId) {
-        PackageInfo packageInfo = mPackages.get(packageName);
-        if (packageInfo == null) {
+        Map<Integer, PackageInfo> userPackages = mPackages.get(packageName);
+        if (userPackages == null) {
             throw new IllegalArgumentException("There is no package called " + packageName);
         }
+        PackageInfo packageInfo = userPackages.get(userId);
         packageInfo.applicationInfo.enabled = enable;
-        setPackageInfo(packageInfo);
+        setPackageInfoForUser(userId, packageInfo);
     }
 
     @Override
@@ -97,23 +114,61 @@
     @Override
     public PackageInfo getPackageInfoForProvider(WebViewProviderInfo info) throws
             NameNotFoundException {
-        PackageInfo ret = mPackages.get(info.packageName);
+        Map<Integer, PackageInfo> userPackages = mPackages.get(info.packageName);
+        if (userPackages == null) throw new NameNotFoundException(info.packageName);
+        PackageInfo ret = userPackages.get(PRIMARY_USER_ID);
         if (ret == null) throw new NameNotFoundException(info.packageName);
         return ret;
     }
 
-    public void setPackageInfo(PackageInfo pi) {
-        mPackages.put(pi.packageName, pi);
+    @Override
+    public List<UserPackage> getPackageInfoForProviderAllUsers(
+            Context context, WebViewProviderInfo info) {
+        Map<Integer, PackageInfo> userPackages = mPackages.get(info.packageName);
+        List<UserPackage> ret = new ArrayList();
+        // Loop over defined users, and find the corresponding package for each user.
+        for (int userId : mUsers) {
+            ret.add(new UserPackage(createUserInfo(userId),
+                    userPackages == null ? null : userPackages.get(userId)));
+        }
+        return ret;
     }
 
+    private static UserInfo createUserInfo(int userId) {
+        return new UserInfo(userId, "User nr. " + userId, 0 /* flags */);
+    }
+
+    /**
+     * Set package for primary user.
+     */
+    public void setPackageInfo(PackageInfo pi) {
+        setPackageInfoForUser(PRIMARY_USER_ID, pi);
+    }
+
+    public void setPackageInfoForUser(int userId, PackageInfo pi) {
+        if (!mUsers.contains(userId)) {
+            throw new IllegalArgumentException("User nr. " + userId + " doesn't exist");
+        }
+        if (!mPackages.containsKey(pi.packageName)) {
+            mPackages.put(pi.packageName, new HashMap<Integer, PackageInfo>());
+        }
+        mPackages.get(pi.packageName).put(userId, pi);
+    }
+
+    /**
+     * Removes the package {@param packageName} for the primary user.
+     */
     public void removePackageInfo(String packageName) {
-        mPackages.remove(packageName);
+        mPackages.get(packageName).remove(PRIMARY_USER_ID);
     }
 
     @Override
     public int getFactoryPackageVersion(String packageName) throws NameNotFoundException {
         PackageInfo pi = null;
-        pi = mPackages.get(packageName);
+        Map<Integer, PackageInfo> userPackages = mPackages.get(packageName);
+        if (userPackages == null) throw new NameNotFoundException();
+
+        pi = userPackages.get(PRIMARY_USER_ID);
         if (pi != null && pi.applicationInfo.isSystemApp()) {
             return pi.applicationInfo.versionCode;
         }
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index 0519448..33cedfa 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -92,9 +92,15 @@
     }
 
     private void setEnabledAndValidPackageInfos(WebViewProviderInfo[] providers) {
+        // Set package infos for the primary user (user 0).
+        setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, providers);
+    }
+
+    private void setEnabledAndValidPackageInfosForUser(int userId,
+            WebViewProviderInfo[] providers) {
         for(WebViewProviderInfo wpi : providers) {
-            mTestSystemImpl.setPackageInfo(createPackageInfo(wpi.packageName, true /* enabled */,
-                        true /* valid */, true /* installed */));
+            mTestSystemImpl.setPackageInfoForUser(userId, createPackageInfo(wpi.packageName,
+                    true /* enabled */, true /* valid */, true /* installed */));
         }
     }
 
@@ -335,7 +341,7 @@
         setEnabledAndValidPackageInfos(packages);
 
         mWebViewUpdateServiceImpl.packageStateChanged(singlePackage,
-                WebViewUpdateService.PACKAGE_ADDED, 0);
+                WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
 
         checkPreparationPhasesForPackage(singlePackage, 1 /* number of finished preparations */);
         assertEquals(singlePackage,
@@ -344,7 +350,7 @@
         // Remove the package again
         mTestSystemImpl.removePackageInfo(singlePackage);
         mWebViewUpdateServiceImpl.packageStateChanged(singlePackage,
-                WebViewUpdateService.PACKAGE_ADDED, 0);
+                WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
 
         // Package removed - ensure our interface states that there is no package
         response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
@@ -374,7 +380,7 @@
                 createPackageInfo(wpi.packageName, true /* enabled */, true /* valid */,
                     true /* installed */));
         mWebViewUpdateServiceImpl.packageStateChanged(wpi.packageName,
-                WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
+                WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
 
         checkPreparationPhasesForPackage(wpi.packageName, 1);
     }
@@ -429,16 +435,8 @@
             new WebViewProviderInfo(firstPackage, "", true, false, null),
             new WebViewProviderInfo(secondPackage, "", true, false, null)};
         setupWithPackages(packages);
-        if (settingsChange) {
-            // Have all packages be enabled, so that we can change provider however we want to
-            setEnabledAndValidPackageInfos(packages);
-        } else {
-            // Have all packages be disabled so that we can change one to enabled later
-            for(WebViewProviderInfo wpi : packages) {
-                mTestSystemImpl.setPackageInfo(createPackageInfo(wpi.packageName,
-                            false /* enabled */, true /* valid */, true /* installed */));
-            }
-        }
+        // Have all packages be enabled, so that we can change provider however we want to
+        setEnabledAndValidPackageInfos(packages);
 
         CountDownLatch countdown = new CountDownLatch(1);
 
@@ -457,8 +455,12 @@
                     mWebViewUpdateServiceImpl.waitForAndGetProvider();
                 assertEquals(WebViewFactory.LIBLOAD_SUCCESS, threadResponse.status);
                 assertEquals(secondPackage, threadResponse.packageInfo.packageName);
-                // Verify that we killed the first package
-                Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(firstPackage));
+                // Verify that we killed the first package if we performed a settings change -
+                // otherwise we had to disable the first package, in which case its dependents
+                // should have been killed by the framework.
+                if (settingsChange) {
+                    Mockito.verify(mTestSystemImpl).killPackageDependents(Mockito.eq(firstPackage));
+                }
                 countdown.countDown();
             }
         }).start();
@@ -470,11 +472,21 @@
         if (settingsChange) {
             mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
         } else {
-            // Switch provider by enabling the second one
+            // Enable the second provider
             mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
                         true /* valid */, true /* installed */));
             mWebViewUpdateServiceImpl.packageStateChanged(
-                    secondPackage, WebViewUpdateService.PACKAGE_CHANGED, 0);
+                    secondPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
+
+            // Ensure we haven't changed package yet.
+            assertEquals(firstPackage,
+                    mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName);
+
+            // Switch provider by disabling the first one
+            mTestSystemImpl.setPackageInfo(createPackageInfo(firstPackage, false /* enabled */,
+                        true /* valid */, true /* installed */));
+            mWebViewUpdateServiceImpl.packageStateChanged(
+                    firstPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
         }
         mWebViewUpdateServiceImpl.notifyRelroCreationCompleted();
         // first package done, should start on second
@@ -528,7 +540,7 @@
         mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
                         true /* valid */, true /* installed */));
         mWebViewUpdateServiceImpl.packageStateChanged(
-                fallbackPackage, WebViewUpdateService.PACKAGE_CHANGED, 0);
+                fallbackPackage, WebViewUpdateService.PACKAGE_CHANGED, TestSystemImpl.PRIMARY_USER_ID);
 
         if (fallbackLogicEnabled) {
             // Check that we have now disabled the fallback package twice
@@ -573,7 +585,7 @@
                 createPackageInfo(primaryPackage, true /* enabled */ , true /* valid */,
                     true /* installed */));
         mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
-                WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
+                WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
 
         // Verify fallback disabled, primary package used as provider, and fallback package killed
         Mockito.verify(mTestSystemImpl).uninstallAndDisablePackageForAllUsers(
@@ -583,7 +595,31 @@
     }
 
     @Test
-    public void testFallbackChangesEnabledState() {
+    public void testFallbackChangesEnabledStateSingleUser() {
+        for (PackageRemovalType removalType : REMOVAL_TYPES) {
+            checkFallbackChangesEnabledState(false /* multiUser */, removalType);
+        }
+    }
+
+    @Test
+    public void testFallbackChangesEnabledStateMultiUser() {
+        for (PackageRemovalType removalType : REMOVAL_TYPES) {
+            checkFallbackChangesEnabledState(true /* multiUser */, removalType);
+        }
+    }
+
+    /**
+     * Represents how to remove a package during a tests (disabling it / uninstalling it / hiding
+     * it).
+     */
+    private enum PackageRemovalType {
+        UNINSTALL, DISABLE, HIDE
+    }
+
+    private PackageRemovalType[] REMOVAL_TYPES = PackageRemovalType.class.getEnumConstants();
+
+    public void checkFallbackChangesEnabledState(boolean multiUser,
+            PackageRemovalType removalType) {
         String primaryPackage = "primary";
         String fallbackPackage = "fallback";
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
@@ -592,46 +628,68 @@
             new WebViewProviderInfo(
                     fallbackPackage, "", true /* default available */, true /* fallback */, null)};
         setupWithPackages(packages, true /* fallbackLogicEnabled */);
-        setEnabledAndValidPackageInfos(packages);
+        int secondaryUserId = 10;
+        int userIdToChangePackageFor = multiUser ? secondaryUserId : TestSystemImpl.PRIMARY_USER_ID;
+        if (multiUser) {
+            mTestSystemImpl.addUser(secondaryUserId);
+            setEnabledAndValidPackageInfosForUser(secondaryUserId, packages);
+        }
+        setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
 
         runWebViewBootPreparationOnMainSync();
 
         // Verify fallback disabled at boot when primary package enabled
-        Mockito.verify(mTestSystemImpl).enablePackageForUser(
-                Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
-                Matchers.anyInt());
+        checkEnablePackageForUserCalled(fallbackPackage, false, multiUser
+                ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
+                : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */);
 
         checkPreparationPhasesForPackage(primaryPackage, 1);
 
+        boolean enabled = !(removalType == PackageRemovalType.DISABLE);
+        boolean installed = !(removalType == PackageRemovalType.UNINSTALL);
+        boolean hidden = (removalType == PackageRemovalType.HIDE);
         // Disable primary package and ensure fallback becomes enabled and used
-        mTestSystemImpl.setPackageInfo(
-                createPackageInfo(primaryPackage, false /* enabled */, true /* valid */,
-                    true /* installed */));
+        mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
+                createPackageInfo(primaryPackage, enabled /* enabled */, true /* valid */,
+                    installed /* installed */, null /* signature */, 0 /* updateTime */,
+                    hidden /* hidden */));
         mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
-                WebViewUpdateService.PACKAGE_CHANGED, 0);
+                removalType == PackageRemovalType.DISABLE
+                ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_REMOVED,
+                userIdToChangePackageFor); // USER ID
 
-        Mockito.verify(mTestSystemImpl).enablePackageForUser(
-                Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */,
-                Matchers.anyInt());
+        checkEnablePackageForUserCalled(fallbackPackage, true, multiUser
+                ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
+                : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 1 /* numUsages */);
 
         checkPreparationPhasesForPackage(fallbackPackage, 1);
 
 
         // Again enable primary package and verify primary is used and fallback becomes disabled
-        mTestSystemImpl.setPackageInfo(
+        mTestSystemImpl.setPackageInfoForUser(userIdToChangePackageFor,
                 createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
                     true /* installed */));
         mWebViewUpdateServiceImpl.packageStateChanged(primaryPackage,
-                WebViewUpdateService.PACKAGE_CHANGED, 0);
+                removalType == PackageRemovalType.DISABLE
+                ? WebViewUpdateService.PACKAGE_CHANGED : WebViewUpdateService.PACKAGE_ADDED,
+                userIdToChangePackageFor);
 
         // Verify fallback is disabled a second time when primary package becomes enabled
-        Mockito.verify(mTestSystemImpl, Mockito.times(2)).enablePackageForUser(
-                Mockito.eq(fallbackPackage), Mockito.eq(false) /* enable */,
-                Matchers.anyInt());
+        checkEnablePackageForUserCalled(fallbackPackage, false, multiUser
+                ? new int[] {TestSystemImpl.PRIMARY_USER_ID, secondaryUserId}
+                : new int[] {TestSystemImpl.PRIMARY_USER_ID}, 2 /* numUsages */);
 
         checkPreparationPhasesForPackage(primaryPackage, 2);
     }
 
+    private void checkEnablePackageForUserCalled(String packageName, boolean expectEnabled,
+            int[] userIds, int numUsages) {
+        for (int userId : userIds) {
+            Mockito.verify(mTestSystemImpl, Mockito.times(numUsages)).enablePackageForUser(
+                    Mockito.eq(packageName), Mockito.eq(expectEnabled), Mockito.eq(userId));
+        }
+    }
+
     @Test
     public void testAddUserWhenFallbackLogicEnabled() {
         checkAddingNewUser(true);
@@ -651,8 +709,10 @@
             new WebViewProviderInfo(
                     fallbackPackage, "", true /* default available */, true /* fallback */, null)};
         setupWithPackages(packages, fallbackLogicEnabled);
-        setEnabledAndValidPackageInfos(packages);
+        setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
         int newUser = 100;
+        mTestSystemImpl.addUser(newUser);
+        setEnabledAndValidPackageInfosForUser(newUser, packages);
         mWebViewUpdateServiceImpl.handleNewUser(newUser);
         if (fallbackLogicEnabled) {
             // Verify fallback package becomes disabled for new user
@@ -668,6 +728,42 @@
     }
 
     /**
+     * Ensures that adding a new user for which the current WebView package is uninstalled causes a
+     * change of WebView provider.
+     */
+    @Test
+    public void testAddingNewUserWithUninstalledPackage() {
+        String primaryPackage = "primary";
+        String fallbackPackage = "fallback";
+        WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
+            new WebViewProviderInfo(
+                    primaryPackage, "", true /* default available */, false /* fallback */, null),
+            new WebViewProviderInfo(
+                    fallbackPackage, "", true /* default available */, true /* fallback */, null)};
+        setupWithPackages(packages, true /* fallbackLogicEnabled */);
+        setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
+        int newUser = 100;
+        mTestSystemImpl.addUser(newUser);
+        // Let the primary package be uninstalled for the new user
+        mTestSystemImpl.setPackageInfoForUser(newUser,
+                createPackageInfo(primaryPackage, true /* enabled */, true /* valid */,
+                        false /* installed */));
+        mTestSystemImpl.setPackageInfoForUser(newUser,
+                createPackageInfo(fallbackPackage, false /* enabled */, true /* valid */,
+                        true /* installed */));
+        mWebViewUpdateServiceImpl.handleNewUser(newUser);
+        // Verify fallback package doesn't become disabled for the primary user.
+        Mockito.verify(mTestSystemImpl, Mockito.never()).enablePackageForUser(
+                Mockito.anyObject(), Mockito.eq(false) /* enable */,
+                Mockito.eq(TestSystemImpl.PRIMARY_USER_ID) /* user */);
+        // Verify that we enable the fallback package for the secondary user.
+        Mockito.verify(mTestSystemImpl, Mockito.times(1)).enablePackageForUser(
+                Mockito.eq(fallbackPackage), Mockito.eq(true) /* enable */,
+                Mockito.eq(newUser) /* user */);
+        checkPreparationPhasesForPackage(fallbackPackage, 1 /* numRelros */);
+    }
+
+    /**
      * Timing dependent test where we verify that the list of valid webview packages becoming empty
      * at a certain point doesn't crash us or break our state.
      */
@@ -713,7 +809,7 @@
                     1 /* updateTime */ ));
 
         mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
-                WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
+                WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
 
         // Ensure we use firstPackage
         checkPreparationPhasesForPackage(firstPackage, 2 /* second preparation for this package */);
@@ -742,14 +838,14 @@
         mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
                     false /* valid */, true /* installed */));
         mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
-                WebViewUpdateService.PACKAGE_ADDED, 0);
+                WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
         checkPreparationPhasesForPackage(firstPackage, 2 /* second time for this package */);
 
         // Now make the second package valid again and verify that it is used again
         mTestSystemImpl.setPackageInfo(createPackageInfo(secondPackage, true /* enabled */,
                     true /* valid */, true /* installed */));
         mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
-                WebViewUpdateService.PACKAGE_ADDED, 0);
+                WebViewUpdateService.PACKAGE_ADDED, TestSystemImpl.PRIMARY_USER_ID);
         checkPreparationPhasesForPackage(secondPackage, 2 /* second time for this package */);
     }
 
@@ -820,7 +916,7 @@
             mWebViewUpdateServiceImpl.changeProviderAndSetting(secondPackage);
         } else {
             mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
-                    WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
+                    WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
         }
 
         WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
@@ -831,7 +927,7 @@
                     true /* valid */, true /* installed */));
 
         mWebViewUpdateServiceImpl.packageStateChanged(secondPackage,
-                WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
+                WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
 
 
         checkPreparationPhasesForPackage(secondPackage, 1);
@@ -863,11 +959,11 @@
                     createPackageInfo(firstPackage, true /* enabled */, false /* valid */,
                         true /* installed */));
             mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
-                    WebViewUpdateService.PACKAGE_ADDED_REPLACED, 0);
+                    WebViewUpdateService.PACKAGE_ADDED_REPLACED, TestSystemImpl.PRIMARY_USER_ID);
         } else {
             mTestSystemImpl.removePackageInfo(firstPackage);
             mWebViewUpdateServiceImpl.packageStateChanged(firstPackage,
-                    WebViewUpdateService.PACKAGE_REMOVED, 0);
+                    WebViewUpdateService.PACKAGE_REMOVED, TestSystemImpl.PRIMARY_USER_ID);
         }
 
         checkPreparationPhasesForPackage(secondPackage, 1);
@@ -1098,8 +1194,10 @@
         }
     }
 
-    // Ensure that the update service uses an uninstalled package if that is the only package
-    // available.
+    /**
+     * Ensure that the update service does use an uninstalled package when that is the only
+     * package available.
+     */
     @Test
     public void testWithSingleUninstalledPackage() {
         String testPackageName = "test.package.name";
@@ -1113,21 +1211,32 @@
         runWebViewBootPreparationOnMainSync();
 
         checkPreparationPhasesForPackage(testPackageName, 1 /* first preparation phase */);
+        // TODO(gsennton) change this logic to use the code below when we have created a functional
+        // stub.
+        //Mockito.verify(mTestSystemImpl, Mockito.never()).onWebViewProviderChanged(
+        //        Matchers.anyObject());
+        //WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider();
+        //assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status);
+        //assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage());
     }
 
     @Test
     public void testNonhiddenPackageUserOverHidden() {
-        checkVisiblePackageUserOverNonVisible(false /* true == uninstalled, false == hidden */);
+        checkVisiblePackageUserOverNonVisible(false /* multiUser*/, PackageRemovalType.HIDE);
+        checkVisiblePackageUserOverNonVisible(true /* multiUser*/, PackageRemovalType.HIDE);
     }
 
     @Test
     public void testInstalledPackageUsedOverUninstalled() {
-        checkVisiblePackageUserOverNonVisible(true /* true == uninstalled, false == hidden */);
+        checkVisiblePackageUserOverNonVisible(false /* multiUser*/, PackageRemovalType.UNINSTALL);
+        checkVisiblePackageUserOverNonVisible(true /* multiUser*/, PackageRemovalType.UNINSTALL);
     }
 
-    private void checkVisiblePackageUserOverNonVisible(boolean uninstalledNotHidden) {
-        boolean testUninstalled = uninstalledNotHidden;
-        boolean testHidden = !uninstalledNotHidden;
+    private void checkVisiblePackageUserOverNonVisible(boolean multiUser,
+            PackageRemovalType removalType) {
+        assert removalType != PackageRemovalType.DISABLE;
+        boolean testUninstalled = removalType == PackageRemovalType.UNINSTALL;
+        boolean testHidden = removalType == PackageRemovalType.HIDE;
         String installedPackage = "installedPackage";
         String uninstalledPackage = "uninstalledPackage";
         WebViewProviderInfo[] webviewPackages = new WebViewProviderInfo[] {
@@ -1137,11 +1246,25 @@
                     false /* fallback */, null)};
 
         setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
-        mTestSystemImpl.setPackageInfo(createPackageInfo(installedPackage, true /* enabled */,
-                    true /* valid */, true /* installed */));
-        mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
+        int secondaryUserId = 5;
+        if (multiUser) {
+            mTestSystemImpl.addUser(secondaryUserId);
+            // Install all packages for the primary user.
+            setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
+            mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(
+                    installedPackage, true /* enabled */, true /* valid */, true /* installed */));
+            // Hide or uninstall the primary package for the second user
+            mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
                     true /* valid */, (testUninstalled ? false : true) /* installed */,
                     null /* signatures */, 0 /* updateTime */, (testHidden ? true : false)));
+        } else {
+            mTestSystemImpl.setPackageInfo(createPackageInfo(installedPackage, true /* enabled */,
+                    true /* valid */, true /* installed */));
+            // Hide or uninstall the primary package
+            mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
+                    true /* valid */, (testUninstalled ? false : true) /* installed */,
+                    null /* signatures */, 0 /* updateTime */, (testHidden ? true : false)));
+        }
 
         runWebViewBootPreparationOnMainSync();
 
@@ -1160,9 +1283,7 @@
     }
 
     /**
-     * Ensure that we won't prioritize an uninstalled (or hidden) package even if it is user-chosen,
-     * and that an uninstalled (or hidden) package is not considered valid (in the
-     * getValidWebViewPackages() API).
+     * Ensure that we won't prioritize an uninstalled (or hidden) package even if it is user-chosen.
      */
     private void checkCantSwitchToNonVisiblePackage(boolean uninstalledNotHidden) {
         boolean testUninstalled = uninstalledNotHidden;
@@ -1176,27 +1297,31 @@
                     false /* fallback */, null)};
 
         setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
-        mTestSystemImpl.setPackageInfo(createPackageInfo(installedPackage, true /* enabled */,
-                    true /* valid */, true /* installed */));
-        mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
-                    true /* valid */, (testUninstalled ? false : true) /* installed */,
-                    null /* signatures */, 0 /* updateTime */,
-                    (testHidden ? true : false) /* hidden */));
+        int secondaryUserId = 412;
+        mTestSystemImpl.addUser(secondaryUserId);
+
+        // Let all packages be installed and enabled for the primary user.
+        setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
+        // Only uninstall the 'uninstalled package' for the secondary user.
+        mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(installedPackage,
+                true /* enabled */, true /* valid */, true /* installed */));
+        mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(uninstalledPackage,
+                true /* enabled */, true /* valid */, !testUninstalled /* installed */,
+                null /* signatures */, 0 /* updateTime */, testHidden /* hidden */));
 
         runWebViewBootPreparationOnMainSync();
 
         checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
 
-        // Ensure that only the installed package is considered valid
-        WebViewProviderInfo[] validPackages = mWebViewUpdateServiceImpl.getValidWebViewPackages();
-        assertEquals(1, validPackages.length);
-        assertEquals(installedPackage, validPackages[0].packageName);
-
         // ensure that we don't switch to the uninstalled package (it will be used if it becomes
         // installed later)
         assertEquals(installedPackage,
                 mWebViewUpdateServiceImpl.changeProviderAndSetting(uninstalledPackage));
 
+        // Ensure both packages are considered valid.
+        assertEquals(2, mWebViewUpdateServiceImpl.getValidWebViewPackages().length);
+
+
         // We should only have called onWebViewProviderChanged once (before calling
         // changeProviderAndSetting
         Mockito.verify(mTestSystemImpl, Mockito.times(1)).onWebViewProviderChanged(
@@ -1227,12 +1352,16 @@
                     false /* fallback */, null)};
 
         setupWithPackages(webviewPackages, true /* fallback logic enabled */, 1 /* numRelros */);
-        mTestSystemImpl.setPackageInfo(createPackageInfo(installedPackage, true /* enabled */,
-                    true /* valid */, true /* installed */));
-        mTestSystemImpl.setPackageInfo(createPackageInfo(uninstalledPackage, true /* enabled */,
-                    true /* valid */, (testUninstalled ? false : true) /* installed */,
-                    null /* signatures */, 0 /* updateTime */,
-                    (testHidden ? true : false) /* hidden */));
+        int secondaryUserId = 4;
+        mTestSystemImpl.addUser(secondaryUserId);
+
+        setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, webviewPackages);
+        mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(installedPackage,
+                true /* enabled */, true /* valid */, true /* installed */));
+        mTestSystemImpl.setPackageInfoForUser(secondaryUserId, createPackageInfo(uninstalledPackage,
+                true /* enabled */, true /* valid */,
+                (testUninstalled ? false : true) /* installed */, null /* signatures */,
+                0 /* updateTime */, (testHidden ? true : false) /* hidden */));
 
         // Start with the setting pointing to the uninstalled package
         mTestSystemImpl.updateUserSetting(null, uninstalledPackage);
@@ -1242,12 +1371,21 @@
         checkPreparationPhasesForPackage(installedPackage, 1 /* first preparation phase */);
     }
 
+    @Test
+    public void testFallbackEnabledIfPrimaryUninstalledSingleUser() {
+        checkFallbackEnabledIfPrimaryUninstalled(false /* multiUser */);
+    }
+
+    @Test
+    public void testFallbackEnabledIfPrimaryUninstalledMultiUser() {
+        checkFallbackEnabledIfPrimaryUninstalled(true /* multiUser */);
+    }
+
     /**
-     * Ensures that fallback becomes enabled if the primary package is uninstalled for the current
+     * Ensures that fallback becomes enabled at boot if the primary package is uninstalled for some
      * user.
      */
-    @Test
-    public void testFallbackEnabledIfPrimaryUninstalled() {
+    private void checkFallbackEnabledIfPrimaryUninstalled(boolean multiUser) {
         String primaryPackage = "primary";
         String fallbackPackage = "fallback";
         WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
@@ -1256,10 +1394,24 @@
             new WebViewProviderInfo(
                     fallbackPackage, "", true /* default available */, true /* fallback */, null)};
         setupWithPackages(packages, true /* fallback logic enabled */);
-        mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
+        int secondaryUserId = 5;
+        if (multiUser) {
+            mTestSystemImpl.addUser(secondaryUserId);
+            // Install all packages for the primary user.
+            setEnabledAndValidPackageInfosForUser(TestSystemImpl.PRIMARY_USER_ID, packages);
+            // Only install fallback package for secondary user.
+            mTestSystemImpl.setPackageInfoForUser(secondaryUserId,
+                    createPackageInfo(primaryPackage, true /* enabled */,
+                            true /* valid */, false /* installed */));
+            mTestSystemImpl.setPackageInfoForUser(secondaryUserId,
+                    createPackageInfo(fallbackPackage, false /* enabled */,
+                            true /* valid */, true /* installed */));
+        } else {
+            mTestSystemImpl.setPackageInfo(createPackageInfo(primaryPackage, true /* enabled */,
                     true /* valid */, false /* installed */));
-        mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, true /* enabled */,
+            mTestSystemImpl.setPackageInfo(createPackageInfo(fallbackPackage, false /* enabled */,
                     true /* valid */, true /* installed */));
+        }
 
         runWebViewBootPreparationOnMainSync();
         // Verify that we enable the fallback package
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 00e8f9f..ba7b6a1 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -58,12 +58,15 @@
      * Input: get*Extra field {@link #EXTRA_PHONE_ACCOUNT_HANDLE} contains the component name of the
      * {@link android.telecom.ConnectionService} that Telecom should bind to. Telecom will then
      * ask the connection service for more information about the call prior to showing any UI.
+     *
+     * @deprecated Use {@link #addNewIncomingCall} instead.
      */
     public static final String ACTION_INCOMING_CALL = "android.telecom.action.INCOMING_CALL";
 
     /**
      * Similar to {@link #ACTION_INCOMING_CALL}, but is used only by Telephony to add a new
      * sim-initiated MO call for carrier testing.
+     * @deprecated Use {@link #addNewUnknownCall} instead.
      * @hide
      */
     public static final String ACTION_NEW_UNKNOWN_CALL = "android.telecom.action.NEW_UNKNOWN_CALL";
diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
index 50efc7f..d0c9599 100644
--- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java
@@ -16,6 +16,7 @@
 
 package android.graphics;
 
+import android.text.FontConfig;
 import com.android.ide.common.rendering.api.AssetRepository;
 import com.android.ide.common.rendering.api.LayoutLog;
 import com.android.layoutlib.bridge.Bridge;
@@ -284,7 +285,7 @@
 
     @LayoutlibDelegate
     /*package*/ static boolean nAddFontWeightStyle(long nativeFamily, ByteBuffer font,
-            int ttcIndex, List<FontListParser.Axis> listOfAxis,
+            int ttcIndex, List<FontConfig.Axis> listOfAxis,
             int weight, boolean isItalic) {
         assert false : "The only client of this method has been overriden.";
         return false;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index 5cd34f6..6e337d5 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -16,6 +16,7 @@
 
 package android.graphics;
 
+import android.text.FontConfig;
 import com.android.layoutlib.bridge.impl.DelegateManager;
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 
@@ -208,12 +209,12 @@
     }
 
     @LayoutlibDelegate
-    /*package*/ static FontFamily makeFamilyFromParsed(FontListParser.Family family,
+    /*package*/ static FontFamily makeFamilyFromParsed(FontConfig.Family family,
             Map<String, ByteBuffer> bufferForPath) {
-        FontFamily fontFamily = new FontFamily(family.lang, family.variant);
-        for (FontListParser.Font font : family.fonts) {
-            FontFamily_Delegate.addFont(fontFamily.mNativePtr, font.fontName, font.weight,
-                    font.isItalic);
+        FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
+        for (FontConfig.Font font : family.getFonts()) {
+            FontFamily_Delegate.addFont(fontFamily.mNativePtr, font.getFontName(),
+                    font.getWeight(), font.isItalic());
         }
         return fontFamily;
     }
