// Path: expectations/src/main/java/jinsist/expectations/Expectations.java
// public interface Expectations {
//     <ReturnType, MockType> void recordStub(
//             Class<MockType> classToMock,
//             MockType instance,
//             Method method,
//             Arguments arguments,
//             ReturnType result
//     );
// 
//     <MockType> Object execute(
//             Class<MockType> classToMock,
//             MockType instance,
//             Method method,
//             Object[] arguments
//     );
// 
//     void verify();
// }
// 
// Path: matchers/src/main/java/jinsist/matchers/Arguments.java
// public class Arguments {
//     private List<ArgumentMatcher<?>> argumentMatchers;
// 
//     public Arguments(List<ArgumentMatcher<?>> argumentMatchers) {
//         this.argumentMatchers = argumentMatchers;
//     }
// 
//     public boolean matches(Object... arguments) {
//         int length = argumentMatchers.size();
//         if (length != arguments.length)
//             return false;
//         else
//             for (int i = 0; i < length; i++) {
//                 ArgumentMatcher matcher = argumentMatchers.get(i);
//                 @SuppressWarnings("unchecked")
//                 boolean matches = matcher.matches(arguments[i]);
//                 if (!matches) return false;
//             }
//         return true;
//     }
// 
//     public List<ArgumentMatcher<?>> getArgumentMatchers() {
//         return argumentMatchers;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Arguments arguments = (Arguments) o;
// 
//         return argumentMatchers.equals(arguments.argumentMatchers);
//     }
// 
//     @Override
//     public int hashCode() {
//         return argumentMatchers != null ? argumentMatchers.hashCode() : 0;
//     }
// }
// 
// Path: matchers/src/main/java/jinsist/matchers/EqualsMatcher.java
// public class EqualsMatcher<T> implements ArgumentMatcher<T> {
//     private T value;
// 
//     public EqualsMatcher(T value) {
//         this.value = value;
//     }
// 
//     @Override
//     public boolean matches(T argument) {
//         boolean isValueNull = value == null;
//         boolean isArgumentNull = argument == null;
// 
//         return isArgumentNull && isValueNull || !isValueNull && value.equals(argument);
//     }
// 
//     @Override
//     public String toString() {
//         return "EqualsMatcher " + value;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         EqualsMatcher<?> that = (EqualsMatcher<?>) o;
// 
//         return value != null ? value.equals(that.value) : that.value == null;
//     }
// 
//     @Override
//     public int hashCode() {
//         return value != null ? value.hashCode() : 0;
//     }
// }
// 
// Path: mock/src/main/java/jinsist/mock/SetupResult.java
// public class SetupResult {
//     private boolean wasRecorded = false;
// 
//     public void setSuccess() {
//         this.wasRecorded = true;
//     }
// 
//     void verify() {
//         if (!wasRecorded) throw new MethodToStubNotFound();
//     }
// }
// 
// Path: proxy/src/main/java/jinsist/proxy/Delegator.java
// public interface Delegator<T> {
//     Object handle(T instance, Method method, Object[] arguments);
// }


import jinsist.expectations.Expectations;
import jinsist.matchers.Arguments;
import jinsist.matchers.EqualsMatcher;
import jinsist.mock.SetupResult;
import jinsist.proxy.Delegator;
import java.lang.reflect.Method;
import java.util.stream.Collectors;
import static java.util.Arrays.stream;
package jinsist.mock.delegators;




public class SetupRecorder<ReturnType, MockType> implements Delegator<MockType> {

    private MockType instance;
    private ReturnType result;
    private SetupResult setupResult;
    private Expectations expectations;
    private Class<MockType> mockType;

    public SetupRecorder(
            Expectations expectations,
            Class<MockType> mockType,
// Path: expectations/src/main/java/jinsist/expectations/Expectations.java
// public interface Expectations {
//     <ReturnType, MockType> void recordStub(
//             Class<MockType> classToMock,
//             MockType instance,
//             Method method,
//             Arguments arguments,
//             ReturnType result
//     );
// 
//     <MockType> Object execute(
//             Class<MockType> classToMock,
//             MockType instance,
//             Method method,
//             Object[] arguments
//     );
// 
//     void verify();
// }
// 
// Path: matchers/src/main/java/jinsist/matchers/Arguments.java
// public class Arguments {
//     private List<ArgumentMatcher<?>> argumentMatchers;
// 
//     public Arguments(List<ArgumentMatcher<?>> argumentMatchers) {
//         this.argumentMatchers = argumentMatchers;
//     }
// 
//     public boolean matches(Object... arguments) {
//         int length = argumentMatchers.size();
//         if (length != arguments.length)
//             return false;
//         else
//             for (int i = 0; i < length; i++) {
//                 ArgumentMatcher matcher = argumentMatchers.get(i);
//                 @SuppressWarnings("unchecked")
//                 boolean matches = matcher.matches(arguments[i]);
//                 if (!matches) return false;
//             }
//         return true;
//     }
// 
//     public List<ArgumentMatcher<?>> getArgumentMatchers() {
//         return argumentMatchers;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Arguments arguments = (Arguments) o;
// 
//         return argumentMatchers.equals(arguments.argumentMatchers);
//     }
// 
//     @Override
//     public int hashCode() {
//         return argumentMatchers != null ? argumentMatchers.hashCode() : 0;
//     }
// }
// 
// Path: matchers/src/main/java/jinsist/matchers/EqualsMatcher.java
// public class EqualsMatcher<T> implements ArgumentMatcher<T> {
//     private T value;
// 
//     public EqualsMatcher(T value) {
//         this.value = value;
//     }
// 
//     @Override
//     public boolean matches(T argument) {
//         boolean isValueNull = value == null;
//         boolean isArgumentNull = argument == null;
// 
//         return isArgumentNull && isValueNull || !isValueNull && value.equals(argument);
//     }
// 
//     @Override
//     public String toString() {
//         return "EqualsMatcher " + value;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         EqualsMatcher<?> that = (EqualsMatcher<?>) o;
// 
//         return value != null ? value.equals(that.value) : that.value == null;
//     }
// 
//     @Override
//     public int hashCode() {
//         return value != null ? value.hashCode() : 0;
//     }
// }
// 
// Path: mock/src/main/java/jinsist/mock/SetupResult.java
// public class SetupResult {
//     private boolean wasRecorded = false;
// 
//     public void setSuccess() {
//         this.wasRecorded = true;
//     }
// 
//     void verify() {
//         if (!wasRecorded) throw new MethodToStubNotFound();
//     }
// }
// 
// Path: proxy/src/main/java/jinsist/proxy/Delegator.java
// public interface Delegator<T> {
//     Object handle(T instance, Method method, Object[] arguments);
// }


// Path: mock/src/main/java/jinsist/mock/delegators/SetupRecorder.java
import jinsist.expectations.Expectations;
import jinsist.matchers.Arguments;
import jinsist.matchers.EqualsMatcher;
import jinsist.mock.SetupResult;
import jinsist.proxy.Delegator;
import java.lang.reflect.Method;
import java.util.stream.Collectors;
import static java.util.Arrays.stream;

package jinsist.mock.delegators;




public class SetupRecorder<ReturnType, MockType> implements Delegator<MockType> {

    private MockType instance;
    private ReturnType result;
    private SetupResult setupResult;
    private Expectations expectations;
    private Class<MockType> mockType;

    public SetupRecorder(
            Expectations expectations,
            Class<MockType> mockType,
            MockType instance,