diff --git a/res/layout/lists_fragment.xml b/res/layout/lists_fragment.xml
index 26f62c7..98a1422 100644
--- a/res/layout/lists_fragment.xml
+++ b/res/layout/lists_fragment.xml
@@ -14,84 +14,79 @@
      limitations under the License.
 -->
 
-<com.android.dialer.widget.OverlappingPaneLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/lists_frame"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:animateLayoutChanges="true" >
 
-    <!-- TODO: Apply background color to ActionBar instead of a FrameLayout. For now, this is the
-         easiest way to preserve correct pane scrolling and searchbar collapse/expand behaviors. -->
-    <FrameLayout
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="@dimen/action_bar_height_large"
-        android:background="@color/actionbar_background_color" />
+        android:layout_height="match_parent"
+        android:orientation="vertical">
 
-    <FrameLayout
+        <!-- TODO: Apply background color to ActionBar instead of a FrameLayout. For now, this is
+             the easiest way to preserve correct pane scrolling and searchbar collapse/expand
+             behaviors. -->
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/action_bar_height_large"
+            android:background="@color/actionbar_background_color" />
+
+        <com.android.contacts.common.list.ViewPagerTabs
+            android:id="@+id/lists_pager_header"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/tab_height"
+            android:textAllCaps="true"
+            android:orientation="horizontal"
+            android:layout_gravity="top"
+            android:elevation="@dimen/tab_elevation"
+            style="@style/DialtactsActionBarTabTextStyle" />
+
+        <android.support.v4.view.ViewPager
+            android:id="@+id/lists_pager"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <com.android.dialer.list.RemoveView
+        android:id="@+id/remove_view"
         android:layout_width="match_parent"
-        android:layout_height="match_parent">
+        android:layout_height="@dimen/tab_height"
+        android:layout_alignParentTop="true" >
 
         <LinearLayout
-            android:layout_width="match_parent"
+            android:id="@+id/remove_view_content"
             android:layout_height="match_parent"
-            android:orientation="vertical">
+            android:layout_width="match_parent"
+            android:background="@color/actionbar_background_color"
+            android:gravity="center"
+            android:orientation="horizontal"
+            android:visibility="gone" >
 
-            <com.android.contacts.common.list.ViewPagerTabs
-                android:id="@+id/lists_pager_header"
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/tab_height"
-                android:textAllCaps="true"
-                android:orientation="horizontal"
-                android:layout_gravity="top"
-                android:elevation="@dimen/tab_elevation"
-                style="@style/DialtactsActionBarTabTextStyle" />
+            <ImageView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="8dp"
+                android:layout_marginBottom="8dp"
+                android:id="@+id/remove_view_icon"
+                android:src="@drawable/ic_remove"
+                android:contentDescription="@string/remove_contact"
+                android:tint="@color/remove_text_color" />
 
-            <android.support.v4.view.ViewPager
-                android:id="@+id/lists_pager"
-                android:layout_width="match_parent"
-                android:layout_height="0dp"
-                android:layout_weight="1" />
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/remove_view_text"
+                android:textSize="@dimen/remove_text_size"
+                android:textColor="@color/remove_text_color"
+                android:text="@string/remove_contact" />
 
         </LinearLayout>
 
-        <com.android.dialer.list.RemoveView
-            android:id="@+id/remove_view"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/tab_height"
-            android:layout_alignParentTop="true" >
+    </com.android.dialer.list.RemoveView >
 
-            <LinearLayout
-                android:id="@+id/remove_view_content"
-                android:layout_height="match_parent"
-                android:layout_width="match_parent"
-                android:background="@color/actionbar_background_color"
-                android:gravity="center"
-                android:orientation="horizontal"
-                android:visibility="gone" >
-
-                <ImageView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginTop="8dp"
-                    android:layout_marginBottom="8dp"
-                    android:id="@+id/remove_view_icon"
-                    android:src="@drawable/ic_remove"
-                    android:contentDescription="@string/remove_contact"
-                    android:tint="@color/remove_text_color" />
-
-                <TextView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:id="@+id/remove_view_text"
-                    android:textSize="@dimen/remove_text_size"
-                    android:textColor="@color/remove_text_color"
-                    android:text="@string/remove_contact" />
-
-            </LinearLayout>
-
-        </com.android.dialer.list.RemoveView >
-
-    </FrameLayout>
-
-</com.android.dialer.widget.OverlappingPaneLayout>
+</FrameLayout>
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 7da13f3..61aeed5 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -1113,9 +1113,6 @@
      */
     @Override
     public void onDragStarted(int x, int y, PhoneFavoriteSquareTileView view) {
-        if (mListsFragment.isPaneOpen()) {
-            mActionBarController.setAlpha(ListsFragment.REMOVE_VIEW_SHOWN_ALPHA);
-        }
         mListsFragment.showRemoveView(true);
     }
 
@@ -1128,9 +1125,6 @@
      */
     @Override
     public void onDragFinished(int x, int y) {
-        if (mListsFragment.isPaneOpen()) {
-            mActionBarController.setAlpha(ListsFragment.REMOVE_VIEW_HIDDEN_ALPHA);
-        }
         mListsFragment.showRemoveView(false);
     }
 
diff --git a/src/com/android/dialer/list/ListsFragment.java b/src/com/android/dialer/list/ListsFragment.java
index 098b647..45b2f68 100644
--- a/src/com/android/dialer/list/ListsFragment.java
+++ b/src/com/android/dialer/list/ListsFragment.java
@@ -31,8 +31,6 @@
 import com.android.dialer.calllog.ContactInfoHelper;
 import com.android.dialer.util.DialerUtils;
 import com.android.dialer.widget.ActionBarController;
-import com.android.dialer.widget.OverlappingPaneLayout;
-import com.android.dialer.widget.OverlappingPaneLayout.PanelSlideCallbacks;
 import com.android.dialerbind.ObjectFactory;
 
 import java.util.ArrayList;
@@ -64,9 +62,6 @@
     private static final String KEY_LAST_DISMISSED_CALL_SHORTCUT_DATE =
             "key_last_dismissed_call_shortcut_date";
 
-    public static final float REMOVE_VIEW_SHOWN_ALPHA = 0.5f;
-    public static final float REMOVE_VIEW_HIDDEN_ALPHA = 1;
-
     public interface HostInterface {
         public void showCallHistory();
         public ActionBarController getActionBarController();
@@ -88,9 +83,6 @@
 
     private CallLogAdapter mCallLogAdapter;
     private CallLogQueryHandler mCallLogQueryHandler;
-    private OverlappingPaneLayout mOverlappingPaneLayout;
-
-    private boolean mIsPanelOpen = true;
 
     /**
      * Call shortcuts older than this date (persisted in shared preferences) will not show up in
@@ -103,64 +95,6 @@
      */
     private long mCurrentCallShortcutDate = 0;
 
-    private PanelSlideCallbacks mPanelSlideCallbacks = new PanelSlideCallbacks() {
-        @Override
-        public void onPanelSlide(View panel, float slideOffset) {
-            if (mActionBar != null) {
-                ActionBarController controller =
-                        ((HostInterface) getActivity()).getActionBarController();
-                controller.setHideOffset((int) (mActionBar.getHeight() * (1 - slideOffset)));
-
-                if (!mActionBar.isShowing()) {
-                    mActionBar.show();
-                }
-            }
-        }
-
-        @Override
-        public void onPanelOpened(View panel) {
-            if (DEBUG) {
-                Log.d(TAG, "onPanelOpened");
-            }
-            mIsPanelOpen = true;
-        }
-
-        @Override
-        public void onPanelClosed(View panel) {
-            if (DEBUG) {
-                Log.d(TAG, "onPanelClosed");
-            }
-            mIsPanelOpen = false;
-        }
-
-        @Override
-        public void onPanelFlingReachesEdge(int velocityY) {
-            if (getCurrentListView() != null) {
-                getCurrentListView().fling(velocityY);
-            }
-        }
-
-        @Override
-        public boolean isScrollableChildUnscrolled() {
-            final AbsListView listView = getCurrentListView();
-            return listView != null && (listView.getChildCount() == 0
-                    || listView.getChildAt(0).getTop() == listView.getPaddingTop());
-        }
-    };
-
-    private AbsListView getCurrentListView() {
-        final int position = mViewPager.getCurrentItem();
-        switch (getRtlPosition(position)) {
-            case TAB_INDEX_SPEED_DIAL:
-                return mSpeedDialFragment == null ? null : mSpeedDialFragment.getListView();
-            case TAB_INDEX_RECENTS:
-                return mRecentsFragment == null ? null : mRecentsFragment.getListView();
-            case TAB_INDEX_ALL_CONTACTS:
-                return mAllContactsFragment == null ? null : mAllContactsFragment.getListView();
-        }
-        throw new IllegalStateException("No fragment at position " + position);
-    }
-
     public class ViewPagerAdapter extends FragmentPagerAdapter {
         public ViewPagerAdapter(FragmentManager fm) {
             super(fm);
@@ -293,8 +227,6 @@
         mRemoveView = (RemoveView) parentView.findViewById(R.id.remove_view);
         mRemoveViewContent = parentView.findViewById(R.id.remove_view_content);
 
-        setupPaneLayout((OverlappingPaneLayout) parentView);
-        mOverlappingPaneLayout = (OverlappingPaneLayout) parentView;
         Trace.endSection();
         Trace.endSection();
         return parentView;
@@ -316,10 +248,6 @@
 
         mCallLogAdapter.changeCursor(cursor);
 
-        // Refresh the overlapping pane to ensure that any changes in the shortcut card height
-        // are appropriately reflected in the overlap position.
-        mOverlappingPaneLayout.refresh();
-
         // Return true; took ownership of cursor
         return true;
     }
@@ -368,21 +296,8 @@
     }
 
     public boolean shouldShowActionBar() {
-        return mIsPanelOpen && mActionBar != null;
-    }
-
-    public boolean isPaneOpen() {
-        return mIsPanelOpen;
-    }
-
-    private void setupPaneLayout(OverlappingPaneLayout paneLayout) {
-        // TODO: Remove the notion of a capturable view. The entire view be slideable, once
-        // the framework better supports nested scrolling.
-        paneLayout.setCapturableView(mViewPagerTabs);
-        paneLayout.openPane();
-        paneLayout.setPanelSlideCallbacks(mPanelSlideCallbacks);
-        paneLayout.setIntermediatePinnedOffset(
-                ((HostInterface) getActivity()).getActionBarController().getActionBarHeight());
+        // TODO: Update this based on scroll state.
+        return mActionBar != null;
     }
 
     public SpeedDialFragment getSpeedDialFragment() {
diff --git a/src/com/android/dialer/widget/OverlappingPaneLayout.java b/src/com/android/dialer/widget/OverlappingPaneLayout.java
deleted file mode 100644
index 167b849..0000000
--- a/src/com/android/dialer/widget/OverlappingPaneLayout.java
+++ /dev/null
@@ -1,1358 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dialer.widget;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.v4.view.AccessibilityDelegateCompat;
-import android.support.v4.view.MotionEventCompat;
-import android.support.v4.view.ViewCompat;
-import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.view.accessibility.AccessibilityEvent;
-
-/**
- * A custom layout that aligns its child views vertically as two panes, and allows for the bottom
- * pane to be dragged upwards to overlap and hide the top pane. This layout is adapted from
- * {@link android.support.v4.widget.SlidingPaneLayout}.
- */
-public class OverlappingPaneLayout extends ViewGroup {
-    private static final String TAG = "SlidingPaneLayout";
-    private static final boolean DEBUG = false;
-
-    /**
-     * Default size of the overhang for a pane in the open state.
-     * At least this much of a sliding pane will remain visible.
-     * This indicates that there is more content available and provides
-     * a "physical" edge to grab to pull it closed.
-     */
-    private static final int DEFAULT_OVERHANG_SIZE = 32; // dp;
-
-    /**
-     * If no fade color is given by default it will fade to 80% gray.
-     */
-    private static final int DEFAULT_FADE_COLOR = 0xcccccccc;
-
-    /**
-     * Minimum velocity that will be detected as a fling
-     */
-    private static final int MIN_FLING_VELOCITY = 400; // dips per second
-
-    /**
-     * The size of the overhang in pixels.
-     * This is the minimum section of the sliding panel that will
-     * be visible in the open state to allow for a closing drag.
-     */
-    private final int mOverhangSize;
-
-    /**
-     * True if a panel can slide with the current measurements
-     */
-    private boolean mCanSlide;
-
-    /**
-     * The child view that can slide, if any.
-     */
-    private View mSlideableView;
-
-    /**
-     * The view that can be used to start the drag with.
-     */
-    private View mCapturableView;
-
-    /**
-     * How far the panel is offset from its closed position.
-     * range [0, 1] where 0 = closed, 1 = open.
-     */
-    private float mSlideOffset;
-
-    /**
-     * How far the panel is offset from its closed position, in pixels.
-     * range [0, {@link #mSlideRange}] where 0 is completely closed.
-     */
-    private int mSlideOffsetPx;
-
-    /**
-     * How far in pixels the slideable panel may move.
-     */
-    private int mSlideRange;
-
-    /**
-     * A panel view is locked into internal scrolling or another condition that
-     * is preventing a drag.
-     */
-    private boolean mIsUnableToDrag;
-
-    /**
-     * Tracks whether or not a child view is in the process of a nested scroll.
-     */
-    private boolean mIsInNestedScroll;
-
-    /**
-     * Indicates that the layout is currently in the process of a nested pre-scroll operation where
-     * the child scrolling view is being dragged downwards.
-     */
-    private boolean mInNestedPreScrollDownwards;
-
-    /**
-     * Indicates that the layout is currently in the process of a nested pre-scroll operation where
-     * the child scrolling view is being dragged upwards.
-     */
-    private boolean mInNestedPreScrollUpwards;
-
-    /**
-     * Indicates that the layout is currently in the process of a fling initiated by a pre-fling
-     * from the child scrolling view.
-     */
-    private boolean mIsInNestedFling;
-
-    /**
-     * Indicates the direction of the pre fling. We need to store this information since
-     * OverScoller doesn't expose the direction of its velocity.
-     */
-    private boolean mInUpwardsPreFling;
-
-    /**
-     * Stores an offset used to represent a point somewhere in between the panel's fully closed
-     * state and fully opened state where the panel can be temporarily pinned or opened up to
-     * during scrolling.
-     */
-    private int mIntermediateOffset = 0;
-
-    private float mInitialMotionX;
-    private float mInitialMotionY;
-
-    private PanelSlideCallbacks mPanelSlideCallbacks;
-
-    private final ViewDragHelper mDragHelper;
-
-    /**
-     * Stores whether or not the pane was open the last time it was slideable.
-     * If open/close operations are invoked this state is modified. Used by
-     * instance state save/restore.
-     */
-    private boolean mPreservedOpenState;
-    private boolean mFirstLayout = true;
-
-    private final Rect mTmpRect = new Rect();
-
-    /**
-     * How many dips we need to scroll past a position before we can snap to the next position
-     * on release. Using this prevents accidentally snapping to positions.
-     *
-     * This is needed since vertical nested scrolling can be passed to this class even if the
-     * vertical scroll is less than the the nested list's touch slop.
-     */
-    private final int mReleaseScrollSlop;
-
-    /**
-     * Callbacks for interacting with sliding panes.
-     */
-    public interface PanelSlideCallbacks {
-        /**
-         * Called when a sliding pane's position changes.
-         * @param panel The child view that was moved
-         * @param slideOffset The new offset of this sliding pane within its range, from 0-1
-         */
-        public void onPanelSlide(View panel, float slideOffset);
-        /**
-         * Called when a sliding pane becomes slid completely open. The pane may or may not
-         * be interactive at this point depending on how much of the pane is visible.
-         * @param panel The child view that was slid to an open position, revealing other panes
-         */
-        public void onPanelOpened(View panel);
-
-        /**
-         * Called when a sliding pane becomes slid completely closed. The pane is now guaranteed
-         * to be interactive. It may now obscure other views in the layout.
-         * @param panel The child view that was slid to a closed position
-         */
-        public void onPanelClosed(View panel);
-
-        /**
-         * Called when a sliding pane is flung as far open/closed as it can be.
-         * @param velocityY Velocity of the panel once its fling goes as far as it can.
-         */
-        public void onPanelFlingReachesEdge(int velocityY);
-
-        /**
-         * Returns true if the second panel's contents haven't been scrolled at all. This value is
-         * used to determine whether or not we can fully expand the header on downwards scrolls.
-         *
-         * Instead of using this callback, it would be preferable to instead fully expand the header
-         * on a View#onNestedFlingOver() callback. The behavior would be nicer. Unfortunately,
-         * no such callback exists yet (b/17547693).
-         */
-        public boolean isScrollableChildUnscrolled();
-    }
-
-    public OverlappingPaneLayout(Context context) {
-        this(context, null);
-    }
-
-    public OverlappingPaneLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public OverlappingPaneLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        final float density = context.getResources().getDisplayMetrics().density;
-        mOverhangSize = (int) (DEFAULT_OVERHANG_SIZE * density + 0.5f);
-
-        setWillNotDraw(false);
-
-        ViewCompat.setAccessibilityDelegate(this, new AccessibilityDelegate());
-
-        mDragHelper = ViewDragHelper.create(this, 0.5f, new DragHelperCallback());
-        mDragHelper.setMinVelocity(MIN_FLING_VELOCITY * density);
-
-        mReleaseScrollSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
-    }
-
-    /**
-     * Set an offset, somewhere in between the panel's fully closed state and fully opened state,
-     * where the panel can be temporarily pinned or opened up to.
-     *
-     * @param offset Offset in pixels
-     */
-    public void setIntermediatePinnedOffset(int offset) {
-        mIntermediateOffset = offset;
-    }
-
-    /**
-     * Set the view that can be used to start dragging the sliding pane.
-     */
-    public void setCapturableView(View capturableView) {
-        mCapturableView = capturableView;
-    }
-
-    public void setPanelSlideCallbacks(PanelSlideCallbacks listener) {
-        mPanelSlideCallbacks = listener;
-    }
-
-    void dispatchOnPanelSlide(View panel) {
-        mPanelSlideCallbacks.onPanelSlide(panel, mSlideOffset);
-    }
-
-    void dispatchOnPanelOpened(View panel) {
-        mPanelSlideCallbacks.onPanelOpened(panel);
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-    }
-
-    void dispatchOnPanelClosed(View panel) {
-        mPanelSlideCallbacks.onPanelClosed(panel);
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
-    }
-
-    void updateObscuredViewsVisibility(View panel) {
-        final int startBound = getPaddingTop();
-        final int endBound = getHeight() - getPaddingBottom();
-
-        final int leftBound = getPaddingLeft();
-        final int rightBound = getWidth() - getPaddingRight();
-        final int left;
-        final int right;
-        final int top;
-        final int bottom;
-        if (panel != null && viewIsOpaque(panel)) {
-            left = panel.getLeft();
-            right = panel.getRight();
-            top = panel.getTop();
-            bottom = panel.getBottom();
-        } else {
-            left = right = top = bottom = 0;
-        }
-
-        for (int i = 0, childCount = getChildCount(); i < childCount; i++) {
-            final View child = getChildAt(i);
-
-            if (child == panel) {
-                // There are still more children above the panel but they won't be affected.
-                break;
-            }
-
-            final int clampedChildLeft = Math.max(leftBound, child.getLeft());
-            final int clampedChildRight = Math.min(rightBound, child.getRight());
-            final int clampedChildTop = Math.max(startBound, child.getTop());
-            final int clampedChildBottom = Math.min(endBound, child.getBottom());
-
-            final int vis;
-            if (clampedChildLeft >= left && clampedChildTop >= top &&
-                    clampedChildRight <= right && clampedChildBottom <= bottom) {
-                vis = INVISIBLE;
-            } else {
-                vis = VISIBLE;
-            }
-            child.setVisibility(vis);
-        }
-    }
-
-    void setAllChildrenVisible() {
-        for (int i = 0, childCount = getChildCount(); i < childCount; i++) {
-            final View child = getChildAt(i);
-            if (child.getVisibility() == INVISIBLE) {
-                child.setVisibility(VISIBLE);
-            }
-        }
-    }
-
-    private static boolean viewIsOpaque(View v) {
-        if (ViewCompat.isOpaque(v)) return true;
-
-        final Drawable bg = v.getBackground();
-        if (bg != null) {
-            return bg.getOpacity() == PixelFormat.OPAQUE;
-        }
-        return false;
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        mFirstLayout = true;
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mFirstLayout = true;
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-
-        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
-        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
-
-        if (widthMode != MeasureSpec.EXACTLY) {
-            if (isInEditMode()) {
-                // Don't crash the layout editor. Consume all of the space if specified
-                // or pick a magic number from thin air otherwise.
-                // TODO Better communication with tools of this bogus state.
-                // It will crash on a real device.
-                if (widthMode == MeasureSpec.AT_MOST) {
-                    widthMode = MeasureSpec.EXACTLY;
-                } else if (widthMode == MeasureSpec.UNSPECIFIED) {
-                    widthMode = MeasureSpec.EXACTLY;
-                    widthSize = 300;
-                }
-            } else {
-                throw new IllegalStateException("Width must have an exact value or MATCH_PARENT");
-            }
-        } else if (heightMode == MeasureSpec.UNSPECIFIED) {
-            if (isInEditMode()) {
-                // Don't crash the layout editor. Pick a magic number from thin air instead.
-                // TODO Better communication with tools of this bogus state.
-                // It will crash on a real device.
-                if (heightMode == MeasureSpec.UNSPECIFIED) {
-                    heightMode = MeasureSpec.AT_MOST;
-                    heightSize = 300;
-                }
-            } else {
-                throw new IllegalStateException("Height must not be UNSPECIFIED");
-            }
-        }
-
-        int layoutWidth = 0;
-        int maxLayoutWidth = -1;
-        switch (widthMode) {
-            case MeasureSpec.EXACTLY:
-                layoutWidth = maxLayoutWidth = widthSize - getPaddingLeft() - getPaddingRight();
-                break;
-            case MeasureSpec.AT_MOST:
-                maxLayoutWidth = widthSize - getPaddingLeft() - getPaddingRight();
-                break;
-        }
-
-        float weightSum = 0;
-        boolean canSlide = false;
-        final int heightAvailable = heightSize - getPaddingTop() - getPaddingBottom();
-        int heightRemaining = heightAvailable;
-        final int childCount = getChildCount();
-
-        if (childCount > 2) {
-            Log.e(TAG, "onMeasure: More than two child views are not supported.");
-        }
-
-        // We'll find the current one below.
-        mSlideableView = null;
-
-        // First pass. Measure based on child LayoutParams width/height.
-        // Weight will incur a second pass.
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            if (child.getVisibility() == GONE) {
-                continue;
-            }
-
-            if (lp.weight > 0) {
-                weightSum += lp.weight;
-
-                // If we have no height, weight is the only contributor to the final size.
-                // Measure this view on the weight pass only.
-                if (lp.height == 0) continue;
-            }
-
-            int childHeightSpec;
-            final int verticalMargin = lp.topMargin + lp.bottomMargin;
-            if (lp.height == LayoutParams.WRAP_CONTENT) {
-                childHeightSpec = MeasureSpec.makeMeasureSpec(heightAvailable - verticalMargin,
-                        MeasureSpec.AT_MOST);
-            } else if (lp.height == LayoutParams.MATCH_PARENT) {
-                childHeightSpec = MeasureSpec.makeMeasureSpec(heightAvailable - verticalMargin,
-                        MeasureSpec.EXACTLY);
-            } else {
-                childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
-            }
-
-            int childWidthSpec;
-            if (lp.width == LayoutParams.WRAP_CONTENT) {
-                childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.AT_MOST);
-            } else if (lp.width == LayoutParams.MATCH_PARENT) {
-                childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.EXACTLY);
-            } else {
-                childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
-            }
-
-            child.measure(childWidthSpec, childHeightSpec);
-            final int childWidth = child.getMeasuredWidth();
-            final int childHeight = child.getMeasuredHeight();
-
-            if (widthMode == MeasureSpec.AT_MOST && childWidth > layoutWidth) {
-                layoutWidth = Math.min(childWidth, maxLayoutWidth);
-            }
-
-            heightRemaining -= childHeight;
-            canSlide |= lp.slideable = heightRemaining < 0;
-            if (lp.slideable) {
-                mSlideableView = child;
-            }
-        }
-
-        // Resolve weight and make sure non-sliding panels are smaller than the full screen.
-        if (canSlide || weightSum > 0) {
-            final int fixedPanelHeightLimit = heightAvailable - mOverhangSize;
-
-            for (int i = 0; i < childCount; i++) {
-                final View child = getChildAt(i);
-
-                if (child.getVisibility() == GONE) {
-                    continue;
-                }
-
-                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-                if (child.getVisibility() == GONE) {
-                    continue;
-                }
-
-                final boolean skippedFirstPass = lp.height == 0 && lp.weight > 0;
-                final int measuredHeight = skippedFirstPass ? 0 : child.getMeasuredHeight();
-                if (canSlide && child != mSlideableView) {
-                    if (lp.height < 0 && (measuredHeight > fixedPanelHeightLimit || lp.weight > 0)) {
-                        // Fixed panels in a sliding configuration should
-                        // be clamped to the fixed panel limit.
-                        final int childWidthSpec;
-                        if (skippedFirstPass) {
-                            // Do initial width measurement if we skipped measuring this view
-                            // the first time around.
-                            if (lp.width == LayoutParams.WRAP_CONTENT) {
-                                childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth,
-                                        MeasureSpec.AT_MOST);
-                            } else if (lp.height == LayoutParams.MATCH_PARENT) {
-                                childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth,
-                                        MeasureSpec.EXACTLY);
-                            } else {
-                                childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width,
-                                        MeasureSpec.EXACTLY);
-                            }
-                        } else {
-                            childWidthSpec = MeasureSpec.makeMeasureSpec(
-                                    child.getMeasuredWidth(), MeasureSpec.EXACTLY);
-                        }
-                        final int childHeightSpec = MeasureSpec.makeMeasureSpec(
-                                fixedPanelHeightLimit, MeasureSpec.EXACTLY);
-                        child.measure(childWidthSpec, childHeightSpec);
-                    }
-                } else if (lp.weight > 0) {
-                    int childWidthSpec;
-                    if (lp.height == 0) {
-                        // This was skipped the first time; figure out a real width spec.
-                        if (lp.width == LayoutParams.WRAP_CONTENT) {
-                            childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth,
-                                    MeasureSpec.AT_MOST);
-                        } else if (lp.width == LayoutParams.MATCH_PARENT) {
-                            childWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth,
-                                    MeasureSpec.EXACTLY);
-                        } else {
-                            childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width,
-                                    MeasureSpec.EXACTLY);
-                        }
-                    } else {
-                        childWidthSpec = MeasureSpec.makeMeasureSpec(
-                                child.getMeasuredWidth(), MeasureSpec.EXACTLY);
-                    }
-
-                    if (canSlide) {
-                        // Consume available space
-                        final int verticalMargin = lp.topMargin + lp.bottomMargin;
-                        final int newHeight = heightAvailable - verticalMargin;
-                        final int childHeightSpec = MeasureSpec.makeMeasureSpec(
-                                newHeight, MeasureSpec.EXACTLY);
-                        if (measuredHeight != newHeight) {
-                            child.measure(childWidthSpec, childHeightSpec);
-                        }
-                    } else {
-                        // Distribute the extra width proportionally similar to LinearLayout
-                        final int heightToDistribute = Math.max(0, heightRemaining);
-                        final int addedHeight = (int) (lp.weight * heightToDistribute / weightSum);
-                        final int childHeightSpec = MeasureSpec.makeMeasureSpec(
-                                measuredHeight + addedHeight, MeasureSpec.EXACTLY);
-                        child.measure(childWidthSpec, childHeightSpec);
-                    }
-                }
-            }
-        }
-
-        final int measuredHeight = heightSize;
-        final int measuredWidth = layoutWidth + getPaddingLeft() + getPaddingRight();
-
-        setMeasuredDimension(measuredWidth, measuredHeight);
-        mCanSlide = canSlide;
-
-        if (mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE && !canSlide) {
-            // Cancel scrolling in progress, it's no longer relevant.
-            mDragHelper.abort();
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_TOP);
-
-        final int height = b - t;
-        final int paddingTop = getPaddingTop();
-        final int paddingBottom = getPaddingBottom();
-        final int paddingLeft = getPaddingLeft();
-
-        final int childCount = getChildCount();
-        int yStart = paddingTop;
-        int nextYStart = yStart;
-
-        if (mFirstLayout) {
-            mSlideOffset = mCanSlide && mPreservedOpenState ? 1.f : 0.f;
-        }
-
-        for (int i = 0; i < childCount; i++) {
-            final View child = getChildAt(i);
-
-            if (child.getVisibility() == GONE) {
-                continue;
-            }
-
-            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
-            final int childHeight = child.getMeasuredHeight();
-
-            if (lp.slideable) {
-                final int margin = lp.topMargin + lp.bottomMargin;
-                final int range = Math.min(nextYStart,
-                        height - paddingBottom - mOverhangSize) - yStart - margin;
-                mSlideRange = range;
-                final int lpMargin = lp.topMargin;
-                final int pos = (int) (range * mSlideOffset);
-                yStart += pos + lpMargin;
-                updateSlideOffset(pos);
-            } else {
-                yStart = nextYStart;
-            }
-
-            final int childTop = yStart;
-            final int childBottom = childTop + childHeight;
-            final int childLeft = paddingLeft;
-            final int childRight = childLeft + child.getMeasuredWidth();
-
-            child.layout(childLeft, childTop, childRight, childBottom);
-
-            nextYStart += child.getHeight();
-        }
-
-        if (mFirstLayout) {
-            updateObscuredViewsVisibility(mSlideableView);
-        }
-
-        mFirstLayout = false;
-    }
-
-    @Override
-    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-        // Recalculate sliding panes and their details
-        if (h != oldh) {
-            mFirstLayout = true;
-        }
-    }
-
-    @Override
-    public void requestChildFocus(View child, View focused) {
-        super.requestChildFocus(child, focused);
-        if (!isInTouchMode() && !mCanSlide) {
-            mPreservedOpenState = child == mSlideableView;
-        }
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        final int action = MotionEventCompat.getActionMasked(ev);
-
-        // Preserve the open state based on the last view that was touched.
-        if (!mCanSlide && action == MotionEvent.ACTION_DOWN && getChildCount() > 1) {
-            // After the first things will be slideable.
-            final View secondChild = getChildAt(1);
-            if (secondChild != null) {
-                mPreservedOpenState = !mDragHelper.isViewUnder(secondChild,
-                        (int) ev.getX(), (int) ev.getY());
-            }
-        }
-
-        if (!mCanSlide || (mIsUnableToDrag && action != MotionEvent.ACTION_DOWN)) {
-            if (!mIsInNestedScroll) {
-                mDragHelper.cancel();
-            }
-            return super.onInterceptTouchEvent(ev);
-        }
-
-        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
-            if (!mIsInNestedScroll) {
-                mDragHelper.cancel();
-            }
-            return false;
-        }
-
-        switch (action) {
-            case MotionEvent.ACTION_DOWN: {
-                mIsUnableToDrag = false;
-                final float x = ev.getX();
-                final float y = ev.getY();
-                mInitialMotionX = x;
-                mInitialMotionY = y;
-
-                break;
-            }
-
-            case MotionEvent.ACTION_MOVE: {
-                final float x = ev.getX();
-                final float y = ev.getY();
-                final float adx = Math.abs(x - mInitialMotionX);
-                final float ady = Math.abs(y - mInitialMotionY);
-                final int slop = mDragHelper.getTouchSlop();
-                if (ady > slop && adx > ady || !isCapturableViewUnder((int) x, (int) y)) {
-                    if (!mIsInNestedScroll) {
-                        mDragHelper.cancel();
-                    }
-                    mIsUnableToDrag = true;
-                    return false;
-                }
-            }
-        }
-
-        final boolean interceptForDrag = mDragHelper.shouldInterceptTouchEvent(ev);
-
-        return interceptForDrag;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (!mCanSlide) {
-            return super.onTouchEvent(ev);
-        }
-
-        mDragHelper.processTouchEvent(ev);
-
-        final int action = ev.getAction();
-        boolean wantTouchEvents = true;
-
-        switch (action & MotionEventCompat.ACTION_MASK) {
-            case MotionEvent.ACTION_DOWN: {
-                final float x = ev.getX();
-                final float y = ev.getY();
-                mInitialMotionX = x;
-                mInitialMotionY = y;
-                break;
-            }
-        }
-
-        return wantTouchEvents;
-    }
-
-    /**
-     * Refreshes the {@link OverlappingPaneLayout} be attempting to re-open or re-close the pane.
-     * This ensures that the overlapping pane is repositioned based on any changes to the view
-     * which is being overlapped.
-     * <p>
-     * The {@link #openPane()} and {@link #closePane()} methods do not perform any animation if the
-     * pane has already been positioned appropriately.
-     */
-    public void refresh() {
-        if (isOpen()) {
-            openPane();
-        } else {
-            closePane();
-        }
-    }
-
-    private boolean closePane(View pane, int initialVelocity) {
-        if (mFirstLayout || smoothSlideTo(0.f, initialVelocity)) {
-            mPreservedOpenState = false;
-            return true;
-        }
-        return false;
-    }
-
-    private boolean openPane(View pane, int initialVelocity) {
-        if (mFirstLayout || smoothSlideTo(1.f, initialVelocity)) {
-            mPreservedOpenState = true;
-            return true;
-        }
-        return false;
-    }
-
-    private void updateSlideOffset(int offsetPx) {
-        mSlideOffsetPx = offsetPx;
-        mSlideOffset = (float) mSlideOffsetPx / mSlideRange;
-    }
-
-    /**
-     * Open the sliding pane if it is currently slideable. If first layout
-     * has already completed this will animate.
-     *
-     * @return true if the pane was slideable and is now open/in the process of opening
-     */
-    public boolean openPane() {
-        return openPane(mSlideableView, 0);
-    }
-
-    /**
-     * Close the sliding pane if it is currently slideable. If first layout
-     * has already completed this will animate.
-     *
-     * @return true if the pane was slideable and is now closed/in the process of closing
-     */
-    public boolean closePane() {
-        return closePane(mSlideableView, 0);
-    }
-
-    /**
-     * Check if the layout is open. It can be open either because the slider
-     * itself is open revealing the left pane, or if all content fits without sliding.
-     *
-     * @return true if sliding panels are open
-     */
-    public boolean isOpen() {
-        return !mCanSlide || mSlideOffset > 0;
-    }
-
-    /**
-     * Check if the content in this layout cannot fully fit side by side and therefore
-     * the content pane can be slid back and forth.
-     *
-     * @return true if content in this layout can be slid open and closed
-     */
-    public boolean isSlideable() {
-        return mCanSlide;
-    }
-
-    private void onPanelDragged(int newTop) {
-        if (mSlideableView == null) {
-            // This can happen if we're aborting motion during layout because everything now fits.
-            mSlideOffset = 0;
-            return;
-        }
-        final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
-
-        final int lpMargin = lp.topMargin;
-        final int topBound = getPaddingTop() + lpMargin;
-
-        updateSlideOffset(newTop - topBound);
-
-        dispatchOnPanelSlide(mSlideableView);
-    }
-
-    @Override
-    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
-        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-        boolean result;
-        final int save = canvas.save(Canvas.CLIP_SAVE_FLAG);
-
-        if (mCanSlide && !lp.slideable && mSlideableView != null) {
-            // Clip against the slider; no sense drawing what will immediately be covered.
-            canvas.getClipBounds(mTmpRect);
-
-            mTmpRect.bottom = Math.min(mTmpRect.bottom, mSlideableView.getTop());
-            canvas.clipRect(mTmpRect);
-        }
-
-        if (Build.VERSION.SDK_INT >= 11) { // HC
-            result = super.drawChild(canvas, child, drawingTime);
-        } else {
-            if (child.isDrawingCacheEnabled()) {
-                child.setDrawingCacheEnabled(false);
-            }
-            result = super.drawChild(canvas, child, drawingTime);
-        }
-
-        canvas.restoreToCount(save);
-
-        return result;
-    }
-
-    /**
-     * Smoothly animate mDraggingPane to the target X position within its range.
-     *
-     * @param slideOffset position to animate to
-     * @param velocity initial velocity in case of fling, or 0.
-     */
-    boolean smoothSlideTo(float slideOffset, int velocity) {
-        if (!mCanSlide) {
-            // Nothing to do.
-            return false;
-        }
-
-        final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
-
-        int y;
-        int topBound = getPaddingTop() + lp.topMargin;
-        y = (int) (topBound + slideOffset * mSlideRange);
-
-        if (mDragHelper.smoothSlideViewTo(mSlideableView, mSlideableView.getLeft(), y)) {
-            setAllChildrenVisible();
-            ViewCompat.postInvalidateOnAnimation(this);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void computeScroll() {
-        if (mDragHelper.continueSettling(/* deferCallbacks = */ false)) {
-            if (!mCanSlide) {
-                mDragHelper.abort();
-                return;
-            }
-
-            ViewCompat.postInvalidateOnAnimation(this);
-        }
-    }
-
-    private boolean isCapturableViewUnder(int x, int y) {
-        View capturableView = mCapturableView != null ? mCapturableView : mSlideableView;
-        if (capturableView == null) {
-            return false;
-        }
-        int[] viewLocation = new int[2];
-        capturableView.getLocationOnScreen(viewLocation);
-        int[] parentLocation = new int[2];
-        this.getLocationOnScreen(parentLocation);
-        int screenX = parentLocation[0] + x;
-        int screenY = parentLocation[1] + y;
-        return screenX >= viewLocation[0]
-                && screenX < viewLocation[0] + capturableView.getWidth()
-                && screenY >= viewLocation[1]
-                && screenY < viewLocation[1] + capturableView.getHeight();
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
-        return new LayoutParams();
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof MarginLayoutParams
-                ? new LayoutParams((MarginLayoutParams) p)
-                : new LayoutParams(p);
-    }
-
-    @Override
-    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams && super.checkLayoutParams(p);
-    }
-
-    @Override
-    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
-        return new LayoutParams(getContext(), attrs);
-    }
-
-    @Override
-    protected Parcelable onSaveInstanceState() {
-        Parcelable superState = super.onSaveInstanceState();
-
-        SavedState ss = new SavedState(superState);
-        ss.isOpen = isSlideable() ? isOpen() : mPreservedOpenState;
-
-        return ss;
-    }
-
-    @Override
-    protected void onRestoreInstanceState(Parcelable state) {
-        SavedState ss = (SavedState) state;
-        super.onRestoreInstanceState(ss.getSuperState());
-
-        if (ss.isOpen) {
-            openPane();
-        } else {
-            closePane();
-        }
-        mPreservedOpenState = ss.isOpen;
-    }
-
-    @Override
-    public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
-        final boolean startNestedScroll = (nestedScrollAxes & SCROLL_AXIS_VERTICAL) != 0;
-        if (startNestedScroll) {
-            mIsInNestedScroll = true;
-            mDragHelper.startNestedScroll(mSlideableView);
-        }
-        if (DEBUG) {
-            Log.d(TAG, "onStartNestedScroll: " + startNestedScroll);
-        }
-        return startNestedScroll;
-    }
-
-    @Override
-    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
-        if (dy == 0) {
-            // Nothing to do
-            return;
-        }
-        if (DEBUG) {
-            Log.d(TAG, "onNestedPreScroll: " + dy);
-        }
-
-        mInNestedPreScrollDownwards = dy < 0;
-        mInNestedPreScrollUpwards = dy > 0;
-        mIsInNestedFling = false;
-        mDragHelper.processNestedScroll(mSlideableView, 0, -dy, consumed);
-    }
-
-    @Override
-    public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
-        if (!(velocityY > 0 && mSlideOffsetPx != 0
-                || velocityY < 0 && mSlideOffsetPx < mIntermediateOffset
-                || velocityY < 0 && mSlideOffsetPx < mSlideRange
-                && mPanelSlideCallbacks.isScrollableChildUnscrolled())) {
-            // No need to consume the fling if the fling won't collapse or expand the header.
-            // How far we are willing to expand the header depends on isScrollableChildUnscrolled().
-            return false;
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "onNestedPreFling: " + velocityY);
-        }
-        mInUpwardsPreFling = velocityY > 0;
-        mIsInNestedFling = true;
-        mIsInNestedScroll = false;
-        mDragHelper.processNestedFling(mSlideableView, (int) -velocityY);
-        return true;
-    }
-
-    @Override
-    public void onNestedScroll(View target, int dxConsumed, int dyConsumed, int dxUnconsumed,
-            int dyUnconsumed) {
-        if (DEBUG) {
-            Log.d(TAG, "onNestedScroll: " + dyUnconsumed);
-        }
-        mIsInNestedFling = false;
-        mDragHelper.processNestedScroll(mSlideableView, 0, -dyUnconsumed, null);
-    }
-
-    @Override
-    public void onStopNestedScroll(View child) {
-        if (DEBUG) {
-            Log.d(TAG, "onStopNestedScroll");
-        }
-        if (mIsInNestedScroll && !mIsInNestedFling) {
-            mDragHelper.stopNestedScroll(mSlideableView);
-            mInNestedPreScrollDownwards = false;
-            mInNestedPreScrollUpwards = false;
-            mIsInNestedScroll = false;
-        }
-    }
-
-    private class DragHelperCallback extends ViewDragHelper.Callback {
-
-        @Override
-        public boolean tryCaptureView(View child, int pointerId) {
-            if (mIsUnableToDrag) {
-                return false;
-            }
-
-            return ((LayoutParams) child.getLayoutParams()).slideable;
-        }
-
-        @Override
-        public void onViewDragStateChanged(int state) {
-            if (DEBUG) {
-                Log.d(TAG, "onViewDragStateChanged: " + state);
-            }
-
-            if (mDragHelper.getViewDragState() == ViewDragHelper.STATE_IDLE) {
-                if (mSlideOffset == 0) {
-                    updateObscuredViewsVisibility(mSlideableView);
-                    dispatchOnPanelClosed(mSlideableView);
-                    mPreservedOpenState = false;
-                } else {
-                    dispatchOnPanelOpened(mSlideableView);
-                    mPreservedOpenState = true;
-                }
-            }
-
-            if (state == ViewDragHelper.STATE_IDLE
-                    && mDragHelper.getVelocityMagnitude() > 0
-                    && mIsInNestedFling) {
-                mIsInNestedFling = false;
-                final int flingVelocity = !mInUpwardsPreFling ?
-                        -mDragHelper.getVelocityMagnitude() : mDragHelper.getVelocityMagnitude();
-                mPanelSlideCallbacks.onPanelFlingReachesEdge(flingVelocity);
-            }
-        }
-
-        @Override
-        public void onViewCaptured(View capturedChild, int activePointerId) {
-            // Make all child views visible in preparation for sliding things around
-            setAllChildrenVisible();
-        }
-
-        @Override
-        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
-            onPanelDragged(top);
-            invalidate();
-        }
-
-        @Override
-        public void onViewFling(View releasedChild, float xVelocity, float yVelocity) {
-            if (releasedChild == null) {
-                return;
-            }
-            if (DEBUG) {
-                Log.d(TAG, "onViewFling: " + yVelocity);
-            }
-
-            // Flings won't always fully expand or collapse the header. Instead of performing the
-            // fling and then waiting for the fling to end before snapping into place, we
-            // immediately snap into place if we predict the fling won't fully expand or collapse
-            // the header.
-            int yOffsetPx = mDragHelper.predictFlingYOffset((int) yVelocity);
-            if (yVelocity < 0) {
-                // Only perform a fling if we know the fling will fully compress the header.
-                if (-yOffsetPx > mSlideOffsetPx) {
-                    mDragHelper.flingCapturedView(releasedChild.getLeft(), /* minTop = */ 0,
-                            mSlideRange, Integer.MAX_VALUE, (int) yVelocity);
-                } else {
-                    mIsInNestedFling = false;
-                    onViewReleased(releasedChild, xVelocity, yVelocity);
-                }
-            } else {
-                // Only perform a fling if we know the fling will expand the header as far
-                // as it can possible be expanded, given the isScrollableChildUnscrolled() value.
-                if (yOffsetPx + mSlideOffsetPx >= mSlideRange
-                        && mPanelSlideCallbacks.isScrollableChildUnscrolled()) {
-                    mDragHelper.flingCapturedView(releasedChild.getLeft(), /* minTop = */ 0,
-                            Integer.MAX_VALUE, mSlideRange, (int) yVelocity);
-                } else if (yOffsetPx + mSlideOffsetPx >= mIntermediateOffset
-                        && mSlideOffsetPx <= mIntermediateOffset
-                        && !mPanelSlideCallbacks.isScrollableChildUnscrolled()) {
-                    mDragHelper.flingCapturedView(releasedChild.getLeft(), /* minTop = */ 0,
-                            Integer.MAX_VALUE, mIntermediateOffset, (int) yVelocity);
-                } else {
-                    mIsInNestedFling = false;
-                    onViewReleased(releasedChild, xVelocity, yVelocity);
-                }
-            }
-
-            mInNestedPreScrollDownwards = false;
-            mInNestedPreScrollUpwards = false;
-
-            // Without this invalidate, some calls to flingCapturedView can have no affect.
-            invalidate();
-        }
-
-        @Override
-        public void onViewReleased(View releasedChild, float xvel, float yvel) {
-            if (DEBUG) {
-                Log.d(TAG, "onViewReleased: "
-                        + " mIsInNestedFling=" + mIsInNestedFling
-                        + " unscrolled=" + mPanelSlideCallbacks.isScrollableChildUnscrolled()
-                        + ", mInNestedPreScrollDownwards = " + mInNestedPreScrollDownwards
-                        + ", mInNestedPreScrollUpwards = " + mInNestedPreScrollUpwards
-                        + ", yvel=" + yvel);
-            }
-            if (releasedChild == null) {
-                return;
-            }
-
-            final LayoutParams lp = (LayoutParams) releasedChild.getLayoutParams();
-            int top = getPaddingTop() + lp.topMargin;
-
-            // Decide where to snap to according to the current direction of motion and the current
-            // position. The velocity's magnitude has no bearing on this.
-            if (mInNestedPreScrollDownwards || yvel > 0) {
-                // Scrolling downwards
-                if (mSlideOffsetPx > mIntermediateOffset + mReleaseScrollSlop) {
-                    top += mSlideRange;
-                } else if (mSlideOffsetPx > mReleaseScrollSlop) {
-                    top += mIntermediateOffset;
-                } else {
-                    // Offset is very close to 0
-                }
-            } else if (mInNestedPreScrollUpwards || yvel < 0) {
-                // Scrolling upwards
-                if (mSlideOffsetPx > mSlideRange - mReleaseScrollSlop) {
-                    // Offset is very close to mSlideRange
-                    top += mSlideRange;
-                } else if (mSlideOffsetPx > mIntermediateOffset - mReleaseScrollSlop) {
-                    // Offset is between mIntermediateOffset and mSlideRange.
-                    top += mIntermediateOffset;
-                } else {
-                    // Offset is between 0 and mIntermediateOffset.
-                }
-            } else {
-                // Not moving upwards or downwards. This case can only be triggered when directly
-                // dragging the tabs. We don't bother to remember previous scroll direction
-                // when directly dragging the tabs.
-                if (0 <= mSlideOffsetPx && mSlideOffsetPx <= mIntermediateOffset / 2) {
-                    // Offset is between 0 and mIntermediateOffset, but closer to 0
-                    // Leave top unchanged
-                } else if (mIntermediateOffset / 2 <= mSlideOffsetPx
-                        && mSlideOffsetPx <= (mIntermediateOffset + mSlideRange) / 2) {
-                    // Offset is closest to mIntermediateOffset
-                    top += mIntermediateOffset;
-                } else {
-                    // Offset is between mIntermediateOffset and mSlideRange, but closer to
-                    // mSlideRange
-                    top += mSlideRange;
-                }
-            }
-
-            mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top);
-            invalidate();
-        }
-
-        @Override
-        public int getViewVerticalDragRange(View child) {
-            return mSlideRange;
-        }
-
-        @Override
-        public int clampViewPositionHorizontal(View child, int left, int dx) {
-            // Make sure we never move views horizontally.
-            return child.getLeft();
-        }
-
-        @Override
-        public int clampViewPositionVertical(View child, int top, int dy) {
-            final LayoutParams lp = (LayoutParams) mSlideableView.getLayoutParams();
-
-            final int newTop;
-            int previousTop = top - dy;
-            int topBound = getPaddingTop() + lp.topMargin;
-            int bottomBound = topBound + (mPanelSlideCallbacks.isScrollableChildUnscrolled()
-                    || !mIsInNestedScroll ? mSlideRange : mIntermediateOffset);
-            if (previousTop > bottomBound) {
-                // We were previously below the bottomBound, so loosen the bottomBound so that this
-                // makes sense. This can occur after the view was directly dragged by the tabs.
-                bottomBound = Math.max(bottomBound, mSlideRange);
-            }
-            newTop = Math.min(Math.max(top, topBound), bottomBound);
-
-            return newTop;
-        }
-
-        @Override
-        public void onEdgeDragStarted(int edgeFlags, int pointerId) {
-            mDragHelper.captureChildView(mSlideableView, pointerId);
-        }
-    }
-
-    public static class LayoutParams extends ViewGroup.MarginLayoutParams {
-        private static final int[] ATTRS = new int[] {
-            android.R.attr.layout_weight
-        };
-
-        /**
-         * The weighted proportion of how much of the leftover space
-         * this child should consume after measurement.
-         */
-        public float weight = 0;
-
-        /**
-         * True if this pane is the slideable pane in the layout.
-         */
-        boolean slideable;
-
-        public LayoutParams() {
-            super(FILL_PARENT, FILL_PARENT);
-        }
-
-        public LayoutParams(int width, int height) {
-            super(width, height);
-        }
-
-        public LayoutParams(android.view.ViewGroup.LayoutParams source) {
-            super(source);
-        }
-
-        public LayoutParams(MarginLayoutParams source) {
-            super(source);
-        }
-
-        public LayoutParams(LayoutParams source) {
-            super(source);
-            this.weight = source.weight;
-        }
-
-        public LayoutParams(Context c, AttributeSet attrs) {
-            super(c, attrs);
-
-            final TypedArray a = c.obtainStyledAttributes(attrs, ATTRS);
-            this.weight = a.getFloat(0, 0);
-            a.recycle();
-        }
-
-    }
-
-    static class SavedState extends BaseSavedState {
-        boolean isOpen;
-
-        SavedState(Parcelable superState) {
-            super(superState);
-        }
-
-        private SavedState(Parcel in) {
-            super(in);
-            isOpen = in.readInt() != 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel out, int flags) {
-            super.writeToParcel(out, flags);
-            out.writeInt(isOpen ? 1 : 0);
-        }
-
-        public static final Parcelable.Creator<SavedState> CREATOR =
-                new Parcelable.Creator<SavedState>() {
-            public SavedState createFromParcel(Parcel in) {
-                return new SavedState(in);
-            }
-
-            public SavedState[] newArray(int size) {
-                return new SavedState[size];
-            }
-        };
-    }
-
-    class AccessibilityDelegate extends AccessibilityDelegateCompat {
-        private final Rect mTmpRect = new Rect();
-
-        @Override
-        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
-            final AccessibilityNodeInfoCompat superNode = AccessibilityNodeInfoCompat.obtain(info);
-            super.onInitializeAccessibilityNodeInfo(host, superNode);
-            copyNodeInfoNoChildren(info, superNode);
-            superNode.recycle();
-
-            info.setClassName(OverlappingPaneLayout.class.getName());
-            info.setSource(host);
-
-            final ViewParent parent = ViewCompat.getParentForAccessibility(host);
-            if (parent instanceof View) {
-                info.setParent((View) parent);
-            }
-
-            // This is a best-approximation of addChildrenForAccessibility()
-            // that accounts for filtering.
-            final int childCount = getChildCount();
-            for (int i = 0; i < childCount; i++) {
-                final View child = getChildAt(i);
-                if (child.getVisibility() == View.VISIBLE) {
-                    // Force importance to "yes" since we can't read the value.
-                    ViewCompat.setImportantForAccessibility(
-                            child, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_YES);
-                    info.addChild(child);
-                }
-            }
-        }
-
-        @Override
-        public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
-            super.onInitializeAccessibilityEvent(host, event);
-
-            event.setClassName(OverlappingPaneLayout.class.getName());
-        }
-
-        /**
-         * This should really be in AccessibilityNodeInfoCompat, but there unfortunately
-         * seem to be a few elements that are not easily cloneable using the underlying API.
-         * Leave it private here as it's not general-purpose useful.
-         */
-        private void copyNodeInfoNoChildren(AccessibilityNodeInfoCompat dest,
-                AccessibilityNodeInfoCompat src) {
-            final Rect rect = mTmpRect;
-
-            src.getBoundsInParent(rect);
-            dest.setBoundsInParent(rect);
-
-            src.getBoundsInScreen(rect);
-            dest.setBoundsInScreen(rect);
-
-            dest.setVisibleToUser(src.isVisibleToUser());
-            dest.setPackageName(src.getPackageName());
-            dest.setClassName(src.getClassName());
-            dest.setContentDescription(src.getContentDescription());
-
-            dest.setEnabled(src.isEnabled());
-            dest.setClickable(src.isClickable());
-            dest.setFocusable(src.isFocusable());
-            dest.setFocused(src.isFocused());
-            dest.setAccessibilityFocused(src.isAccessibilityFocused());
-            dest.setSelected(src.isSelected());
-            dest.setLongClickable(src.isLongClickable());
-
-            dest.addAction(src.getActions());
-
-            dest.setMovementGranularities(src.getMovementGranularities());
-        }
-    }
-}
