// Path: src/test/java/com/timgroup/stanislavski/matchers/AMethodCall.java
// public final class AMethodCall<C> extends TypeSafeDiagnosingMatcher<MethodCall> {
//     private final String methodName;
//     private final Class<C> targetClass;
//     private final Collection<AnArgument<?>> arguments = Lists.newLinkedList();
//     
//     public static interface MethodNameBinder {
//         <C> AMethodCall<C> of(Class<C> interfaceClass);
//     }
//     
//     public static AMethodCall.MethodNameBinder to(final String methodName) {
//         return new MethodNameBinder() {
//             @Override public <C> AMethodCall<C> of(Class<C> targetClass) { return new AMethodCall<C>(methodName, targetClass); }
//         };
//     }
// 
//     private AMethodCall(String methodName, Class<C> targetClass) {
//         this.methodName = methodName;
//         this.targetClass = targetClass;
//     }
//     
//     public AMethodCall<C> with(AnArgument<?> anArgument) {
//         arguments.add(anArgument);
//         return this;
//     }
//     
//     public AMethodCall<C> and(AnArgument<?> anArgument) {
//         arguments.add(anArgument);
//         return this;
//     }
//     
//     @Override
//     public void describeTo(Description description) {
//         description.appendText(" a method call to the method ").appendValue(methodName).appendText(" on class ").appendValue(targetClass);
//         if (arguments.size() > 0) {
//             description.appendText(" with arguments ").appendValueList("[", ",", "]", arguments);
//         }
//     }
// 
//     @Override
//     protected boolean matchesSafely(MethodCall item, Description mismatchDescription) {
//         if (!item.targetClass().equals(targetClass)) {
//             mismatchDescription.appendText(" the target class was ").appendValue(targetClass);
//             return false;
//         }
//         if (!item.name().equals(methodName)) {
//             mismatchDescription.appendText(" the method called was ").appendText(methodName);
//             return false;
//         }
//         if (arguments.size() != item.arguments().size()) {
//             mismatchDescription.appendText(" the number of arguments was ").appendValue(item.arguments().size());
//             return false;
//         }
//         Iterator<AnArgument<?>> matcherIterator = arguments.iterator();
//         Iterator<MethodCallArgument<?>> argumentIterator = item.arguments().iterator();
//         int argumentIndex = 0;
//         while (matcherIterator.hasNext()) {
//             AnArgument<?> matcher = matcherIterator.next();
//             MethodCallArgument<?> argument = argumentIterator.next();
//             argumentIndex += 1;
//             if (!matcher.matches(argument)) {
//                 mismatchDescription.appendText(" argument [").appendValue(argumentIndex).appendText("]");
//                 matcher.describeMismatch(argument, mismatchDescription);
//                 return false;
//             }
//         }
//         return true;
//     }
// }
// 
// Path: src/test/java/com/timgroup/stanislavski/matchers/AnArgument.java
// public final class AnArgument<C> extends TypeSafeDiagnosingMatcher<MethodCallArgument<C>> {
//     private final C value;
// 
//     public static <C> AnArgument<C> of(C value) {
//         return new AnArgument<C>(value);
//     }
//     
//     private AnArgument(C value) {
//         this.value = value;
//     }
//     
//     @Override
//     public void describeTo(Description description) {
//         description.appendText(" an argument with the value ").appendValue(value);
//     }
// 
//     @Override
//     protected boolean matchesSafely(MethodCallArgument<C> item, Description mismatchDescription) {
//         if (item.value().equals(value)) {
//             return true;
//         }
//         mismatchDescription.appendText(" had the value ").appendValue(value);
//         return false;
//     }
//     
// }
// 
// Path: src/main/java/com/timgroup/stanislavski/reflection/MethodCall.java
// public class MethodCall {
//     private final Method method;
//     private final Object[] rawArgs;
//     private final List<MethodCallArgument<?>> arguments;
//     
//     public static MethodCall create(Method method, Object...args) {
//         return new MethodCall(method, args);
//     }
// 
//     private MethodCall(Method method, Object[] rawArgs) {
//         this.method = method;
//         this.rawArgs = rawArgs;
//         this.arguments = MethodCallArgument.wrapArguments(method, rawArgs);
//     }
// 
//     public Class<?> targetClass() {
//         return method.getDeclaringClass();
//     }
//     
//     public Class<?> returnType() {
//         return method.getReturnType();
//     }
// 
//     public String name() {
//         return method.getName();
//     }
// 
//     public List<MethodCallArgument<?>> arguments() {
//         return arguments;
//     }
// 
//     public boolean hasAnnotation(Class<? extends Annotation> annotationClass) {
//         return method.isAnnotationPresent(annotationClass);
//     }
//     
//     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
//         return method.getAnnotation(annotationClass);
//     }
// 
//     public MethodCallArgument<?> firstArgument() {
//         return arguments.get(0);
//     }
//     
//     public Object applyTo(Object target) throws Throwable {
//         try {
//             return this.method.invoke(target, rawArgs);
//         } catch (InvocationTargetException e) {
//             throw e.getCause();
//         }
//     }
//     
//     @Override public String toString() {
//         return String.format("%s: %s", method, arguments);
//     }
// 
//     public List<Object> argumentValues() {
//         return Lists.transform(arguments, MethodCallArgument.TO_VALUE);
//     }
// }


import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.Test;
import com.google.common.base.Predicate;
import com.timgroup.stanislavski.matchers.AMethodCall;
import com.timgroup.stanislavski.matchers.AnArgument;
import com.timgroup.stanislavski.reflection.MethodCall;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
package com.timgroup.stanislavski.recording;




public class InterceptingMethodCallRecorderTest {

    private final Mockery context = new Mockery();
    
    @SuppressWarnings("unchecked")
// Path: src/test/java/com/timgroup/stanislavski/matchers/AMethodCall.java
// public final class AMethodCall<C> extends TypeSafeDiagnosingMatcher<MethodCall> {
//     private final String methodName;
//     private final Class<C> targetClass;
//     private final Collection<AnArgument<?>> arguments = Lists.newLinkedList();
//     
//     public static interface MethodNameBinder {
//         <C> AMethodCall<C> of(Class<C> interfaceClass);
//     }
//     
//     public static AMethodCall.MethodNameBinder to(final String methodName) {
//         return new MethodNameBinder() {
//             @Override public <C> AMethodCall<C> of(Class<C> targetClass) { return new AMethodCall<C>(methodName, targetClass); }
//         };
//     }
// 
//     private AMethodCall(String methodName, Class<C> targetClass) {
//         this.methodName = methodName;
//         this.targetClass = targetClass;
//     }
//     
//     public AMethodCall<C> with(AnArgument<?> anArgument) {
//         arguments.add(anArgument);
//         return this;
//     }
//     
//     public AMethodCall<C> and(AnArgument<?> anArgument) {
//         arguments.add(anArgument);
//         return this;
//     }
//     
//     @Override
//     public void describeTo(Description description) {
//         description.appendText(" a method call to the method ").appendValue(methodName).appendText(" on class ").appendValue(targetClass);
//         if (arguments.size() > 0) {
//             description.appendText(" with arguments ").appendValueList("[", ",", "]", arguments);
//         }
//     }
// 
//     @Override
//     protected boolean matchesSafely(MethodCall item, Description mismatchDescription) {
//         if (!item.targetClass().equals(targetClass)) {
//             mismatchDescription.appendText(" the target class was ").appendValue(targetClass);
//             return false;
//         }
//         if (!item.name().equals(methodName)) {
//             mismatchDescription.appendText(" the method called was ").appendText(methodName);
//             return false;
//         }
//         if (arguments.size() != item.arguments().size()) {
//             mismatchDescription.appendText(" the number of arguments was ").appendValue(item.arguments().size());
//             return false;
//         }
//         Iterator<AnArgument<?>> matcherIterator = arguments.iterator();
//         Iterator<MethodCallArgument<?>> argumentIterator = item.arguments().iterator();
//         int argumentIndex = 0;
//         while (matcherIterator.hasNext()) {
//             AnArgument<?> matcher = matcherIterator.next();
//             MethodCallArgument<?> argument = argumentIterator.next();
//             argumentIndex += 1;
//             if (!matcher.matches(argument)) {
//                 mismatchDescription.appendText(" argument [").appendValue(argumentIndex).appendText("]");
//                 matcher.describeMismatch(argument, mismatchDescription);
//                 return false;
//             }
//         }
//         return true;
//     }
// }
// 
// Path: src/test/java/com/timgroup/stanislavski/matchers/AnArgument.java
// public final class AnArgument<C> extends TypeSafeDiagnosingMatcher<MethodCallArgument<C>> {
//     private final C value;
// 
//     public static <C> AnArgument<C> of(C value) {
//         return new AnArgument<C>(value);
//     }
//     
//     private AnArgument(C value) {
//         this.value = value;
//     }
//     
//     @Override
//     public void describeTo(Description description) {
//         description.appendText(" an argument with the value ").appendValue(value);
//     }
// 
//     @Override
//     protected boolean matchesSafely(MethodCallArgument<C> item, Description mismatchDescription) {
//         if (item.value().equals(value)) {
//             return true;
//         }
//         mismatchDescription.appendText(" had the value ").appendValue(value);
//         return false;
//     }
//     
// }
// 
// Path: src/main/java/com/timgroup/stanislavski/reflection/MethodCall.java
// public class MethodCall {
//     private final Method method;
//     private final Object[] rawArgs;
//     private final List<MethodCallArgument<?>> arguments;
//     
//     public static MethodCall create(Method method, Object...args) {
//         return new MethodCall(method, args);
//     }
// 
//     private MethodCall(Method method, Object[] rawArgs) {
//         this.method = method;
//         this.rawArgs = rawArgs;
//         this.arguments = MethodCallArgument.wrapArguments(method, rawArgs);
//     }
// 
//     public Class<?> targetClass() {
//         return method.getDeclaringClass();
//     }
//     
//     public Class<?> returnType() {
//         return method.getReturnType();
//     }
// 
//     public String name() {
//         return method.getName();
//     }
// 
//     public List<MethodCallArgument<?>> arguments() {
//         return arguments;
//     }
// 
//     public boolean hasAnnotation(Class<? extends Annotation> annotationClass) {
//         return method.isAnnotationPresent(annotationClass);
//     }
//     
//     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
//         return method.getAnnotation(annotationClass);
//     }
// 
//     public MethodCallArgument<?> firstArgument() {
//         return arguments.get(0);
//     }
//     
//     public Object applyTo(Object target) throws Throwable {
//         try {
//             return this.method.invoke(target, rawArgs);
//         } catch (InvocationTargetException e) {
//             throw e.getCause();
//         }
//     }
//     
//     @Override public String toString() {
//         return String.format("%s: %s", method, arguments);
//     }
// 
//     public List<Object> argumentValues() {
//         return Lists.transform(arguments, MethodCallArgument.TO_VALUE);
//     }
// }


// Path: src/test/java/com/timgroup/stanislavski/recording/InterceptingMethodCallRecorderTest.java
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.Test;
import com.google.common.base.Predicate;
import com.timgroup.stanislavski.matchers.AMethodCall;
import com.timgroup.stanislavski.matchers.AnArgument;
import com.timgroup.stanislavski.reflection.MethodCall;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

package com.timgroup.stanislavski.recording;




public class InterceptingMethodCallRecorderTest {

    private final Mockery context = new Mockery();
    
    @SuppressWarnings("unchecked")
    private final Predicate<MethodCall> finalCallMatcher = context.mock(Predicate.class);