private void testLegalStrictBinding(boolean dynamicallyTyped, Annotation... targetAnnotation)
     throws Exception {
   when(annotation.value()).thenReturn(AllArguments.Assignment.STRICT);
   when(stackManipulation.isValid()).thenReturn(true);
   when(source.getParameters())
       .thenReturn(new ParameterList.Explicit.ForTypes(source, firstSourceType, secondSourceType));
   when(source.isStatic()).thenReturn(false);
   when(targetType.isArray()).thenReturn(true);
   when(targetType.getComponentType()).thenReturn(componentType);
   when(componentType.getStackSize()).thenReturn(StackSize.SINGLE);
   when(target.getType()).thenReturn(targetType);
   when(target.getDeclaredAnnotations())
       .thenReturn(new AnnotationList.ForLoadedAnnotations(targetAnnotation));
   MethodDelegationBinder.ParameterBinding<?> parameterBinding =
       AllArguments.Binder.INSTANCE.bind(
           annotationDescription, source, target, implementationTarget, assigner);
   assertThat(parameterBinding.isValid(), is(true));
   verify(source, atLeast(1)).getParameters();
   verify(source, atLeast(1)).isStatic();
   verify(target, atLeast(1)).getType();
   verify(target, atLeast(1)).getDeclaredAnnotations();
   verify(assigner).assign(firstSourceType, componentType, Assigner.Typing.of(dynamicallyTyped));
   verify(assigner).assign(secondSourceType, componentType, Assigner.Typing.of(dynamicallyTyped));
   verifyNoMoreInteractions(assigner);
 }
 @Test
 public void testLegalSlackBinding() throws Exception {
   when(target.getIndex()).thenReturn(1);
   when(annotation.value()).thenReturn(AllArguments.Assignment.SLACK);
   when(stackManipulation.isValid()).thenReturn(false);
   when(source.getParameters())
       .thenReturn(new ParameterList.Explicit.ForTypes(source, firstSourceType, secondSourceType));
   when(source.isStatic()).thenReturn(false);
   when(targetType.isArray()).thenReturn(true);
   when(targetType.getComponentType()).thenReturn(componentType);
   when(componentType.getStackSize()).thenReturn(StackSize.SINGLE);
   when(target.getType()).thenReturn(targetType);
   when(target.getDeclaredAnnotations()).thenReturn(new AnnotationList.Empty());
   when(rawComponentType.getInternalName()).thenReturn(FOO);
   MethodDelegationBinder.ParameterBinding<?> parameterBinding =
       AllArguments.Binder.INSTANCE.bind(
           annotationDescription, source, target, implementationTarget, assigner);
   MethodVisitor methodVisitor = mock(MethodVisitor.class);
   Implementation.Context implementationContext = mock(Implementation.Context.class);
   StackManipulation.Size size = parameterBinding.apply(methodVisitor, implementationContext);
   assertThat(size.getSizeImpact(), is(1));
   assertThat(size.getMaximalSize(), is(1));
   verify(methodVisitor).visitInsn(Opcodes.ICONST_0);
   verify(methodVisitor).visitTypeInsn(Opcodes.ANEWARRAY, FOO);
   verifyNoMoreInteractions(methodVisitor);
   verifyZeroInteractions(implementationContext);
   assertThat(parameterBinding.isValid(), is(true));
   verify(source, atLeast(1)).getParameters();
   verify(source, atLeast(1)).isStatic();
   verify(target, atLeast(1)).getType();
   verify(target, atLeast(1)).getDeclaredAnnotations();
   verify(assigner).assign(firstSourceType, componentType, Assigner.Typing.STATIC);
   verify(assigner).assign(secondSourceType, componentType, Assigner.Typing.STATIC);
   verifyNoMoreInteractions(assigner);
 }
 @Test
 public void testIllegalBindingForNonAssignableType() throws Exception {
   doReturn(void.class).when(annotation).proxyType();
   MethodDelegationBinder.ParameterBinding<?> parameterBinding =
       Super.Binder.INSTANCE.bind(
           annotationDescription, source, target, implementationTarget, assigner);
   assertThat(parameterBinding.isValid(), is(false));
 }
 @Test
 public void testAssignableBinding() throws Exception {
   doReturn(void.class).when(annotation).proxyType();
   when(stackManipulation.isValid()).thenReturn(true);
   when(instrumentedType.isAssignableTo(targetType)).thenReturn(true);
   MethodDelegationBinder.ParameterBinding<?> parameterBinding =
       Super.Binder.INSTANCE.bind(
           annotationDescription, source, target, implementationTarget, assigner);
   assertThat(parameterBinding.isValid(), is(true));
   verify(instantiation).proxyFor(targetType, implementationTarget, annotationDescription);
 }