// 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/main/java/com/statemachinesystems/envy/parsers/IntegerValueParser.java
// public class IntegerValueParser implements ValueParser<Integer> {
// 
//     @Override
//     public Integer parseValue(String value) {
//         return Integer.parseInt(value);
//     }
// 
//     @Override
//     public Class<Integer> getValueClass() {
//         return Integer.class;
//     }
// 
// }
// 
// Path: src/main/java/com/statemachinesystems/envy/parsers/ObjectAsStringValueParser.java
// public class ObjectAsStringValueParser implements ValueParser<Object> {
// 
//     private final StringValueParser valueParser = new StringValueParser();
// 
//     @Override
//     public Object parseValue(String value) {
//         return valueParser.parseValue(value);
//     }
// 
//     @Override
//     public Class<Object> getValueClass() {
//         return Object.class;
//     }
// }
// 
// Path: src/main/java/com/statemachinesystems/envy/parsers/StringValueParser.java
// public class StringValueParser implements ValueParser<String> {
// 
//     @Override
//     public String parseValue(String value) {
//         return value;
//     }
// 
//     @Override
//     public Class<String> getValueClass() {
//         return String.class;
//     }
// }
// 
// Path: src/main/java/com/statemachinesystems/envy/values/ConfigValue.java
// public interface ConfigValue<T> extends Serializable {
// 
//     static <T> ConfigValue<T> of(T value, ConfigValue.Status status, Method method) {
//         return method.getAnnotation(Sensitive.class) != null
//             ? new SensitiveValue<>(value, status)
//             : new ResolvedValue<>(value, status);
//     }
// 
//     enum Status {
//         CONFIGURED,
//         MISSING,
//         DEFAULTED
//     }
// 
//     /**
//      * Returns the fully extracted and parsed value, or a default.
//      *
//      * @param proxy  the proxy this value belongs to
//      */
//     T getValue(Object proxy);
// 
//     /**
//      * Returns the value formatted as a String.
//      *
//      * @param proxy  the proxy this value belongs to
//      * @return  the value formatted as a String
//      */
//     String format(Object proxy);
// 
//     /**
//      * Indicates whether the value was found in the underlying {@link ConfigSource},
//      * missing, or replaced by a default value.
//      */
//     Status getStatus();
// }
// 
// Path: src/main/java/com/statemachinesystems/envy/values/ConfigValue.java
// enum Status {
//     CONFIGURED,
//     MISSING,
//     DEFAULTED
// }


import com.statemachinesystems.envy.common.StubConfigSource;
import com.statemachinesystems.envy.parsers.IntegerValueParser;
import com.statemachinesystems.envy.parsers.ObjectAsStringValueParser;
import com.statemachinesystems.envy.parsers.StringValueParser;
import com.statemachinesystems.envy.values.ConfigValue;
import com.statemachinesystems.envy.values.ConfigValue.Status;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
    public interface BadConfigWithOverriddenObjectMethod {
        @Override
        String toString();
    }

    @SuppressWarnings("unused")
    public interface BadConfigWithVoidReturnType {
        void methodWithVoidReturnType();
    }

    private StubConfigSource configSource;
    private ValueParserFactory valueParserFactory;
    private ConfigExtractor configExtractor;

    @Before
    public void setUp() {
        configSource = new StubConfigSource()
                .add("A_STRING", "foo")
                .add("A_BOXED_INTEGER", "10")
                .add("A_PRIMITIVE_INTEGER", "15")
                .add("AN_ARRAY_OF_BOXED_INTEGERS", "7")
                .add("AN_ARRAY_OF_PRIMITIVE_INTEGERS", "1,2,3")
                .add("CUSTOM_PARAMETER_NAME", "bar")
                .add("NULLABLE", "5")
                .add("OPTIONAL_NON_NULL", "6")
                .add("METHOD_WITH_OBJECT_RETURN_TYPE", "bar")
                .add("INT_IN_SUB_INTERFACE", "37")
                .add("INT_IN_SUB_SUB_INTERFACE", "98")
                .add("ANOTHER_STRING", "baz");

// 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/main/java/com/statemachinesystems/envy/parsers/IntegerValueParser.java
// public class IntegerValueParser implements ValueParser<Integer> {
// 
//     @Override
//     public Integer parseValue(String value) {
//         return Integer.parseInt(value);
//     }
// 
//     @Override
//     public Class<Integer> getValueClass() {
//         return Integer.class;
//     }
// 
// }
// 
// Path: src/main/java/com/statemachinesystems/envy/parsers/ObjectAsStringValueParser.java
// public class ObjectAsStringValueParser implements ValueParser<Object> {
// 
//     private final StringValueParser valueParser = new StringValueParser();
// 
//     @Override
//     public Object parseValue(String value) {
//         return valueParser.parseValue(value);
//     }
// 
//     @Override
//     public Class<Object> getValueClass() {
//         return Object.class;
//     }
// }
// 
// Path: src/main/java/com/statemachinesystems/envy/parsers/StringValueParser.java
// public class StringValueParser implements ValueParser<String> {
// 
//     @Override
//     public String parseValue(String value) {
//         return value;
//     }
// 
//     @Override
//     public Class<String> getValueClass() {
//         return String.class;
//     }
// }
// 
// Path: src/main/java/com/statemachinesystems/envy/values/ConfigValue.java
// public interface ConfigValue<T> extends Serializable {
// 
//     static <T> ConfigValue<T> of(T value, ConfigValue.Status status, Method method) {
//         return method.getAnnotation(Sensitive.class) != null
//             ? new SensitiveValue<>(value, status)
//             : new ResolvedValue<>(value, status);
//     }
// 
//     enum Status {
//         CONFIGURED,
//         MISSING,
//         DEFAULTED
//     }
// 
//     /**
//      * Returns the fully extracted and parsed value, or a default.
//      *
//      * @param proxy  the proxy this value belongs to
//      */
//     T getValue(Object proxy);
// 
//     /**
//      * Returns the value formatted as a String.
//      *
//      * @param proxy  the proxy this value belongs to
//      * @return  the value formatted as a String
//      */
//     String format(Object proxy);
// 
//     /**
//      * Indicates whether the value was found in the underlying {@link ConfigSource},
//      * missing, or replaced by a default value.
//      */
//     Status getStatus();
// }
// 
// Path: src/main/java/com/statemachinesystems/envy/values/ConfigValue.java
// enum Status {
//     CONFIGURED,
//     MISSING,
//     DEFAULTED
// }


// Path: src/test/java/com/statemachinesystems/envy/ConfigExtractorTest.java
import com.statemachinesystems.envy.common.StubConfigSource;
import com.statemachinesystems.envy.parsers.IntegerValueParser;
import com.statemachinesystems.envy.parsers.ObjectAsStringValueParser;
import com.statemachinesystems.envy.parsers.StringValueParser;
import com.statemachinesystems.envy.values.ConfigValue;
import com.statemachinesystems.envy.values.ConfigValue.Status;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

    public interface BadConfigWithOverriddenObjectMethod {
        @Override
        String toString();
    }

    @SuppressWarnings("unused")
    public interface BadConfigWithVoidReturnType {
        void methodWithVoidReturnType();
    }

    private StubConfigSource configSource;
    private ValueParserFactory valueParserFactory;
    private ConfigExtractor configExtractor;

    @Before
    public void setUp() {
        configSource = new StubConfigSource()
                .add("A_STRING", "foo")
                .add("A_BOXED_INTEGER", "10")
                .add("A_PRIMITIVE_INTEGER", "15")
                .add("AN_ARRAY_OF_BOXED_INTEGERS", "7")
                .add("AN_ARRAY_OF_PRIMITIVE_INTEGERS", "1,2,3")
                .add("CUSTOM_PARAMETER_NAME", "bar")
                .add("NULLABLE", "5")
                .add("OPTIONAL_NON_NULL", "6")
                .add("METHOD_WITH_OBJECT_RETURN_TYPE", "bar")
                .add("INT_IN_SUB_INTERFACE", "37")
                .add("INT_IN_SUB_SUB_INTERFACE", "98")
                .add("ANOTHER_STRING", "baz");

        valueParserFactory = new ValueParserFactory(new StringValueParser(), new IntegerValueParser(),