// Path: src/main/java/com/statemachinesystems/envy/ConfigSource.java
// public interface ConfigSource {
// 
//     /**
//      * Retrieves the configuration value associated with the given parameter.
//      *
//      * @param parameter  the parameter to retrieve.
//      * @return           the value associated with the parameter, or null if no value was present
//      */
//     String getValue(Parameter parameter);
// }
// 
// Path: src/test/java/com/statemachinesystems/envy/common/FeatureTest.java
// public abstract class FeatureTest {
// 
//     protected Envy envy() {
//         return envy(valueParserFactory(), configSource());
//     }
// 
//     protected Envy envy(ValueParserFactory valueParserFactory) {
//         return envy(valueParserFactory, configSource());
//     }
// 
//     protected Envy envy(ConfigSource configSource) {
//         return envy(valueParserFactory(), configSource);
//     }
// 
//     protected Envy envy(ValueParserFactory valueParserFactory, ConfigSource configSource) {
//         return new Envy(valueParserFactory, configSource);
//     }
// 
//     protected ValueParserFactory valueParserFactory() {
//         List<ValueParser<?>> valueParsers = new ArrayList<ValueParser<?>>(Envy.defaultValueParsers());
//         return new ValueParserFactory(valueParsers);
//     }
// 
//     protected StubConfigSource configSource() {
//         return new StubConfigSource();
//     }
// }
// 
// Path: src/test/java/com/statemachinesystems/envy/common/StubConfigSource.java
// public class StubConfigSource implements ConfigSource {
// 
//     private final Map<Parameter, String> params;
// 
//     public StubConfigSource() {
//         this.params = new HashMap<Parameter, String>();
//     }
// 
//     public StubConfigSource add(String parameter, String value) {
//         params.put(new Parameter(parameter), value);
//         return this;
//     }
// 
//     @Override
//     public String getValue(Parameter parameter) {
//         return params.get(parameter);
//     }
// }


import com.statemachinesystems.envy.ConfigSource;
import com.statemachinesystems.envy.common.FeatureTest;
import com.statemachinesystems.envy.common.StubConfigSource;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
package com.statemachinesystems.envy.features;




public class EqualsAndHashCodeTest extends FeatureTest {

    @SuppressWarnings("unused")
    public interface Config {
        int foo();
        String bar();
    }

    @SuppressWarnings("unused")
    public interface AnotherConfig {
        int foo();
        String bar();
    }

    @Override
    public StubConfigSource configSource() {
        return super.configSource().add("foo", "1").add("bar", "bar");
    }

    @Test
    public void equalsMethodOnProxyReturnsTrueForSameInstance() {
        Config config = envy().proxy(Config.class);
        assertEquals(config, config);
    }

    @Test
    public void equalsMethodOnProxyReturnsTrueForEqualInstances() {
        Config config1 = envy().proxy(Config.class);
        Config config2 = envy().proxy(Config.class);

        assertEquals(config1, config2);
        assertEquals(config2, config1);
    }

    @Test
    public void equalsMethodOnProxyReturnsFalseForUnequalInstances() {
// Path: src/main/java/com/statemachinesystems/envy/ConfigSource.java
// public interface ConfigSource {
// 
//     /**
//      * Retrieves the configuration value associated with the given parameter.
//      *
//      * @param parameter  the parameter to retrieve.
//      * @return           the value associated with the parameter, or null if no value was present
//      */
//     String getValue(Parameter parameter);
// }
// 
// Path: src/test/java/com/statemachinesystems/envy/common/FeatureTest.java
// public abstract class FeatureTest {
// 
//     protected Envy envy() {
//         return envy(valueParserFactory(), configSource());
//     }
// 
//     protected Envy envy(ValueParserFactory valueParserFactory) {
//         return envy(valueParserFactory, configSource());
//     }
// 
//     protected Envy envy(ConfigSource configSource) {
//         return envy(valueParserFactory(), configSource);
//     }
// 
//     protected Envy envy(ValueParserFactory valueParserFactory, ConfigSource configSource) {
//         return new Envy(valueParserFactory, configSource);
//     }
// 
//     protected ValueParserFactory valueParserFactory() {
//         List<ValueParser<?>> valueParsers = new ArrayList<ValueParser<?>>(Envy.defaultValueParsers());
//         return new ValueParserFactory(valueParsers);
//     }
// 
//     protected StubConfigSource configSource() {
//         return new StubConfigSource();
//     }
// }
// 
// Path: src/test/java/com/statemachinesystems/envy/common/StubConfigSource.java
// public class StubConfigSource implements ConfigSource {
// 
//     private final Map<Parameter, String> params;
// 
//     public StubConfigSource() {
//         this.params = new HashMap<Parameter, String>();
//     }
// 
//     public StubConfigSource add(String parameter, String value) {
//         params.put(new Parameter(parameter), value);
//         return this;
//     }
// 
//     @Override
//     public String getValue(Parameter parameter) {
//         return params.get(parameter);
//     }
// }


// Path: src/test/java/com/statemachinesystems/envy/features/EqualsAndHashCodeTest.java
import com.statemachinesystems.envy.ConfigSource;
import com.statemachinesystems.envy.common.FeatureTest;
import com.statemachinesystems.envy.common.StubConfigSource;
import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;

package com.statemachinesystems.envy.features;




public class EqualsAndHashCodeTest extends FeatureTest {

    @SuppressWarnings("unused")
    public interface Config {
        int foo();
        String bar();
    }

    @SuppressWarnings("unused")
    public interface AnotherConfig {
        int foo();
        String bar();
    }

    @Override
    public StubConfigSource configSource() {
        return super.configSource().add("foo", "1").add("bar", "bar");
    }

    @Test
    public void equalsMethodOnProxyReturnsTrueForSameInstance() {
        Config config = envy().proxy(Config.class);
        assertEquals(config, config);
    }

    @Test
    public void equalsMethodOnProxyReturnsTrueForEqualInstances() {
        Config config1 = envy().proxy(Config.class);
        Config config2 = envy().proxy(Config.class);

        assertEquals(config1, config2);
        assertEquals(config2, config1);
    }

    @Test
    public void equalsMethodOnProxyReturnsFalseForUnequalInstances() {
        ConfigSource configSource1 = configSource();