/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package android.support.v7.widget;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import android.support.test.InstrumentationRegistry;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.SystemClock;
import android.support.v4.view.ViewCompat;
import android.test.TouchUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import static android.support.v7.widget.RecyclerView.NO_POSITION;
import static android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE;
import static android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING;
import static android.support.v7.widget.RecyclerView.SCROLL_STATE_SETTLING;
import static android.support.v7.widget.RecyclerView.getChildViewHolderInt;
import android.support.test.runner.AndroidJUnit4;

@RunWith(AndroidJUnit4.class)
public class RecyclerViewLayoutTest extends BaseRecyclerViewInstrumentationTest {
    private static final int FLAG_HORIZONTAL = 1;
    private static final int FLAG_VERTICAL = 1 << 1;
    private static final int FLAG_FLING = 1 << 2;

    private static final boolean DEBUG = false;

    private static final String TAG = "RecyclerViewLayoutTest";

    public RecyclerViewLayoutTest() {
        super(DEBUG);
    }

    @Before
    @Override
    public void setUp() throws Exception {
        super.setUp();
        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
    }

    @After
    @Override
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    public void testFlingFrozen() throws Throwable {
        testScrollFrozen(true);
    }

    @Test
    public void testDragFrozen() throws Throwable {
        testScrollFrozen(false);
    }

    private void testScrollFrozen(boolean fling) throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());

        final int horizontalScrollCount = 3;
        final int verticalScrollCount = 3;
        final int horizontalVelocity = 1000;
        final int verticalVelocity = 1000;
        final AtomicInteger horizontalCounter = new AtomicInteger(horizontalScrollCount);
        final AtomicInteger verticalCounter = new AtomicInteger(verticalScrollCount);
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public boolean canScrollHorizontally() {
                return true;
            }

            @Override
            public boolean canScrollVertically() {
                return true;
            }

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                layoutRange(recycler, 0, 10);
                layoutLatch.countDown();
            }

            @Override
            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                if (verticalCounter.get() > 0) {
                    verticalCounter.decrementAndGet();
                    return dy;
                }
                return 0;
            }

            @Override
            public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                if (horizontalCounter.get() > 0) {
                    horizontalCounter.decrementAndGet();
                    return dx;
                }
                return 0;
            }
        };
        TestAdapter adapter = new TestAdapter(100);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(recyclerView);
        tlm.waitForLayout(2);

        freezeLayout(true);

        if (fling) {
            assertFalse("fling should be blocked", fling(horizontalVelocity, verticalVelocity));
        } else { // drag
            TouchUtils.dragViewTo(this, recyclerView,
                    Gravity.LEFT | Gravity.TOP,
                    mRecyclerView.getWidth() / 2, mRecyclerView.getHeight() / 2);
        }
        assertEquals("rv's horizontal scroll cb must not run", horizontalScrollCount,
                horizontalCounter.get());
        assertEquals("rv's vertical scroll cb must not run", verticalScrollCount,
                verticalCounter.get());

        freezeLayout(false);

        if (fling) {
            assertTrue("fling should be started", fling(horizontalVelocity, verticalVelocity));
        } else { // drag
            TouchUtils.dragViewTo(this, recyclerView,
                    Gravity.LEFT | Gravity.TOP,
                    mRecyclerView.getWidth() / 2, mRecyclerView.getHeight() / 2);
        }
        assertEquals("rv's horizontal scroll cb must finishes", 0, horizontalCounter.get());
        assertEquals("rv's vertical scroll cb must finishes", 0, verticalCounter.get());
    }

    @Test
    public void  testFocusSearchFailFrozen() throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());
        final CountDownLatch focusLatch = new CountDownLatch(1);
        final AtomicInteger focusSearchCalled = new AtomicInteger(0);
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public boolean canScrollHorizontally() {
                return true;
            }

            @Override
            public boolean canScrollVertically() {
                return true;
            }

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                layoutRange(recycler, 0, 10);
                layoutLatch.countDown();
            }

            @Override
            public View onFocusSearchFailed(View focused, int direction,
                    RecyclerView.Recycler recycler, RecyclerView.State state) {
                focusSearchCalled.addAndGet(1);
                focusLatch.countDown();
                return null;
            }
        };
        TestAdapter adapter = new TestAdapter(100);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(recyclerView);
        tlm.waitForLayout(2);

        final View c = recyclerView.getChildAt(recyclerView.getChildCount() - 1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                c.requestFocus();
            }
        });
        assertTrue(c.hasFocus());
        freezeLayout(true);
        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
        assertEquals("onFocusSearchFailed should not be called when layout is frozen",
                0, focusSearchCalled.get());
        freezeLayout(false);
        sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
        assertTrue(focusLatch.await(2, TimeUnit.SECONDS));
        assertEquals(1, focusSearchCalled.get());
    }

    @Test
    public void testFrozenAndChangeAdapter() throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());

        final AtomicInteger focusSearchCalled = new AtomicInteger(0);
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public boolean canScrollHorizontally() {
                return true;
            }

            @Override
            public boolean canScrollVertically() {
                return true;
            }

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                layoutRange(recycler, 0, 10);
                layoutLatch.countDown();
            }

            @Override
            public View onFocusSearchFailed(View focused, int direction, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                focusSearchCalled.addAndGet(1);
                return null;
            }
        };
        TestAdapter adapter = new TestAdapter(100);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(recyclerView);
        tlm.waitForLayout(2);

        freezeLayout(true);
        TestAdapter adapter2 = new TestAdapter(1000);
        setAdapter(adapter2);
        assertFalse(recyclerView.isLayoutFrozen());
        assertSame(adapter2, recyclerView.getAdapter());

        freezeLayout(true);
        TestAdapter adapter3 = new TestAdapter(1000);
        swapAdapter(adapter3, true);
        assertFalse(recyclerView.isLayoutFrozen());
        assertSame(adapter3, recyclerView.getAdapter());
    }

    @Test
    public void testScrollToPositionCallback() throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());
        TestLayoutManager tlm = new TestLayoutManager() {
            int scrollPos = RecyclerView.NO_POSITION;

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                layoutLatch.countDown();
                if (scrollPos == RecyclerView.NO_POSITION) {
                    layoutRange(recycler, 0, 10);
                } else {
                    layoutRange(recycler, scrollPos, scrollPos + 10);
                }
            }

            @Override
            public void scrollToPosition(int position) {
                scrollPos = position;
                requestLayout();
            }
        };
        recyclerView.setLayoutManager(tlm);
        TestAdapter adapter = new TestAdapter(100);
        recyclerView.setAdapter(adapter);
        final AtomicInteger rvCounter = new AtomicInteger(0);
        final AtomicInteger viewGroupCounter = new AtomicInteger(0);
        recyclerView.getViewTreeObserver().addOnScrollChangedListener(
                new ViewTreeObserver.OnScrollChangedListener() {
                    @Override
                    public void onScrollChanged() {
                        viewGroupCounter.incrementAndGet();
                    }
                });
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                rvCounter.incrementAndGet();
                super.onScrolled(recyclerView, dx, dy);
            }
        });
        tlm.expectLayouts(1);

        setRecyclerView(recyclerView);
        tlm.waitForLayout(2);
        // wait for draw :/
        Thread.sleep(1000);

        assertEquals("RV on scroll should be called for initialization", 1, rvCounter.get());
        assertEquals("VTO on scroll should be called for initialization", 1,
                viewGroupCounter.get());
        tlm.expectLayouts(1);
        freezeLayout(true);
        scrollToPosition(3);
        tlm.assertNoLayout("scrollToPosition should be ignored", 2);
        freezeLayout(false);
        scrollToPosition(3);
        tlm.waitForLayout(2);
        assertEquals("RV on scroll should be called", 2, rvCounter.get());
        assertEquals("VTO on scroll should be called", 2, viewGroupCounter.get());
        tlm.expectLayouts(1);
        requestLayoutOnUIThread(recyclerView);
        tlm.waitForLayout(2);
        // wait for draw :/
        Thread.sleep(1000);
        assertEquals("on scroll should NOT be called", 2, rvCounter.get());
        assertEquals("on scroll should NOT be called", 2, viewGroupCounter.get());

    }

    @Test
    public void testScrollInBothDirectionEqual() throws Throwable {
        scrollInBothDirection(3, 3, 1000, 1000);
    }

    @Test
    public void testScrollInBothDirectionMoreVertical() throws Throwable {
        scrollInBothDirection(2, 3, 1000, 1000);
    }

    @Test
    public void testScrollInBothDirectionMoreHorizontal() throws Throwable {
        scrollInBothDirection(3, 2, 1000, 1000);
    }

    @Test
    public void testScrollHorizontalOnly() throws Throwable {
        scrollInBothDirection(3, 0, 1000, 0);
    }

    @Test
    public void testScrollVerticalOnly() throws Throwable {
        scrollInBothDirection(0, 3, 0, 1000);
    }

    @Test
    public void testScrollInBothDirectionEqualReverse() throws Throwable {
        scrollInBothDirection(3, 3, -1000, -1000);
    }

    @Test
    public void testScrollInBothDirectionMoreVerticalReverse() throws Throwable {
        scrollInBothDirection(2, 3, -1000, -1000);
    }

    @Test
    public void testScrollInBothDirectionMoreHorizontalReverse() throws Throwable {
        scrollInBothDirection(3, 2, -1000, -1000);
    }

    @Test
    public void testScrollHorizontalOnlyReverse() throws Throwable {
        scrollInBothDirection(3, 0, -1000, 0);
    }

    @Test
    public void testScrollVerticalOnlyReverse() throws Throwable {
        scrollInBothDirection(0, 3, 0, -1000);
    }

    public void scrollInBothDirection(int horizontalScrollCount, int verticalScrollCount,
            int horizontalVelocity, int verticalVelocity)
            throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());
        final AtomicInteger horizontalCounter = new AtomicInteger(horizontalScrollCount);
        final AtomicInteger verticalCounter = new AtomicInteger(verticalScrollCount);
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public boolean canScrollHorizontally() {
                return true;
            }

            @Override
            public boolean canScrollVertically() {
                return true;
            }

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                layoutRange(recycler, 0, 10);
                layoutLatch.countDown();
            }

            @Override
            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                if (verticalCounter.get() > 0) {
                    verticalCounter.decrementAndGet();
                    return dy;
                }
                return 0;
            }

            @Override
            public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                if (horizontalCounter.get() > 0) {
                    horizontalCounter.decrementAndGet();
                    return dx;
                }
                return 0;
            }
        };
        TestAdapter adapter = new TestAdapter(100);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(recyclerView);
        tlm.waitForLayout(2);
        assertTrue("test sanity, fling must run", fling(horizontalVelocity, verticalVelocity));
        assertEquals("rv's horizontal scroll cb must run " + horizontalScrollCount + " times'", 0,
                horizontalCounter.get());
        assertEquals("rv's vertical scroll cb must run " + verticalScrollCount + " times'", 0,
                verticalCounter.get());
    }

    @Test
    public void testDragHorizontal() throws Throwable {
        scrollInOtherOrientationTest(FLAG_HORIZONTAL);
    }

    @Test
    public void testDragVertical() throws Throwable {
        scrollInOtherOrientationTest(FLAG_VERTICAL);
    }

    @Test
    public void testFlingHorizontal() throws Throwable {
        scrollInOtherOrientationTest(FLAG_HORIZONTAL | FLAG_FLING);
    }

    @Test
    public void testFlingVertical() throws Throwable {
        scrollInOtherOrientationTest(FLAG_VERTICAL | FLAG_FLING);
    }

    @Test
    public void testNestedDragVertical() throws Throwable {
        TestedFrameLayout tfl = getActivity().mContainer;
        tfl.setNestedScrollMode(TestedFrameLayout.TEST_NESTED_SCROLL_MODE_CONSUME);
        tfl.setNestedFlingMode(TestedFrameLayout.TEST_NESTED_SCROLL_MODE_CONSUME);
        scrollInOtherOrientationTest(FLAG_VERTICAL, 0);
    }

    @Test
    public void testNestedDragHorizontal() throws Throwable {
        TestedFrameLayout tfl = getActivity().mContainer;
        tfl.setNestedScrollMode(TestedFrameLayout.TEST_NESTED_SCROLL_MODE_CONSUME);
        tfl.setNestedFlingMode(TestedFrameLayout.TEST_NESTED_SCROLL_MODE_CONSUME);
        scrollInOtherOrientationTest(FLAG_HORIZONTAL, 0);
    }

    @Test
    public void testNestedDragHorizontalCallsStopNestedScroll() throws Throwable {
        TestedFrameLayout tfl = getActivity().mContainer;
        tfl.setNestedScrollMode(TestedFrameLayout.TEST_NESTED_SCROLL_MODE_CONSUME);
        tfl.setNestedFlingMode(TestedFrameLayout.TEST_NESTED_SCROLL_MODE_CONSUME);
        scrollInOtherOrientationTest(FLAG_HORIZONTAL, 0);
        assertTrue("onStopNestedScroll called", tfl.stopNestedScrollCalled());
    }

    @Test
    public void testNestedDragVerticalCallsStopNestedScroll() throws Throwable {
        TestedFrameLayout tfl = getActivity().mContainer;
        tfl.setNestedScrollMode(TestedFrameLayout.TEST_NESTED_SCROLL_MODE_CONSUME);
        tfl.setNestedFlingMode(TestedFrameLayout.TEST_NESTED_SCROLL_MODE_CONSUME);
        scrollInOtherOrientationTest(FLAG_VERTICAL, 0);
        assertTrue("onStopNestedScroll called", tfl.stopNestedScrollCalled());
    }

    private void scrollInOtherOrientationTest(int flags)
            throws Throwable {
        scrollInOtherOrientationTest(flags, flags);
    }

    private void scrollInOtherOrientationTest(final int flags, int expectedFlags) throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());
        final AtomicBoolean scrolledHorizontal = new AtomicBoolean(false);
        final AtomicBoolean scrolledVertical = new AtomicBoolean(false);

        final TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public boolean canScrollHorizontally() {
                return (flags & FLAG_HORIZONTAL) != 0;
            }

            @Override
            public boolean canScrollVertically() {
                return (flags & FLAG_VERTICAL) != 0;
            }

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                layoutRange(recycler, 0, 10);
                layoutLatch.countDown();
            }

            @Override
            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                scrolledVertical.set(true);
                return super.scrollVerticallyBy(dy, recycler, state);
            }

            @Override
            public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                scrolledHorizontal.set(true);
                return super.scrollHorizontallyBy(dx, recycler, state);
            }
        };
        TestAdapter adapter = new TestAdapter(100);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(recyclerView);
        tlm.waitForLayout(2);
        if ( (flags & FLAG_FLING) != 0 ) {
            int flingVelocity = (mRecyclerView.getMaxFlingVelocity() +
                    mRecyclerView.getMinFlingVelocity()) / 2;
            assertEquals("fling started", (expectedFlags & FLAG_FLING) != 0,
                    fling(flingVelocity, flingVelocity));
        } else { // drag
            TouchUtils.dragViewTo(this, recyclerView, Gravity.LEFT | Gravity.TOP,
                    mRecyclerView.getWidth() / 2, mRecyclerView.getHeight() / 2);
        }
        assertEquals("horizontally scrolled: " + tlm.mScrollHorizontallyAmount,
                (expectedFlags & FLAG_HORIZONTAL) != 0, scrolledHorizontal.get());
        assertEquals("vertically scrolled: " + tlm.mScrollVerticallyAmount,
                (expectedFlags & FLAG_VERTICAL) != 0, scrolledVertical.get());
    }

    private boolean fling(final int velocityX, final int velocityY) throws Throwable {
        final AtomicBoolean didStart = new AtomicBoolean(false);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                boolean result = mRecyclerView.fling(velocityX, velocityY);
                didStart.set(result);
            }
        });
        if (!didStart.get()) {
            return false;
        }
        // cannot set scroll listener in case it is subject to some test so instead doing a busy
        // loop until state goes idle
        while (mRecyclerView.getScrollState() != SCROLL_STATE_IDLE) {
            getInstrumentation().waitForIdleSync();
        }
        return true;
    }

    private void assertPendingUpdatesAndLayout(TestLayoutManager testLayoutManager,
            final Runnable runnable) throws Throwable {
        testLayoutManager.expectLayouts(1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                runnable.run();
                assertTrue(mRecyclerView.hasPendingAdapterUpdates());
            }
        });
        testLayoutManager.waitForLayout(1);
        assertFalse(mRecyclerView.hasPendingAdapterUpdates());
    }

    private void setupBasic(RecyclerView recyclerView, TestLayoutManager tlm,
            TestAdapter adapter, boolean waitForFirstLayout) throws Throwable {
        recyclerView.setLayoutManager(tlm);
        recyclerView.setAdapter(adapter);
        if (waitForFirstLayout) {
            tlm.expectLayouts(1);
            setRecyclerView(recyclerView);
            tlm.waitForLayout(1);
        } else {
            setRecyclerView(recyclerView);
        }
    }

    @Test
    public void testHasPendingUpdatesBeforeFirstLayout() throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());
        TestLayoutManager layoutManager = new DumbLayoutManager();
        TestAdapter testAdapter = new TestAdapter(10);
        setupBasic(recyclerView, layoutManager, testAdapter, false);
        assertTrue(mRecyclerView.hasPendingAdapterUpdates());
    }

    @Test
    public void testNoPendingUpdatesAfterLayout() throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());
        TestLayoutManager layoutManager = new DumbLayoutManager();
        TestAdapter testAdapter = new TestAdapter(10);
        setupBasic(recyclerView, layoutManager, testAdapter, true);
        assertFalse(mRecyclerView.hasPendingAdapterUpdates());
    }

    @Test
    public void testHasPendingUpdatesWhenAdapterIsChanged() throws Throwable {
        RecyclerView recyclerView = new RecyclerView(getActivity());
        TestLayoutManager layoutManager = new DumbLayoutManager();
        final TestAdapter testAdapter = new TestAdapter(10);
        setupBasic(recyclerView, layoutManager, testAdapter, false);
        assertPendingUpdatesAndLayout(layoutManager, new Runnable() {
            @Override
            public void run() {
                testAdapter.notifyItemRemoved(1);
            }
        });
        assertPendingUpdatesAndLayout(layoutManager, new Runnable() {
            @Override
            public void run() {
                testAdapter.notifyItemInserted(2);
            }
        });

        assertPendingUpdatesAndLayout(layoutManager, new Runnable() {
            @Override
            public void run() {
                testAdapter.notifyItemMoved(2, 3);
            }
        });

        assertPendingUpdatesAndLayout(layoutManager, new Runnable() {
            @Override
            public void run() {
                testAdapter.notifyItemChanged(2);
            }
        });

        assertPendingUpdatesAndLayout(layoutManager, new Runnable() {
            @Override
            public void run() {
                testAdapter.notifyDataSetChanged();
            }
        });
    }

    @Test
    public void testTransientStateRecycleViaAdapter() throws Throwable {
        transientStateRecycleTest(true, false);
    }

    @Test
    public void testTransientStateRecycleViaTransientStateCleanup() throws Throwable {
        transientStateRecycleTest(false, true);
    }

    @Test
    public void testTransientStateDontRecycle() throws Throwable {
        transientStateRecycleTest(false, false);
    }

    public void transientStateRecycleTest(final boolean succeed, final boolean unsetTransientState)
            throws Throwable {
        final List<View> failedToRecycle = new ArrayList<View>();
        final List<View> recycled = new ArrayList<View>();
        TestAdapter testAdapter = new TestAdapter(10) {
            @Override
            public boolean onFailedToRecycleView(
                    TestViewHolder holder) {
                failedToRecycle.add(holder.itemView);
                if (unsetTransientState) {
                    setHasTransientState(holder.itemView, false);
                }
                return succeed;
            }

            @Override
            public void onViewRecycled(TestViewHolder holder) {
                recycled.add(holder.itemView);
                super.onViewRecycled(holder);
            }
        };
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                if (getChildCount() == 0) {
                    detachAndScrapAttachedViews(recycler);
                    layoutRange(recycler, 0, 5);
                } else {
                    removeAndRecycleAllViews(recycler);
                }
                if (layoutLatch != null) {
                    layoutLatch.countDown();
                }
            }
        };
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(tlm);
        recyclerView.setItemAnimator(null);
        setRecyclerView(recyclerView);
        getInstrumentation().waitForIdleSync();
        // make sure we have enough views after this position so that we'll receive the on recycled
        // callback
        View view = recyclerView.getChildAt(3);//this has to be greater than def cache size.
        setHasTransientState(view, true);
        tlm.expectLayouts(1);
        requestLayoutOnUIThread(recyclerView);
        tlm.waitForLayout(2);

        assertTrue(failedToRecycle.contains(view));
        assertEquals(succeed || unsetTransientState, recycled.contains(view));
    }

    @Test
    public void testAdapterPositionInvalidation() throws Throwable {
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        final TestAdapter adapter = new TestAdapter(10);
        final TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                layoutRange(recycler, 0, state.getItemCount());
                layoutLatch.countDown();
            }
        };
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(recyclerView);
        tlm.waitForLayout(1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < tlm.getChildCount(); i++) {
                    assertNotSame("adapter positions should not be undefined",
                            recyclerView.getChildAdapterPosition(tlm.getChildAt(i)),
                            RecyclerView.NO_POSITION);
                }
                adapter.notifyDataSetChanged();
                for (int i = 0; i < tlm.getChildCount(); i++) {
                    assertSame("adapter positions should be undefined",
                            recyclerView.getChildAdapterPosition(tlm.getChildAt(i)),
                            RecyclerView.NO_POSITION);
                }
            }
        });
    }

    @Test
    public void testAdapterPositionsBasic() throws Throwable {
        adapterPositionsTest(null);
    }

    @Test
    public void testAdapterPositionsRemoveItems() throws Throwable {
        adapterPositionsTest(new AdapterRunnable() {
            @Override
            public void run(TestAdapter adapter) throws Throwable {
                adapter.deleteAndNotify(3, 4);
            }
        });
    }

    @Test
    public void testAdapterPositionsRemoveItemsBefore() throws Throwable {
        adapterPositionsTest(new AdapterRunnable() {
            @Override
            public void run(TestAdapter adapter) throws Throwable {
                adapter.deleteAndNotify(0, 1);
            }
        });
    }

    @Test
    public void testAdapterPositionsAddItemsBefore() throws Throwable {
        adapterPositionsTest(new AdapterRunnable() {
            @Override
            public void run(TestAdapter adapter) throws Throwable {
                adapter.addAndNotify(0, 5);
            }
        });
    }

    @Test
    public void testAdapterPositionsAddItemsInside() throws Throwable {
        adapterPositionsTest(new AdapterRunnable() {
            @Override
            public void run(TestAdapter adapter) throws Throwable {
                adapter.addAndNotify(3, 2);
            }
        });
    }

    @Test
    public void testAdapterPositionsMoveItems() throws Throwable {
        adapterPositionsTest(new AdapterRunnable() {
            @Override
            public void run(TestAdapter adapter) throws Throwable {
                adapter.moveAndNotify(3, 5);
            }
        });
    }

    @Test
    public void testAdapterPositionsNotifyDataSetChanged() throws Throwable {
        adapterPositionsTest(new AdapterRunnable() {
            @Override
            public void run(TestAdapter adapter) throws Throwable {
                adapter.mItems.clear();
                for (int i = 0; i < 20; i++) {
                    adapter.mItems.add(new Item(i, "added item"));
                }
                adapter.notifyDataSetChanged();
            }
        });
    }

    @Test
    public void testAvoidLeakingRecyclerViewIfViewIsNotRecycled() throws Throwable {
        final AtomicBoolean failedToRecycle = new AtomicBoolean(false);
        RecyclerView rv = new RecyclerView(getActivity());
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                layoutRange(recycler, 0, state.getItemCount());
                layoutLatch.countDown();
            }
        };
        TestAdapter adapter = new TestAdapter(10) {
            @Override
            public boolean onFailedToRecycleView(
                    TestViewHolder holder) {
                failedToRecycle.set(true);
                return false;
            }
        };
        rv.setAdapter(adapter);
        rv.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(rv);
        tlm.waitForLayout(1);
        final RecyclerView.ViewHolder vh = rv.getChildViewHolder(rv.getChildAt(0));
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                ViewCompat.setHasTransientState(vh.itemView, true);
            }
        });
        tlm.expectLayouts(1);
        adapter.deleteAndNotify(0, 10);
        tlm.waitForLayout(2);
        final CountDownLatch animationsLatch = new CountDownLatch(1);
        rv.getItemAnimator().isRunning(
                new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() {
                    @Override
                    public void onAnimationsFinished() {
                        animationsLatch.countDown();
                    }
                });
        assertTrue(animationsLatch.await(2, TimeUnit.SECONDS));
        assertTrue(failedToRecycle.get());
        assertNull(vh.mOwnerRecyclerView);
        checkForMainThreadException();
    }

    @Test
    public void testAvoidLeakingRecyclerViewViaViewHolder() throws Throwable {
        RecyclerView rv = new RecyclerView(getActivity());
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                layoutRange(recycler, 0, state.getItemCount());
                layoutLatch.countDown();
            }
        };
        TestAdapter adapter = new TestAdapter(10);
        rv.setAdapter(adapter);
        rv.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(rv);
        tlm.waitForLayout(1);
        final RecyclerView.ViewHolder vh = rv.getChildViewHolder(rv.getChildAt(0));
        tlm.expectLayouts(1);
        adapter.deleteAndNotify(0, 10);
        tlm.waitForLayout(2);
        final CountDownLatch animationsLatch = new CountDownLatch(1);
        rv.getItemAnimator().isRunning(
                new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() {
                    @Override
                    public void onAnimationsFinished() {
                        animationsLatch.countDown();
                    }
                });
        assertTrue(animationsLatch.await(2, TimeUnit.SECONDS));
        assertNull(vh.mOwnerRecyclerView);
        checkForMainThreadException();
    }

    public void adapterPositionsTest(final AdapterRunnable adapterChanges) throws Throwable {
        final TestAdapter testAdapter = new TestAdapter(10);
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                try {
                    layoutRange(recycler, Math.min(state.getItemCount(), 2)
                            , Math.min(state.getItemCount(), 7));
                    layoutLatch.countDown();
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                }
            }
        };
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setLayoutManager(tlm);
        recyclerView.setAdapter(testAdapter);
        tlm.expectLayouts(1);
        setRecyclerView(recyclerView);
        tlm.waitForLayout(1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    final int count = recyclerView.getChildCount();
                    Map<View, Integer> layoutPositions = new HashMap<View, Integer>();
                    assertTrue("test sanity", count > 0);
                    for (int i = 0; i < count; i++) {
                        View view = recyclerView.getChildAt(i);
                        TestViewHolder vh = (TestViewHolder) recyclerView.getChildViewHolder(view);
                        int index = testAdapter.mItems.indexOf(vh.mBoundItem);
                        assertEquals("should be able to find VH with adapter position " + index, vh,
                                recyclerView.findViewHolderForAdapterPosition(index));
                        assertEquals("get adapter position should return correct index", index,
                                vh.getAdapterPosition());
                        layoutPositions.put(view, vh.mPosition);
                    }
                    if (adapterChanges != null) {
                        adapterChanges.run(testAdapter);
                        for (int i = 0; i < count; i++) {
                            View view = recyclerView.getChildAt(i);
                            TestViewHolder vh = (TestViewHolder) recyclerView
                                    .getChildViewHolder(view);
                            int index = testAdapter.mItems.indexOf(vh.mBoundItem);
                            if (index >= 0) {
                                assertEquals("should be able to find VH with adapter position "
                                                + index, vh,
                                        recyclerView.findViewHolderForAdapterPosition(index));
                            }
                            assertSame("get adapter position should return correct index", index,
                                    vh.getAdapterPosition());
                            assertSame("should be able to find view with layout position",
                                    vh, mRecyclerView.findViewHolderForLayoutPosition(
                                            layoutPositions.get(view)));
                        }

                    }

                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                }
            }
        });
        checkForMainThreadException();
    }

    @Test
    public void testScrollStateForSmoothScroll() throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        TestLayoutManager tlm = new TestLayoutManager();
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(tlm);
        setRecyclerView(recyclerView);
        getInstrumentation().waitForIdleSync();
        assertEquals(SCROLL_STATE_IDLE, recyclerView.getScrollState());
        final int[] stateCnts = new int[10];
        final CountDownLatch latch = new CountDownLatch(2);
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                stateCnts[newState] = stateCnts[newState] + 1;
                latch.countDown();
            }
        });
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                mRecyclerView.smoothScrollBy(0, 500);
            }
        });
        latch.await(5, TimeUnit.SECONDS);
        assertEquals(1, stateCnts[SCROLL_STATE_SETTLING]);
        assertEquals(1, stateCnts[SCROLL_STATE_IDLE]);
        assertEquals(0, stateCnts[SCROLL_STATE_DRAGGING]);
    }

    @Test
    public void testScrollStateForSmoothScrollWithStop() throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        TestLayoutManager tlm = new TestLayoutManager();
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(tlm);
        setRecyclerView(recyclerView);
        getInstrumentation().waitForIdleSync();
        assertEquals(SCROLL_STATE_IDLE, recyclerView.getScrollState());
        final int[] stateCnts = new int[10];
        final CountDownLatch latch = new CountDownLatch(1);
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                stateCnts[newState] = stateCnts[newState] + 1;
                latch.countDown();
            }
        });
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                mRecyclerView.smoothScrollBy(0, 500);
            }
        });
        latch.await(5, TimeUnit.SECONDS);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                mRecyclerView.stopScroll();
            }
        });
        assertEquals(SCROLL_STATE_IDLE, recyclerView.getScrollState());
        assertEquals(1, stateCnts[SCROLL_STATE_SETTLING]);
        assertEquals(1, stateCnts[SCROLL_STATE_IDLE]);
        assertEquals(0, stateCnts[SCROLL_STATE_DRAGGING]);
    }

    @Test
    public void testScrollStateForFling() throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        TestLayoutManager tlm = new TestLayoutManager();
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(tlm);
        setRecyclerView(recyclerView);
        getInstrumentation().waitForIdleSync();
        assertEquals(SCROLL_STATE_IDLE, recyclerView.getScrollState());
        final int[] stateCnts = new int[10];
        final CountDownLatch latch = new CountDownLatch(2);
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                stateCnts[newState] = stateCnts[newState] + 1;
                latch.countDown();
            }
        });
        final ViewConfiguration vc = ViewConfiguration.get(getActivity());
        final float fling = vc.getScaledMinimumFlingVelocity()
                + (vc.getScaledMaximumFlingVelocity() - vc.getScaledMinimumFlingVelocity()) * .1f;
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                mRecyclerView.fling(0, Math.round(fling));
            }
        });
        latch.await(5, TimeUnit.SECONDS);
        assertEquals(1, stateCnts[SCROLL_STATE_SETTLING]);
        assertEquals(1, stateCnts[SCROLL_STATE_IDLE]);
        assertEquals(0, stateCnts[SCROLL_STATE_DRAGGING]);
    }

    @Test
    public void testScrollStateForFlingWithStop() throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        TestLayoutManager tlm = new TestLayoutManager();
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(tlm);
        setRecyclerView(recyclerView);
        getInstrumentation().waitForIdleSync();
        assertEquals(SCROLL_STATE_IDLE, recyclerView.getScrollState());
        final int[] stateCnts = new int[10];
        final CountDownLatch latch = new CountDownLatch(1);
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                stateCnts[newState] = stateCnts[newState] + 1;
                latch.countDown();
            }
        });
        final ViewConfiguration vc = ViewConfiguration.get(getActivity());
        final float fling = vc.getScaledMinimumFlingVelocity()
                + (vc.getScaledMaximumFlingVelocity() - vc.getScaledMinimumFlingVelocity()) * .8f;
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                mRecyclerView.fling(0, Math.round(fling));
            }
        });
        latch.await(5, TimeUnit.SECONDS);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                mRecyclerView.stopScroll();
            }
        });
        assertEquals(SCROLL_STATE_IDLE, recyclerView.getScrollState());
        assertEquals(1, stateCnts[SCROLL_STATE_SETTLING]);
        assertEquals(1, stateCnts[SCROLL_STATE_IDLE]);
        assertEquals(0, stateCnts[SCROLL_STATE_DRAGGING]);
    }

    @Test
    public void testScrollStateDrag() throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        TestLayoutManager tlm = new TestLayoutManager();
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(tlm);
        setRecyclerView(recyclerView);
        getInstrumentation().waitForIdleSync();
        assertEquals(SCROLL_STATE_IDLE, recyclerView.getScrollState());
        final int[] stateCnts = new int[10];
        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                stateCnts[newState] = stateCnts[newState] + 1;
            }
        });
        drag(mRecyclerView, 0, 0, 0, 500, 5);
        assertEquals(0, stateCnts[SCROLL_STATE_SETTLING]);
        assertEquals(1, stateCnts[SCROLL_STATE_IDLE]);
        assertEquals(1, stateCnts[SCROLL_STATE_DRAGGING]);
    }

    public void drag(ViewGroup view, float fromX, float toX, float fromY, float toY,
            int stepCount) throws Throwable {
        long downTime = SystemClock.uptimeMillis();
        long eventTime = SystemClock.uptimeMillis();

        float y = fromY;
        float x = fromX;

        float yStep = (toY - fromY) / stepCount;
        float xStep = (toX - fromX) / stepCount;

        MotionEvent event = MotionEvent.obtain(downTime, eventTime,
                MotionEvent.ACTION_DOWN, x, y, 0);
        sendTouch(view, event);
        for (int i = 0; i < stepCount; ++i) {
            y += yStep;
            x += xStep;
            eventTime = SystemClock.uptimeMillis();
            event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, x, y, 0);
            sendTouch(view, event);
        }

        eventTime = SystemClock.uptimeMillis();
        event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, x, y, 0);
        sendTouch(view, event);
        getInstrumentation().waitForIdleSync();
    }

    private void sendTouch(final ViewGroup view, final MotionEvent event) throws Throwable {
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (view.onInterceptTouchEvent(event)) {
                    view.onTouchEvent(event);
                }
            }
        });
    }

    @Test
    public void testRecycleScrap() throws Throwable {
        recycleScrapTest(false);
        removeRecyclerView();
        recycleScrapTest(true);
    }

    public void recycleScrapTest(final boolean useRecycler) throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        final AtomicBoolean test = new AtomicBoolean(false);
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                ViewInfoStore infoStore = mRecyclerView.mViewInfoStore;
                if (test.get()) {
                    try {
                        detachAndScrapAttachedViews(recycler);
                        for (int i = recycler.getScrapList().size() - 1; i >= 0; i--) {
                            if (useRecycler) {
                                recycler.recycleView(recycler.getScrapList().get(i).itemView);
                            } else {
                                removeAndRecycleView(recycler.getScrapList().get(i).itemView,
                                        recycler);
                            }
                        }
                        if (infoStore.mOldChangedHolders != null) {
                            for (int i = infoStore.mOldChangedHolders.size() - 1; i >= 0; i--) {
                                if (useRecycler) {
                                    recycler.recycleView(
                                            infoStore.mOldChangedHolders.valueAt(i).itemView);
                                } else {
                                    removeAndRecycleView(
                                            infoStore.mOldChangedHolders.valueAt(i).itemView,
                                            recycler);
                                }
                            }
                        }
                        assertEquals("no scrap should be left over", 0, recycler.getScrapCount());
                        assertEquals("pre layout map should be empty", 0,
                                InfoStoreTrojan.sizeOfPreLayout(infoStore));
                        assertEquals("post layout map should be empty", 0,
                                InfoStoreTrojan.sizeOfPostLayout(infoStore));
                        if (infoStore.mOldChangedHolders != null) {
                            assertEquals("post old change map should be empty", 0,
                                    infoStore.mOldChangedHolders.size());
                        }
                    } catch (Throwable t) {
                        postExceptionToInstrumentation(t);
                    }

                }
                layoutRange(recycler, 0, 5);
                layoutLatch.countDown();
                super.onLayoutChildren(recycler, state);
            }
        };
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(lm);
        ((SimpleItemAnimator)recyclerView.getItemAnimator()).setSupportsChangeAnimations(true);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        test.set(true);
        lm.expectLayouts(1);
        testAdapter.changeAndNotify(3, 1);
        lm.waitForLayout(2);
        checkForMainThreadException();
    }

    @Test
    public void testAccessRecyclerOnOnMeasure() throws Throwable {
        accessRecyclerOnOnMeasureTest(false);
        removeRecyclerView();
        accessRecyclerOnOnMeasureTest(true);
    }

    @Test
    public void testSmoothScrollWithRemovedItemsAndRemoveItem() throws Throwable {
        smoothScrollTest(true);
    }

    @Test
    public void testSmoothScrollWithRemovedItems() throws Throwable {
        smoothScrollTest(false);
    }

    public void smoothScrollTest(final boolean removeItem) throws Throwable {
        final LinearSmoothScroller[] lss = new LinearSmoothScroller[1];
        final CountDownLatch calledOnStart = new CountDownLatch(1);
        final CountDownLatch calledOnStop = new CountDownLatch(1);
        final int visibleChildCount = 10;
        TestLayoutManager lm = new TestLayoutManager() {
            int start = 0;

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                layoutRange(recycler, start, visibleChildCount);
                layoutLatch.countDown();
            }

            @Override
            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                start++;
                if (DEBUG) {
                    Log.d(TAG, "on scroll, remove and recycling. start:" + start + ", cnt:"
                            + visibleChildCount);
                }
                removeAndRecycleAllViews(recycler);
                layoutRange(recycler, start,
                        Math.max(state.getItemCount(), start + visibleChildCount));
                return dy;
            }

            @Override
            public boolean canScrollVertically() {
                return true;
            }

            @Override
            public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                    int position) {
                LinearSmoothScroller linearSmoothScroller =
                        new LinearSmoothScroller(recyclerView.getContext()) {
                            @Override
                            public PointF computeScrollVectorForPosition(int targetPosition) {
                                return new PointF(0, 1);
                            }

                            @Override
                            protected void onStart() {
                                super.onStart();
                                calledOnStart.countDown();
                            }

                            @Override
                            protected void onStop() {
                                super.onStop();
                                calledOnStop.countDown();
                            }
                        };
                linearSmoothScroller.setTargetPosition(position);
                lss[0] = linearSmoothScroller;
                startSmoothScroll(linearSmoothScroller);
            }
        };
        final RecyclerView rv = new RecyclerView(getActivity());
        TestAdapter testAdapter = new TestAdapter(500);
        rv.setLayoutManager(lm);
        rv.setAdapter(testAdapter);
        lm.expectLayouts(1);
        setRecyclerView(rv);
        lm.waitForLayout(1);
        // regular scroll
        final int targetPosition = visibleChildCount * (removeItem ? 30 : 4);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                rv.smoothScrollToPosition(targetPosition);
            }
        });
        if (DEBUG) {
            Log.d(TAG, "scrolling to target position " + targetPosition);
        }
        assertTrue("on start should be called very soon", calledOnStart.await(2, TimeUnit.SECONDS));
        if (removeItem) {
            final int newTarget = targetPosition - 10;
            testAdapter.deleteAndNotify(newTarget + 1, testAdapter.getItemCount() - newTarget - 1);
            final CountDownLatch targetCheck = new CountDownLatch(1);
            runTestOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ViewCompat.postOnAnimationDelayed(rv, new Runnable() {
                        @Override
                        public void run() {
                            try {
                                assertEquals("scroll position should be updated to next available",
                                        newTarget, lss[0].getTargetPosition());
                            } catch (Throwable t) {
                                postExceptionToInstrumentation(t);
                            }
                            targetCheck.countDown();
                        }
                    }, 50);
                }
            });
            assertTrue("target position should be checked on time ",
                    targetCheck.await(10, TimeUnit.SECONDS));
            checkForMainThreadException();
            assertTrue("on stop should be called", calledOnStop.await(30, TimeUnit.SECONDS));
            checkForMainThreadException();
            assertNotNull("should scroll to new target " + newTarget
                    , rv.findViewHolderForLayoutPosition(newTarget));
            if (DEBUG) {
                Log.d(TAG, "on stop has been called on time");
            }
        } else {
            assertTrue("on stop should be called eventually",
                    calledOnStop.await(30, TimeUnit.SECONDS));
            assertNotNull("scroll to position should succeed",
                    rv.findViewHolderForLayoutPosition(targetPosition));
        }
        checkForMainThreadException();
    }

    @Test
    public void testConsecutiveSmoothScroll() throws Throwable {
        final AtomicInteger visibleChildCount = new AtomicInteger(10);
        final AtomicInteger totalScrolled = new AtomicInteger(0);
        final TestLayoutManager lm = new TestLayoutManager() {
            int start = 0;

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                layoutRange(recycler, start, visibleChildCount.get());
                layoutLatch.countDown();
            }

            @Override
            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                totalScrolled.set(totalScrolled.get() + dy);
                return dy;
            }

            @Override
            public boolean canScrollVertically() {
                return true;
            }
        };
        final RecyclerView rv = new RecyclerView(getActivity());
        TestAdapter testAdapter = new TestAdapter(500);
        rv.setLayoutManager(lm);
        rv.setAdapter(testAdapter);
        lm.expectLayouts(1);
        setRecyclerView(rv);
        lm.waitForLayout(1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                rv.smoothScrollBy(0, 2000);
            }
        });
        Thread.sleep(250);
        final AtomicInteger scrollAmt = new AtomicInteger();
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                final int soFar = totalScrolled.get();
                scrollAmt.set(soFar);
                rv.smoothScrollBy(0, 5000 - soFar);
            }
        });
        while (rv.getScrollState() != SCROLL_STATE_IDLE) {
            Thread.sleep(100);
        }
        final int soFar = totalScrolled.get();
        assertEquals("second scroll should be competed properly", 5000, soFar);
    }

    public void accessRecyclerOnOnMeasureTest(final boolean enablePredictiveAnimations)
            throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        final AtomicInteger expectedOnMeasureStateCount = new AtomicInteger(10);
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                try {
                    layoutRange(recycler, 0, state.getItemCount());
                    layoutLatch.countDown();
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }
            }

            @Override
            public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
                    int widthSpec, int heightSpec) {
                try {
                    // make sure we access all views
                    for (int i = 0; i < state.getItemCount(); i++) {
                        View view = recycler.getViewForPosition(i);
                        assertNotNull(view);
                        assertEquals(i, getPosition(view));
                    }
                    assertEquals(state.toString(),
                            expectedOnMeasureStateCount.get(), state.getItemCount());
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                }
                super.onMeasure(recycler, state, widthSpec, heightSpec);
            }

            @Override
            public boolean supportsPredictiveItemAnimations() {
                return enablePredictiveAnimations;
            }
        };
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setLayoutManager(lm);
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        checkForMainThreadException();
        lm.expectLayouts(1);
        if (!enablePredictiveAnimations) {
            expectedOnMeasureStateCount.set(15);
        }
        testAdapter.addAndNotify(4, 5);
        lm.waitForLayout(2);
        checkForMainThreadException();
    }

    @Test
    public void testSetCompatibleAdapter() throws Throwable {
        compatibleAdapterTest(true, true);
        removeRecyclerView();
        compatibleAdapterTest(false, true);
        removeRecyclerView();
        compatibleAdapterTest(true, false);
        removeRecyclerView();
        compatibleAdapterTest(false, false);
        removeRecyclerView();
    }

    private void compatibleAdapterTest(boolean useCustomPool, boolean removeAndRecycleExistingViews)
            throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        final AtomicInteger recycledViewCount = new AtomicInteger();
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                try {
                    layoutRange(recycler, 0, state.getItemCount());
                    layoutLatch.countDown();
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }
            }
        };
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setLayoutManager(lm);
        recyclerView.setAdapter(testAdapter);
        recyclerView.setRecyclerListener(new RecyclerView.RecyclerListener() {
            @Override
            public void onViewRecycled(RecyclerView.ViewHolder holder) {
                recycledViewCount.incrementAndGet();
            }
        });
        lm.expectLayouts(1);
        setRecyclerView(recyclerView, !useCustomPool);
        lm.waitForLayout(2);
        checkForMainThreadException();
        lm.expectLayouts(1);
        swapAdapter(new TestAdapter(10), removeAndRecycleExistingViews);
        lm.waitForLayout(2);
        checkForMainThreadException();
        if (removeAndRecycleExistingViews) {
            assertTrue("Previous views should be recycled", recycledViewCount.get() > 0);
        } else {
            assertEquals("No views should be recycled if adapters are compatible and developer "
                    + "did not request a recycle", 0, recycledViewCount.get());
        }
    }

    @Test
    public void testSetIncompatibleAdapter() throws Throwable {
        incompatibleAdapterTest(true);
        incompatibleAdapterTest(false);
    }

    public void incompatibleAdapterTest(boolean useCustomPool) throws Throwable {
        TestAdapter testAdapter = new TestAdapter(10);
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                try {
                    layoutRange(recycler, 0, state.getItemCount());
                    layoutLatch.countDown();
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }
            }
        };
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setLayoutManager(lm);
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView, !useCustomPool);
        lm.waitForLayout(2);
        checkForMainThreadException();
        lm.expectLayouts(1);
        setAdapter(new TestAdapter2(10));
        lm.waitForLayout(2);
        checkForMainThreadException();
    }

    @Test
    public void testRecycleIgnored() throws Throwable {
        final TestAdapter adapter = new TestAdapter(10);
        final TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                layoutRange(recycler, 0, 5);
                layoutLatch.countDown();
            }
        };
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                View child1 = lm.findViewByPosition(0);
                View child2 = lm.findViewByPosition(1);
                lm.ignoreView(child1);
                lm.ignoreView(child2);

                lm.removeAndRecycleAllViews(recyclerView.mRecycler);
                assertEquals("ignored child should not be recycled or removed", 2,
                        lm.getChildCount());

                Throwable[] throwables = new Throwable[1];
                try {
                    lm.removeAndRecycleView(child1, mRecyclerView.mRecycler);
                } catch (Throwable t) {
                    throwables[0] = t;
                }
                assertTrue("Trying to recycle an ignored view should throw IllegalArgException "
                        , throwables[0] instanceof IllegalArgumentException);
                lm.removeAllViews();
                assertEquals("ignored child should be removed as well ", 0, lm.getChildCount());
            }
        });
    }

    @Test
    public void testFindIgnoredByPosition() throws Throwable {
        final TestAdapter adapter = new TestAdapter(10);
        final TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                layoutRange(recycler, 0, 5);
                layoutLatch.countDown();
            }
        };
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        Thread.sleep(5000);
        final int pos = 1;
        final View[] ignored = new View[1];
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                View child = lm.findViewByPosition(pos);
                lm.ignoreView(child);
                ignored[0] = child;
            }
        });
        assertNotNull("ignored child should not be null", ignored[0]);
        assertNull("find view by position should not return ignored child",
                lm.findViewByPosition(pos));
        lm.expectLayouts(1);
        requestLayoutOnUIThread(mRecyclerView);
        lm.waitForLayout(1);
        assertEquals("child count should be ", 6, lm.getChildCount());
        View replacement = lm.findViewByPosition(pos);
        assertNotNull("re-layout should replace ignored child w/ another one", replacement);
        assertNotSame("replacement should be a different view", replacement, ignored[0]);
    }

    @Test
    public void testInvalidateAllDecorOffsets() throws Throwable {
        final TestAdapter adapter = new TestAdapter(10);
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        final AtomicBoolean invalidatedOffsets = new AtomicBoolean(true);
        recyclerView.setAdapter(adapter);
        final AtomicInteger layoutCount = new AtomicInteger(4);
        final RecyclerView.ItemDecoration dummyItemDecoration = new RecyclerView.ItemDecoration() {
        };
        TestLayoutManager testLayoutManager = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                try {
                    // test
                    for (int i = 0; i < getChildCount(); i++) {
                        View child = getChildAt(i);
                        RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams)
                                child.getLayoutParams();
                        assertEquals(
                                "Decor insets validation for VH should have expected value.",
                                invalidatedOffsets.get(), lp.mInsetsDirty);
                    }
                    for (RecyclerView.ViewHolder vh : mRecyclerView.mRecycler.mCachedViews) {
                        RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams)
                                vh.itemView.getLayoutParams();
                        assertEquals(
                                "Decor insets invalidation in cache for VH should have expected "
                                        + "value.",
                                invalidatedOffsets.get(), lp.mInsetsDirty);
                    }
                    detachAndScrapAttachedViews(recycler);
                    layoutRange(recycler, 0, layoutCount.get());
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }
            }

            @Override
            public boolean supportsPredictiveItemAnimations() {
                return false;
            }
        };
        // first layout
        recyclerView.setItemViewCacheSize(5);
        recyclerView.setLayoutManager(testLayoutManager);
        testLayoutManager.expectLayouts(1);
        setRecyclerView(recyclerView, true, false);
        testLayoutManager.waitForLayout(2);
        checkForMainThreadException();

        // re-layout w/o any change
        invalidatedOffsets.set(false);
        testLayoutManager.expectLayouts(1);
        requestLayoutOnUIThread(recyclerView);
        testLayoutManager.waitForLayout(1);
        checkForMainThreadException();

        // invalidate w/o an item decorator

        invalidateDecorOffsets(recyclerView);
        testLayoutManager.expectLayouts(1);
        invalidateDecorOffsets(recyclerView);
        testLayoutManager.assertNoLayout("layout should not happen", 2);
        checkForMainThreadException();

        // set item decorator, should invalidate
        invalidatedOffsets.set(true);
        testLayoutManager.expectLayouts(1);
        addItemDecoration(mRecyclerView, dummyItemDecoration);
        testLayoutManager.waitForLayout(1);
        checkForMainThreadException();

        // re-layout w/o any change
        invalidatedOffsets.set(false);
        testLayoutManager.expectLayouts(1);
        requestLayoutOnUIThread(recyclerView);
        testLayoutManager.waitForLayout(1);
        checkForMainThreadException();

        // invalidate w/ item decorator
        invalidatedOffsets.set(true);
        invalidateDecorOffsets(recyclerView);
        testLayoutManager.expectLayouts(1);
        invalidateDecorOffsets(recyclerView);
        testLayoutManager.waitForLayout(2);
        checkForMainThreadException();

        // trigger cache.
        layoutCount.set(3);
        invalidatedOffsets.set(false);
        testLayoutManager.expectLayouts(1);
        requestLayoutOnUIThread(mRecyclerView);
        testLayoutManager.waitForLayout(1);
        checkForMainThreadException();
        assertEquals("a view should be cached", 1, mRecyclerView.mRecycler.mCachedViews.size());

        layoutCount.set(5);
        invalidatedOffsets.set(true);
        testLayoutManager.expectLayouts(1);
        invalidateDecorOffsets(recyclerView);
        testLayoutManager.waitForLayout(1);
        checkForMainThreadException();

        // remove item decorator
        invalidatedOffsets.set(true);
        testLayoutManager.expectLayouts(1);
        removeItemDecoration(mRecyclerView, dummyItemDecoration);
        testLayoutManager.waitForLayout(1);
        checkForMainThreadException();
    }

    public void addItemDecoration(final RecyclerView recyclerView, final
    RecyclerView.ItemDecoration itemDecoration) throws Throwable {
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                recyclerView.addItemDecoration(itemDecoration);
            }
        });
    }

    public void removeItemDecoration(final RecyclerView recyclerView, final
    RecyclerView.ItemDecoration itemDecoration) throws Throwable {
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                recyclerView.removeItemDecoration(itemDecoration);
            }
        });
    }

    public void invalidateDecorOffsets(final RecyclerView recyclerView) throws Throwable {
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                recyclerView.invalidateItemDecorations();
            }
        });
    }

    @Test
    public void testInvalidateDecorOffsets() throws Throwable {
        final TestAdapter adapter = new TestAdapter(10);
        adapter.setHasStableIds(true);
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(adapter);

        final Map<Long, Boolean> changes = new HashMap<Long, Boolean>();

        TestLayoutManager testLayoutManager = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                try {
                    if (changes.size() > 0) {
                        // test
                        for (int i = 0; i < getChildCount(); i++) {
                            View child = getChildAt(i);
                            RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams)
                                    child.getLayoutParams();
                            RecyclerView.ViewHolder vh = lp.mViewHolder;
                            if (!changes.containsKey(vh.getItemId())) {
                                continue; //nothing to test
                            }
                            assertEquals(
                                    "Decord insets validation for VH should have expected value.",
                                    changes.get(vh.getItemId()).booleanValue(),
                                    lp.mInsetsDirty);
                        }
                    }
                    detachAndScrapAttachedViews(recycler);
                    layoutRange(recycler, 0, state.getItemCount());
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }
            }

            @Override
            public boolean supportsPredictiveItemAnimations() {
                return false;
            }
        };
        recyclerView.setLayoutManager(testLayoutManager);
        testLayoutManager.expectLayouts(1);
        setRecyclerView(recyclerView);
        testLayoutManager.waitForLayout(2);
        int itemAddedTo = 5;
        for (int i = 0; i < itemAddedTo; i++) {
            changes.put(mRecyclerView.findViewHolderForLayoutPosition(i).getItemId(), false);
        }
        for (int i = itemAddedTo; i < mRecyclerView.getChildCount(); i++) {
            changes.put(mRecyclerView.findViewHolderForLayoutPosition(i).getItemId(), true);
        }
        testLayoutManager.expectLayouts(1);
        adapter.addAndNotify(5, 1);
        testLayoutManager.waitForLayout(2);
        checkForMainThreadException();

        changes.clear();
        int[] changedItems = new int[]{3, 5, 6};
        for (int i = 0; i < adapter.getItemCount(); i++) {
            changes.put(mRecyclerView.findViewHolderForLayoutPosition(i).getItemId(), false);
        }
        for (int i = 0; i < changedItems.length; i++) {
            changes.put(mRecyclerView.findViewHolderForLayoutPosition(changedItems[i]).getItemId(),
                    true);
        }
        testLayoutManager.expectLayouts(1);
        adapter.changePositionsAndNotify(changedItems);
        testLayoutManager.waitForLayout(2);
        checkForMainThreadException();

        for (int i = 0; i < adapter.getItemCount(); i++) {
            changes.put(mRecyclerView.findViewHolderForLayoutPosition(i).getItemId(), true);
        }
        testLayoutManager.expectLayouts(1);
        adapter.dispatchDataSetChanged();
        testLayoutManager.waitForLayout(2);
        checkForMainThreadException();
    }

    @Test
    public void testMovingViaStableIds() throws Throwable {
        stableIdsMoveTest(true);
        removeRecyclerView();
        stableIdsMoveTest(false);
        removeRecyclerView();
    }

    public void stableIdsMoveTest(final boolean supportsPredictive) throws Throwable {
        final TestAdapter testAdapter = new TestAdapter(10);
        testAdapter.setHasStableIds(true);
        final AtomicBoolean test = new AtomicBoolean(false);
        final int movedViewFromIndex = 3;
        final int movedViewToIndex = 6;
        final View[] movedView = new View[1];
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                try {
                    if (test.get()) {
                        if (state.isPreLayout()) {
                            View view = recycler.getViewForPosition(movedViewFromIndex, true);
                            assertSame("In pre layout, should be able to get moved view w/ old "
                                    + "position", movedView[0], view);
                            RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(view);
                            assertTrue("it should come from scrap", holder.wasReturnedFromScrap());
                            // clear scrap flag
                            holder.clearReturnedFromScrapFlag();
                        } else {
                            View view = recycler.getViewForPosition(movedViewToIndex, true);
                            assertSame("In post layout, should be able to get moved view w/ new "
                                    + "position", movedView[0], view);
                            RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(view);
                            assertTrue("it should come from scrap", holder.wasReturnedFromScrap());
                            // clear scrap flag
                            holder.clearReturnedFromScrapFlag();
                        }
                    }
                    layoutRange(recycler, 0, state.getItemCount());
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }


            }

            @Override
            public boolean supportsPredictiveItemAnimations() {
                return supportsPredictive;
            }
        };
        RecyclerView recyclerView = new RecyclerView(this.getActivity());
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(1);

        movedView[0] = recyclerView.getChildAt(movedViewFromIndex);
        test.set(true);
        lm.expectLayouts(supportsPredictive ? 2 : 1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                Item item = testAdapter.mItems.remove(movedViewFromIndex);
                testAdapter.mItems.add(movedViewToIndex, item);
                testAdapter.notifyItemRemoved(movedViewFromIndex);
                testAdapter.notifyItemInserted(movedViewToIndex);
            }
        });
        lm.waitForLayout(2);
        checkForMainThreadException();
    }

    @Test
    public void testAdapterChangeDuringLayout() throws Throwable {
        adapterChangeInMainThreadTest("notifyDataSetChanged", new Runnable() {
            @Override
            public void run() {
                mRecyclerView.getAdapter().notifyDataSetChanged();
            }
        });

        adapterChangeInMainThreadTest("notifyItemChanged", new Runnable() {
            @Override
            public void run() {
                mRecyclerView.getAdapter().notifyItemChanged(2);
            }
        });

        adapterChangeInMainThreadTest("notifyItemInserted", new Runnable() {
            @Override
            public void run() {
                mRecyclerView.getAdapter().notifyItemInserted(2);
            }
        });
        adapterChangeInMainThreadTest("notifyItemRemoved", new Runnable() {
            @Override
            public void run() {
                mRecyclerView.getAdapter().notifyItemRemoved(2);
            }
        });
    }

    public void adapterChangeInMainThreadTest(String msg,
            final Runnable onLayoutRunnable) throws Throwable {
        final AtomicBoolean doneFirstLayout = new AtomicBoolean(false);
        TestAdapter testAdapter = new TestAdapter(10);
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                try {
                    layoutRange(recycler, 0, state.getItemCount());
                    if (doneFirstLayout.get()) {
                        onLayoutRunnable.run();
                    }
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }

            }
        };
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setLayoutManager(lm);
        recyclerView.setAdapter(testAdapter);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        doneFirstLayout.set(true);
        lm.expectLayouts(1);
        requestLayoutOnUIThread(recyclerView);
        lm.waitForLayout(2);
        removeRecyclerView();
        assertTrue("Invalid data updates should be caught:" + msg,
                mainThreadException instanceof IllegalStateException);
        mainThreadException = null;
    }

    @Test
    public void testAdapterChangeDuringScroll() throws Throwable {
        for (int orientation : new int[]{OrientationHelper.HORIZONTAL,
                OrientationHelper.VERTICAL}) {
            adapterChangeDuringScrollTest("notifyDataSetChanged", orientation,
                    new Runnable() {
                        @Override
                        public void run() {
                            mRecyclerView.getAdapter().notifyDataSetChanged();
                        }
                    });
            adapterChangeDuringScrollTest("notifyItemChanged", orientation, new Runnable() {
                @Override
                public void run() {
                    mRecyclerView.getAdapter().notifyItemChanged(2);
                }
            });

            adapterChangeDuringScrollTest("notifyItemInserted", orientation, new Runnable() {
                @Override
                public void run() {
                    mRecyclerView.getAdapter().notifyItemInserted(2);
                }
            });
            adapterChangeDuringScrollTest("notifyItemRemoved", orientation, new Runnable() {
                @Override
                public void run() {
                    mRecyclerView.getAdapter().notifyItemRemoved(2);
                }
            });
        }
    }

    public void adapterChangeDuringScrollTest(String msg, final int orientation,
            final Runnable onScrollRunnable) throws Throwable {
        TestAdapter testAdapter = new TestAdapter(100);
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                try {
                    layoutRange(recycler, 0, 10);
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }
            }

            @Override
            public boolean canScrollVertically() {
                return orientation == OrientationHelper.VERTICAL;
            }

            @Override
            public boolean canScrollHorizontally() {
                return orientation == OrientationHelper.HORIZONTAL;
            }

            public int mockScroll() {
                try {
                    onScrollRunnable.run();
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }
                return 0;
            }

            @Override
            public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                return mockScroll();
            }

            @Override
            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                return mockScroll();
            }
        };
        RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setLayoutManager(lm);
        recyclerView.setAdapter(testAdapter);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        lm.expectLayouts(1);
        scrollBy(200);
        lm.waitForLayout(2);
        removeRecyclerView();
        assertTrue("Invalid data updates should be caught:" + msg,
                mainThreadException instanceof IllegalStateException);
        mainThreadException = null;
    }

    @Test
    public void testRecycleOnDetach() throws Throwable {
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        final TestAdapter testAdapter = new TestAdapter(10);
        final AtomicBoolean didRunOnDetach = new AtomicBoolean(false);
        final TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                layoutRange(recycler, 0, state.getItemCount() - 1);
                layoutLatch.countDown();
            }

            @Override
            public void onDetachedFromWindow(RecyclerView view, RecyclerView.Recycler recycler) {
                super.onDetachedFromWindow(view, recycler);
                didRunOnDetach.set(true);
                removeAndRecycleAllViews(recycler);
            }
        };
        recyclerView.setAdapter(testAdapter);
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        removeRecyclerView();
        assertTrue("When recycler view is removed, detach should run", didRunOnDetach.get());
        assertEquals("All children should be recycled", recyclerView.getChildCount(), 0);
    }

    @Test
    public void testUpdatesWhileDetached() throws Throwable {
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        final int initialAdapterSize = 20;
        final TestAdapter adapter = new TestAdapter(initialAdapterSize);
        final AtomicInteger layoutCount = new AtomicInteger(0);
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                layoutRange(recycler, 0, 5);
                layoutCount.incrementAndGet();
                layoutLatch.countDown();
            }
        };
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(lm);
        recyclerView.setHasFixedSize(true);
        lm.expectLayouts(1);
        adapter.addAndNotify(4, 5);
        lm.assertNoLayout("When RV is not attached, layout should not happen", 1);
    }

    @Test
    public void testUpdatesAfterDetach() throws Throwable {
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        final int initialAdapterSize = 20;
        final TestAdapter adapter = new TestAdapter(initialAdapterSize);
        final AtomicInteger layoutCount = new AtomicInteger(0);
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                layoutRange(recycler, 0, 5);
                layoutCount.incrementAndGet();
                layoutLatch.countDown();
            }
        };
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        recyclerView.setHasFixedSize(true);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        lm.expectLayouts(1);
        final int prevLayoutCount = layoutCount.get();
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    adapter.addAndNotify(4, 5);
                    removeRecyclerView();
                } catch (Throwable throwable) {
                    postExceptionToInstrumentation(throwable);
                }
            }
        });
        checkForMainThreadException();

        lm.assertNoLayout("When RV is not attached, layout should not happen", 1);
        assertEquals("No extra layout should happen when detached", prevLayoutCount,
                layoutCount.get());
    }

    @Test
    public void testNotifyDataSetChangedWithStableIds() throws Throwable {
        final int defaultViewType = 1;
        final Map<Item, Integer> viewTypeMap = new HashMap<Item, Integer>();
        final Map<Integer, Integer> oldPositionToNewPositionMapping =
                new HashMap<Integer, Integer>();
        final TestAdapter adapter = new TestAdapter(100) {
            @Override
            public int getItemViewType(int position) {
                Integer type = viewTypeMap.get(mItems.get(position));
                return type == null ? defaultViewType : type;
            }

            @Override
            public long getItemId(int position) {
                return mItems.get(position).mId;
            }
        };
        adapter.setHasStableIds(true);
        final ArrayList<Item> previousItems = new ArrayList<Item>();
        previousItems.addAll(adapter.mItems);

        final AtomicInteger layoutStart = new AtomicInteger(50);
        final AtomicBoolean validate = new AtomicBoolean(false);
        final int childCount = 10;
        final TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                try {
                    super.onLayoutChildren(recycler, state);
                    if (validate.get()) {
                        assertEquals("Cached views should be kept", 5, recycler
                                .mCachedViews.size());
                        for (RecyclerView.ViewHolder vh : recycler.mCachedViews) {
                            TestViewHolder tvh = (TestViewHolder) vh;
                            assertTrue("view holder should be marked for update",
                                    tvh.needsUpdate());
                            assertTrue("view holder should be marked as invalid", tvh.isInvalid());
                        }
                    }
                    detachAndScrapAttachedViews(recycler);
                    if (validate.get()) {
                        assertEquals("cache size should stay the same", 5,
                                recycler.mCachedViews.size());
                        assertEquals("all views should be scrapped", childCount,
                                recycler.getScrapList().size());
                        for (RecyclerView.ViewHolder vh : recycler.getScrapList()) {
                            // TODO create test case for type change
                            TestViewHolder tvh = (TestViewHolder) vh;
                            assertTrue("view holder should be marked for update",
                                    tvh.needsUpdate());
                            assertTrue("view holder should be marked as invalid", tvh.isInvalid());
                        }
                    }
                    layoutRange(recycler, layoutStart.get(), layoutStart.get() + childCount);
                    if (validate.get()) {
                        for (int i = 0; i < getChildCount(); i++) {
                            View view = getChildAt(i);
                            TestViewHolder tvh = (TestViewHolder) mRecyclerView
                                    .getChildViewHolder(view);
                            final int oldPos = previousItems.indexOf(tvh.mBoundItem);
                            assertEquals("view holder's position should be correct",
                                    oldPositionToNewPositionMapping.get(oldPos).intValue(),
                                    tvh.getLayoutPosition());
                            ;
                        }
                    }
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                } finally {
                    layoutLatch.countDown();
                }
            }
        };
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setItemAnimator(null);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(lm);
        recyclerView.setItemViewCacheSize(10);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        checkForMainThreadException();
        getInstrumentation().waitForIdleSync();
        layoutStart.set(layoutStart.get() + 5);//55
        lm.expectLayouts(1);
        requestLayoutOnUIThread(recyclerView);
        lm.waitForLayout(2);
        validate.set(true);
        lm.expectLayouts(1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    adapter.moveItems(false,
                            new int[]{50, 56}, new int[]{51, 1}, new int[]{52, 2},
                            new int[]{53, 54}, new int[]{60, 61}, new int[]{62, 64},
                            new int[]{75, 58});
                    for (int i = 0; i < previousItems.size(); i++) {
                        Item item = previousItems.get(i);
                        oldPositionToNewPositionMapping.put(i, adapter.mItems.indexOf(item));
                    }
                    adapter.dispatchDataSetChanged();
                } catch (Throwable throwable) {
                    postExceptionToInstrumentation(throwable);
                }
            }
        });
        lm.waitForLayout(2);
        checkForMainThreadException();
    }

    @Test
    public void testCallbacksDuringAdapterSwap() throws Throwable {
        callbacksDuringAdapterChange(true);
    }

    @Test
    public void testCallbacksDuringAdapterSet() throws Throwable {
        callbacksDuringAdapterChange(false);
    }

    public void callbacksDuringAdapterChange(boolean swap) throws Throwable {
        final TestAdapter2 adapter1 = swap ? createBinderCheckingAdapter()
                : createOwnerCheckingAdapter();
        final TestAdapter2 adapter2 = swap ? createBinderCheckingAdapter()
                : createOwnerCheckingAdapter();

        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                try {
                    layoutRange(recycler, 0, state.getItemCount());
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                }
                layoutLatch.countDown();
            }
        };
        RecyclerView rv = new RecyclerView(getActivity());
        rv.setAdapter(adapter1);
        rv.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(rv);
        tlm.waitForLayout(1);
        checkForMainThreadException();
        tlm.expectLayouts(1);
        if (swap) {
            swapAdapter(adapter2, true);
        } else {
            setAdapter(adapter2);
        }
        checkForMainThreadException();
        tlm.waitForLayout(1);
        checkForMainThreadException();
    }

    private TestAdapter2 createOwnerCheckingAdapter() {
        return new TestAdapter2(10) {
            @Override
            public void onViewRecycled(TestViewHolder2 holder) {
                assertSame("on recycled should be called w/ the creator adapter", this,
                        holder.mData);
                super.onViewRecycled(holder);
            }

            @Override
            public void onBindViewHolder(TestViewHolder2 holder, int position) {
                super.onBindViewHolder(holder, position);
                assertSame("on bind should be called w/ the creator adapter", this, holder.mData);
            }

            @Override
            public TestViewHolder2 onCreateViewHolder(ViewGroup parent,
                    int viewType) {
                final TestViewHolder2 vh = super.onCreateViewHolder(parent, viewType);
                vh.mData = this;
                return vh;
            }
        };
    }

    private TestAdapter2 createBinderCheckingAdapter() {
        return new TestAdapter2(10) {
            @Override
            public void onViewRecycled(TestViewHolder2 holder) {
                assertSame("on recycled should be called w/ the creator adapter", this,
                        holder.mData);
                holder.mData = null;
                super.onViewRecycled(holder);
            }

            @Override
            public void onBindViewHolder(TestViewHolder2 holder, int position) {
                super.onBindViewHolder(holder, position);
                holder.mData = this;
            }
        };
    }

    @Test
    public void testFindViewById() throws Throwable {
        findViewByIdTest(false);
        removeRecyclerView();
        findViewByIdTest(true);
    }

    public void findViewByIdTest(final boolean supportPredictive) throws Throwable {
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        final int initialAdapterSize = 20;
        final TestAdapter adapter = new TestAdapter(initialAdapterSize);
        final int deleteStart = 6;
        final int deleteCount = 5;
        recyclerView.setAdapter(adapter);
        final AtomicBoolean assertPositions = new AtomicBoolean(false);
        TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                if (assertPositions.get()) {
                    if (state.isPreLayout()) {
                        for (int i = 0; i < deleteStart; i++) {
                            View view = findViewByPosition(i);
                            assertNotNull("find view by position for existing items should work "
                                    + "fine", view);
                            assertFalse("view should not be marked as removed",
                                    ((RecyclerView.LayoutParams) view.getLayoutParams())
                                            .isItemRemoved());
                        }
                        for (int i = 0; i < deleteCount; i++) {
                            View view = findViewByPosition(i + deleteStart);
                            assertNotNull("find view by position should work fine for removed "
                                    + "views in pre-layout", view);
                            assertTrue("view should be marked as removed",
                                    ((RecyclerView.LayoutParams) view.getLayoutParams())
                                            .isItemRemoved());
                        }
                        for (int i = deleteStart + deleteCount; i < 20; i++) {
                            View view = findViewByPosition(i);
                            assertNotNull(view);
                            assertFalse("view should not be marked as removed",
                                    ((RecyclerView.LayoutParams) view.getLayoutParams())
                                            .isItemRemoved());
                        }
                    } else {
                        for (int i = 0; i < initialAdapterSize - deleteCount; i++) {
                            View view = findViewByPosition(i);
                            assertNotNull("find view by position for existing item " + i +
                                    " should work fine. child count:" + getChildCount(), view);
                            TestViewHolder viewHolder =
                                    (TestViewHolder) mRecyclerView.getChildViewHolder(view);
                            assertSame("should be the correct item " + viewHolder
                                    , viewHolder.mBoundItem,
                                    adapter.mItems.get(viewHolder.mPosition));
                            assertFalse("view should not be marked as removed",
                                    ((RecyclerView.LayoutParams) view.getLayoutParams())
                                            .isItemRemoved());
                        }
                    }
                }
                detachAndScrapAttachedViews(recycler);
                layoutRange(recycler, state.getItemCount() - 1, -1);
                layoutLatch.countDown();
            }

            @Override
            public boolean supportsPredictiveItemAnimations() {
                return supportPredictive;
            }
        };
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        getInstrumentation().waitForIdleSync();

        assertPositions.set(true);
        lm.expectLayouts(supportPredictive ? 2 : 1);
        adapter.deleteAndNotify(new int[]{deleteStart, deleteCount - 1}, new int[]{deleteStart, 1});
        lm.waitForLayout(2);
    }

    @Test
    public void testTypeForCache() throws Throwable {
        final AtomicInteger viewType = new AtomicInteger(1);
        final TestAdapter adapter = new TestAdapter(100) {
            @Override
            public int getItemViewType(int position) {
                return viewType.get();
            }

            @Override
            public long getItemId(int position) {
                return mItems.get(position).mId;
            }
        };
        adapter.setHasStableIds(true);
        final AtomicInteger layoutStart = new AtomicInteger(2);
        final int childCount = 10;
        final TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                detachAndScrapAttachedViews(recycler);
                layoutRange(recycler, layoutStart.get(), layoutStart.get() + childCount);
                layoutLatch.countDown();
            }
        };
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setItemAnimator(null);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(lm);
        recyclerView.setItemViewCacheSize(10);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        getInstrumentation().waitForIdleSync();
        layoutStart.set(4); // trigger a cache for 3,4
        lm.expectLayouts(1);
        requestLayoutOnUIThread(recyclerView);
        lm.waitForLayout(2);
        //
        viewType.incrementAndGet();
        layoutStart.set(2); // go back to bring views from cache
        lm.expectLayouts(1);
        adapter.mItems.remove(1);
        adapter.dispatchDataSetChanged();
        lm.waitForLayout(2);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                for (int i = 2; i < 4; i++) {
                    RecyclerView.ViewHolder vh = recyclerView.findViewHolderForLayoutPosition(i);
                    assertEquals("View holder's type should match latest type", viewType.get(),
                            vh.getItemViewType());
                }
            }
        });
    }

    @Test
    public void testTypeForExistingViews() throws Throwable {
        final AtomicInteger viewType = new AtomicInteger(1);
        final int invalidatedCount = 2;
        final int layoutStart = 2;
        final TestAdapter adapter = new TestAdapter(100) {
            @Override
            public int getItemViewType(int position) {
                return viewType.get();
            }

            @Override
            public void onBindViewHolder(TestViewHolder holder,
                    int position) {
                super.onBindViewHolder(holder, position);
                if (position >= layoutStart && position < invalidatedCount + layoutStart) {
                    try {
                        assertEquals("holder type should match current view type at position " +
                                position, viewType.get(), holder.getItemViewType());
                    } catch (Throwable t) {
                        postExceptionToInstrumentation(t);
                    }
                }
            }

            @Override
            public long getItemId(int position) {
                return mItems.get(position).mId;
            }
        };
        adapter.setHasStableIds(true);

        final int childCount = 10;
        final TestLayoutManager lm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                super.onLayoutChildren(recycler, state);
                detachAndScrapAttachedViews(recycler);
                layoutRange(recycler, layoutStart, layoutStart + childCount);
                layoutLatch.countDown();
            }
        };
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(lm);
        lm.expectLayouts(1);
        setRecyclerView(recyclerView);
        lm.waitForLayout(2);
        getInstrumentation().waitForIdleSync();
        viewType.incrementAndGet();
        lm.expectLayouts(1);
        adapter.changeAndNotify(layoutStart, invalidatedCount);
        lm.waitForLayout(2);
        checkForMainThreadException();
    }


    @Test
    public void testState() throws Throwable {
        final TestAdapter adapter = new TestAdapter(10);
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        recyclerView.setAdapter(adapter);
        recyclerView.setItemAnimator(null);
        final AtomicInteger itemCount = new AtomicInteger();
        final AtomicBoolean structureChanged = new AtomicBoolean();
        TestLayoutManager testLayoutManager = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                layoutRange(recycler, 0, state.getItemCount());
                itemCount.set(state.getItemCount());
                structureChanged.set(state.didStructureChange());
                layoutLatch.countDown();
            }
        };
        recyclerView.setLayoutManager(testLayoutManager);
        testLayoutManager.expectLayouts(1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                getActivity().mContainer.addView(recyclerView);
            }
        });
        testLayoutManager.waitForLayout(2, TimeUnit.SECONDS);

        assertEquals("item count in state should be correct", adapter.getItemCount()
                , itemCount.get());
        assertEquals("structure changed should be true for first layout", true,
                structureChanged.get());
        Thread.sleep(1000); //wait for other layouts.
        testLayoutManager.expectLayouts(1);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                recyclerView.requestLayout();
            }
        });
        testLayoutManager.waitForLayout(2);
        assertEquals("in second layout,structure changed should be false", false,
                structureChanged.get());
        testLayoutManager.expectLayouts(1); //
        adapter.deleteAndNotify(3, 2);
        testLayoutManager.waitForLayout(2);
        assertEquals("when items are removed, item count in state should be updated",
                adapter.getItemCount(),
                itemCount.get());
        assertEquals("structure changed should be true when items are removed", true,
                structureChanged.get());
        testLayoutManager.expectLayouts(1);
        adapter.addAndNotify(2, 5);
        testLayoutManager.waitForLayout(2);

        assertEquals("when items are added, item count in state should be updated",
                adapter.getItemCount(),
                itemCount.get());
        assertEquals("structure changed should be true when items are removed", true,
                structureChanged.get());
    }

    @Test
    public void testDetachWithoutLayoutManager() throws Throwable {
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    setRecyclerView(recyclerView);
                    removeRecyclerView();
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                }
            }
        });
        checkForMainThreadException();
    }

    @Test
    public void testUpdateHiddenView() throws Throwable {
        final RecyclerView.ViewHolder[] mTargetVH = new RecyclerView.ViewHolder[1];
        final RecyclerView recyclerView = new RecyclerView(getActivity());
        final int[] preLayoutRange = new int[]{0, 10};
        final int[] postLayoutRange = new int[]{0, 10};
        final AtomicBoolean enableGetViewTest = new AtomicBoolean(false);
        final List<Integer> disappearingPositions = new ArrayList<Integer>();
        final TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public boolean supportsPredictiveItemAnimations() {
                return true;
            }

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                try {
                    final int[] layoutRange = state.isPreLayout() ? preLayoutRange
                            : postLayoutRange;
                    detachAndScrapAttachedViews(recycler);
                    layoutRange(recycler, layoutRange[0], layoutRange[1]);
                    if (!state.isPreLayout()) {
                        for (Integer position : disappearingPositions) {
                            // test sanity.
                            assertNull(findViewByPosition(position));
                            final View view = recycler.getViewForPosition(position);
                            addDisappearingView(view);
                            measureChildWithMargins(view, 0, 0);
                            // position item out of bounds.
                            view.layout(0, -500, view.getMeasuredWidth(),
                                    -500 + view.getMeasuredHeight());
                        }
                    }
                } catch (Throwable t) {
                    postExceptionToInstrumentation(t);
                }
                layoutLatch.countDown();
            }
        };

        recyclerView.getItemAnimator().setMoveDuration(2000);
        recyclerView.getItemAnimator().setRemoveDuration(2000);
        final TestAdapter adapter = new TestAdapter(100);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(recyclerView);

        tlm.waitForLayout(1);
        checkForMainThreadException();
        mTargetVH[0] = recyclerView.findViewHolderForAdapterPosition(0);
        // now, a child disappears
        disappearingPositions.add(0);
        // layout one shifted
        postLayoutRange[0] = 1;
        postLayoutRange[1] = 11;
        tlm.expectLayouts(2);
        adapter.addAndNotify(8, 1);
        tlm.waitForLayout(2);
        checkForMainThreadException();

        tlm.expectLayouts(2);
        disappearingPositions.clear();
        // now that item should be moving, invalidate it and delete it.
        enableGetViewTest.set(true);
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {
                    adapter.changeAndNotify(0, 1);
                    adapter.deleteAndNotify(0, 1);
                } catch (Throwable throwable) {
                    throwable.printStackTrace();
                }
            }
        });
        tlm.waitForLayout(2);
        checkForMainThreadException();
    }

    @Test
    public void testFocusBigViewOnTop() throws Throwable {
        focusTooBigViewTest(Gravity.TOP);
    }

    @Test
    public void testFocusBigViewOnLeft() throws Throwable {
        focusTooBigViewTest(Gravity.LEFT);
    }

    @Test
    public void testFocusBigViewOnRight() throws Throwable {
        focusTooBigViewTest(Gravity.RIGHT);
    }

    @Test
    public void testFocusBigViewOnBottom() throws Throwable {
        focusTooBigViewTest(Gravity.BOTTOM);
    }

    @Test
    public void testFocusBigViewOnLeftRTL() throws Throwable {
        focusTooBigViewTest(Gravity.LEFT, true);
        assertEquals("test sanity", ViewCompat.LAYOUT_DIRECTION_RTL,
                mRecyclerView.getLayoutManager().getLayoutDirection());
    }

    @Test
    public void testFocusBigViewOnRightRTL() throws Throwable {
        focusTooBigViewTest(Gravity.RIGHT, true);
        assertEquals("test sanity", ViewCompat.LAYOUT_DIRECTION_RTL,
                mRecyclerView.getLayoutManager().getLayoutDirection());
    }

    public void focusTooBigViewTest(final int gravity) throws Throwable {
        focusTooBigViewTest(gravity, false);
    }

    public void focusTooBigViewTest(final int gravity, final boolean rtl) throws Throwable {
        RecyclerView rv = new RecyclerView(getActivity());
        if (rtl) {
            ViewCompat.setLayoutDirection(rv, ViewCompat.LAYOUT_DIRECTION_RTL);
        }
        final AtomicInteger vScrollDist = new AtomicInteger(0);
        final AtomicInteger hScrollDist = new AtomicInteger(0);
        final AtomicInteger vDesiredDist = new AtomicInteger(0);
        final AtomicInteger hDesiredDist = new AtomicInteger(0);
        TestLayoutManager tlm = new TestLayoutManager() {

            @Override
            public int getLayoutDirection() {
                return rtl ? ViewCompat.LAYOUT_DIRECTION_RTL : ViewCompat.LAYOUT_DIRECTION_LTR;
            }

            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                final View view = recycler.getViewForPosition(0);
                addView(view);
                int left = 0, top = 0;
                view.setBackgroundColor(Color.rgb(0, 0, 255));
                switch (gravity) {
                    case Gravity.LEFT:
                    case Gravity.RIGHT:
                        view.measure(
                                View.MeasureSpec.makeMeasureSpec((int) (getWidth() * 1.5),
                                        View.MeasureSpec.EXACTLY),
                                View.MeasureSpec.makeMeasureSpec((int) (getHeight() * .9),
                                        View.MeasureSpec.AT_MOST));
                        left = gravity == Gravity.LEFT ? getWidth() - view.getMeasuredWidth() - 80
                                : 90;
                        top = 0;
                        if (ViewCompat.LAYOUT_DIRECTION_RTL == getLayoutDirection()) {
                            hDesiredDist.set((left + view.getMeasuredWidth()) - getWidth());
                        } else {
                            hDesiredDist.set(left);
                        }
                        break;
                    case Gravity.TOP:
                    case Gravity.BOTTOM:
                        view.measure(
                                View.MeasureSpec.makeMeasureSpec((int) (getWidth() * .9),
                                        View.MeasureSpec.AT_MOST),
                                View.MeasureSpec.makeMeasureSpec((int) (getHeight() * 1.5),
                                        View.MeasureSpec.EXACTLY));
                        top = gravity == Gravity.TOP ? getHeight() - view.getMeasuredHeight() -
                                80 : 90;
                        left = 0;
                        vDesiredDist.set(top);
                        break;
                }

                view.layout(left, top, left + view.getMeasuredWidth(),
                        top + view.getMeasuredHeight());
                layoutLatch.countDown();
            }

            @Override
            public boolean canScrollVertically() {
                return true;
            }

            @Override
            public boolean canScrollHorizontally() {
                return super.canScrollHorizontally();
            }

            @Override
            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                vScrollDist.addAndGet(dy);
                getChildAt(0).offsetTopAndBottom(-dy);
                return dy;
            }

            @Override
            public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                hScrollDist.addAndGet(dx);
                getChildAt(0).offsetLeftAndRight(-dx);
                return dx;
            }
        };
        TestAdapter adapter = new TestAdapter(10);
        rv.setAdapter(adapter);
        rv.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(rv);
        tlm.waitForLayout(2);
        View view = rv.getChildAt(0);
        requestFocus(view);
        Thread.sleep(1000);
        assertEquals(vDesiredDist.get(), vScrollDist.get());
        assertEquals(hDesiredDist.get(), hScrollDist.get());
        assertEquals(mRecyclerView.getPaddingTop(), view.getTop());
        if (rtl) {
            assertEquals(mRecyclerView.getWidth() - mRecyclerView.getPaddingRight(),
                    view.getRight());
        } else {
            assertEquals(mRecyclerView.getPaddingLeft(), view.getLeft());
        }
    }

    @Test
    public void testFocusRectOnScreenWithDecorOffsets() throws Throwable {
        focusRectOnScreenTest(true);
    }

    @Test
    public void testFocusRectOnScreenWithout() throws Throwable {
        focusRectOnScreenTest(false);
    }


    public void focusRectOnScreenTest(boolean addItemDecors) throws Throwable {
        RecyclerView rv = new RecyclerView(getActivity());
        final AtomicInteger scrollDist = new AtomicInteger(0);
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                final View view = recycler.getViewForPosition(0);
                addView(view);
                measureChildWithMargins(view, 0, 0);
                view.layout(0, -20, view.getWidth(),
                        -20 + view.getHeight());// ignore decors on purpose
                layoutLatch.countDown();
            }

            @Override
            public boolean canScrollVertically() {
                return true;
            }

            @Override
            public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler,
                    RecyclerView.State state) {
                scrollDist.addAndGet(dy);
                return dy;
            }
        };
        TestAdapter adapter = new TestAdapter(10);
        if (addItemDecors) {
            rv.addItemDecoration(new RecyclerView.ItemDecoration() {
                @Override
                public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                        RecyclerView.State state) {
                    outRect.set(0, 10, 0, 10);
                }
            });
        }
        rv.setAdapter(adapter);
        rv.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(rv);
        tlm.waitForLayout(2);

        View view = rv.getChildAt(0);
        requestFocus(view);
        Thread.sleep(1000);
        assertEquals(addItemDecors ? -30 : -20, scrollDist.get());
    }

    @Test
    public void testUnimplementedSmoothScroll() throws Throwable {
        final AtomicInteger receivedScrollToPosition = new AtomicInteger(-1);
        final AtomicInteger receivedSmoothScrollToPosition = new AtomicInteger(-1);
        final CountDownLatch cbLatch = new CountDownLatch(2);
        TestLayoutManager tlm = new TestLayoutManager() {
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                layoutRange(recycler, 0, 10);
                layoutLatch.countDown();
            }

            @Override
            public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                    int position) {
                assertEquals(-1, receivedSmoothScrollToPosition.get());
                receivedSmoothScrollToPosition.set(position);
                RecyclerView.SmoothScroller ss =
                        new LinearSmoothScroller(recyclerView.getContext()) {
                            @Override
                            public PointF computeScrollVectorForPosition(int targetPosition) {
                                return null;
                            }
                        };
                ss.setTargetPosition(position);
                startSmoothScroll(ss);
                cbLatch.countDown();
            }

            @Override
            public void scrollToPosition(int position) {
                assertEquals(-1, receivedScrollToPosition.get());
                receivedScrollToPosition.set(position);
                cbLatch.countDown();
            }
        };
        RecyclerView rv = new RecyclerView(getActivity());
        rv.setAdapter(new TestAdapter(100));
        rv.setLayoutManager(tlm);
        tlm.expectLayouts(1);
        setRecyclerView(rv);
        tlm.waitForLayout(2);
        freezeLayout(true);
        smoothScrollToPosition(35);
        assertEquals("smoothScrollToPosition should be ignored when frozen",
                -1, receivedSmoothScrollToPosition.get());
        freezeLayout(false);
        smoothScrollToPosition(35);
        assertTrue("both scrolls should be called", cbLatch.await(3, TimeUnit.SECONDS));
        checkForMainThreadException();
        assertEquals(35, receivedSmoothScrollToPosition.get());
        assertEquals(35, receivedScrollToPosition.get());
    }

    @Test
    public void testJumpingJackSmoothScroller() throws Throwable {
        jumpingJackSmoothScrollerTest(true);
    }

    @Test
    public void testJumpingJackSmoothScrollerGoesIdle() throws Throwable {
        jumpingJackSmoothScrollerTest(false);
    }

    private void jumpingJackSmoothScrollerTest(final boolean succeed) throws Throwable {
        final List<Integer> receivedScrollToPositions = new ArrayList<>();
        final TestAdapter testAdapter = new TestAdapter(200);
        final AtomicBoolean mTargetFound = new AtomicBoolean(false);
        TestLayoutManager tlm = new TestLayoutManager() {
            int pendingScrollPosition = -1;
            @Override
            public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
                detachAndScrapAttachedViews(recycler);
                final int pos = pendingScrollPosition < 0 ? 0: pendingScrollPosition;
                layoutRange(recycler, pos, pos + 10);
                if (layoutLatch != null) {
                    layoutLatch.countDown();
                }
            }

            @Override
            public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state,
                    final int position) {
                RecyclerView.SmoothScroller ss =
                        new LinearSmoothScroller(recyclerView.getContext()) {
                            @Override
                            public PointF computeScrollVectorForPosition(int targetPosition) {
                                return new PointF(0, 1);
                            }

                            @Override
                            protected void onTargetFound(View targetView, RecyclerView.State state,
                                                         Action action) {
                                super.onTargetFound(targetView, state, action);
                                mTargetFound.set(true);
                            }

                            @Override
                            protected void updateActionForInterimTarget(Action action) {
                                int limit = succeed ? getTargetPosition() : 100;
                                if (pendingScrollPosition + 2 < limit) {
                                    if (pendingScrollPosition != NO_POSITION) {
                                        assertEquals(pendingScrollPosition,
                                                getChildViewHolderInt(getChildAt(0))
                                                        .getAdapterPosition());
                                    }
                                    action.jumpTo(pendingScrollPosition + 2);
                                }
                            }
                        };
                ss.setTargetPosition(position);
                startSmoothScroll(ss);
            }

            @Override
            public void scrollToPosition(int position) {
                receivedScrollToPositions.add(position);
                pendingScrollPosition = position;
                requestLayout();
            }
        };
        final RecyclerView rv = new RecyclerView(getActivity());
        rv.setAdapter(testAdapter);
        rv.setLayoutManager(tlm);

        tlm.expectLayouts(1);
        setRecyclerView(rv);
        tlm.waitForLayout(2);

        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                rv.smoothScrollToPosition(150);
            }
        });
        int limit = 100;
        while (rv.getLayoutManager().isSmoothScrolling() && --limit > 0) {
            Thread.sleep(200);
            checkForMainThreadException();
        }
        checkForMainThreadException();
        assertTrue(limit > 0);
        for (int i = 1; i < 100; i+=2) {
            assertTrue("scroll positions must include " + i, receivedScrollToPositions.contains(i));
        }

        assertEquals(succeed, mTargetFound.get());

    }

    private static class TestViewHolder2 extends RecyclerView.ViewHolder {

        Object mData;

        public TestViewHolder2(View itemView) {
            super(itemView);
        }
    }

    private static class TestAdapter2 extends RecyclerView.Adapter<TestViewHolder2> {

        List<Item> mItems;

        private TestAdapter2(int count) {
            mItems = new ArrayList<Item>(count);
            for (int i = 0; i < count; i++) {
                mItems.add(new Item(i, "Item " + i));
            }
        }

        @Override
        public TestViewHolder2 onCreateViewHolder(ViewGroup parent,
                int viewType) {
            return new TestViewHolder2(new TextView(parent.getContext()));
        }

        @Override
        public void onBindViewHolder(TestViewHolder2 holder, int position) {
            final Item item = mItems.get(position);
            ((TextView) (holder.itemView)).setText(item.mText + "(" + item.mAdapterIndex + ")");
        }

        @Override
        public int getItemCount() {
            return mItems.size();
        }
    }

    private static interface AdapterRunnable {

        public void run(TestAdapter adapter) throws Throwable;
    }

}
