@Test
public void testChainUsageWithChildInstance() throws Throwable {

  // simulate building upon a final @Rule at the class-level
  Mockspresso mockspresso = mRule.buildUpon().build();
  Statement base = verifyChildDelegateStatement(mockspresso, mChildMockspresso);
  TestTestRule outerRule1 = spy(new TestTestRule());
  TestMethodRule outerRule2 = spy(new TestMethodRule());
  TestTestRule innerRule1 = spy(new TestTestRule());
  TestMethodRule innerRule2 = spy(new TestMethodRule());
  mRuleConfig.addOuterRule(outerRule1);
  mRuleConfig.addOuterRule(outerRule2);
  mRuleConfig.addInnerRule(innerRule1);
  mRuleConfig.addInnerRule(innerRule2);
  Statement result = mRule.apply(base, mFrameworkMethod, mTarget);
  result.evaluate();
  InOrder inOrder = Mockito.inOrder(
      mConfig,
      mBuilderProvider,
      mBuilder,
      base,
      mConfig,
      mChildConfig,
      innerRule1,
      innerRule1.returnStatement,
      innerRule2,
      innerRule2.returnStatement,
      mChildBuilder,
      outerRule1,
      outerRule1.returnStatement,
      outerRule2,
      outerRule2.returnStatement);
  // first builderProvider.get happens inline
  inOrder.verify(mBuilderProvider).get();
  // apply happens in reverse order
  inOrder.verify(innerRule2).apply(base, mFrameworkMethod, mTarget);
  inOrder.verify(innerRule1).apply(eq(innerRule2.returnStatement), any(Description.class));
  inOrder.verify(outerRule2).apply(any(Statement.class), eq(mFrameworkMethod), eq(mTarget));
  inOrder.verify(outerRule1).apply(eq(outerRule2.returnStatement), any(Description.class));
  // eval happens in correct order, first outerRules, then mockspresso, then innerRule1, then innerRule2, then base
  inOrder.verify(outerRule1.returnStatement).before();
  inOrder.verify(outerRule2.returnStatement).before();
  inOrder.verify(mBuilder).deepCopy();
  inOrder.verify(mBuilder).testResourcesWithoutLifecycle(mTarget);
  inOrder.verify(mBuilder).buildInternal();
  inOrder.verify(mConfig).setup(mOriginal);
  inOrder.verify(mChildBuilder).deepCopy();
  inOrder.verify(mChildBuilder).buildInternal();
  inOrder.verify(mChildConfig).setup(mChildMockspresso);
  inOrder.verify(innerRule1.returnStatement).before();
  inOrder.verify(innerRule2.returnStatement).before();
  inOrder.verify(base).evaluate();
  inOrder.verify(innerRule2.returnStatement).after();
  inOrder.verify(innerRule1.returnStatement).after();
  inOrder.verify(mChildConfig).teardown();
  inOrder.verify(mConfig).teardown();
  inOrder.verify(outerRule2.returnStatement).after();
  inOrder.verify(outerRule1.returnStatement).after();
  assertRuleNoLongerWorks();
}