// Path: src/main/java/com/github/hgwood/fanfaron/utils/vendorextensions/VendorExtensions.java
// public class VendorExtensions extends DynamicObject<Object> {
// 
//     @Override public Object put(String key, Object value) {
//         if (isVendorExtension(key)) return super.put(key, value);
//         else throw new IllegalArgumentException(format("Unrecognized field '%s' (%s)", key, getClass()));
//     }
// 
//     public static boolean isVendorExtension(String key) {
//         return key.startsWith("x-");
//     }
// 
// }


import com.github.hgwood.fanfaron.utils.vendorextensions.VendorExtensions;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertNotEquals;
            typeOfValues = ((ParameterizedType)typeOfValues).getActualTypeArguments()[0];
        }
        return (Class<?>)typeOfValues;
    }

    private <T> Collection<Class<?>> nestedTypes(Class<T> type) throws Exception {
        if (Map.class.isAssignableFrom(type)) {
            return Collections.<Class<?>>singletonList(typeOfValues(type));
        }
        Collection<Class<?>> nestedTypes = new ArrayList<>();
        for (Field field : type.getFields()) {
            assertIsInEqual(type, field);
            if (List.class.isAssignableFrom(field.getType())) {
                nestedTypes.add((Class<?>)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0]);
            } else {
                nestedTypes.add(field.getType());
            }
        }
        return nestedTypes;
    }

    private <T> void assertIsInEqual(Class<T> _class, Field field) throws Exception {
        T reference = _class.newInstance();
        T mutated = _class.newInstance();
        if (field.getType() == List.class) field.set(mutated, emptyList());
        else if (field.getType() == boolean.class) field.set(mutated, true);
        else if (field.getType() == Boolean.class) field.set(mutated, true);
        else if (field.getType() == BigInteger.class) field.set(mutated, BigInteger.ONE);
        else if (field.getType() == BigDecimal.class) field.set(mutated, BigDecimal.ONE);
        else if (field.getName().equals("vendorExtensions")) {
// Path: src/main/java/com/github/hgwood/fanfaron/utils/vendorextensions/VendorExtensions.java
// public class VendorExtensions extends DynamicObject<Object> {
// 
//     @Override public Object put(String key, Object value) {
//         if (isVendorExtension(key)) return super.put(key, value);
//         else throw new IllegalArgumentException(format("Unrecognized field '%s' (%s)", key, getClass()));
//     }
// 
//     public static boolean isVendorExtension(String key) {
//         return key.startsWith("x-");
//     }
// 
// }


// Path: src/test/java/com/github/hgwood/fanfaron/StructuralEqualityTest.java
import com.github.hgwood.fanfaron.utils.vendorextensions.VendorExtensions;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static org.junit.Assert.assertNotEquals;

            typeOfValues = ((ParameterizedType)typeOfValues).getActualTypeArguments()[0];
        }
        return (Class<?>)typeOfValues;
    }

    private <T> Collection<Class<?>> nestedTypes(Class<T> type) throws Exception {
        if (Map.class.isAssignableFrom(type)) {
            return Collections.<Class<?>>singletonList(typeOfValues(type));
        }
        Collection<Class<?>> nestedTypes = new ArrayList<>();
        for (Field field : type.getFields()) {
            assertIsInEqual(type, field);
            if (List.class.isAssignableFrom(field.getType())) {
                nestedTypes.add((Class<?>)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0]);
            } else {
                nestedTypes.add(field.getType());
            }
        }
        return nestedTypes;
    }

    private <T> void assertIsInEqual(Class<T> _class, Field field) throws Exception {
        T reference = _class.newInstance();
        T mutated = _class.newInstance();
        if (field.getType() == List.class) field.set(mutated, emptyList());
        else if (field.getType() == boolean.class) field.set(mutated, true);
        else if (field.getType() == Boolean.class) field.set(mutated, true);
        else if (field.getType() == BigInteger.class) field.set(mutated, BigInteger.ONE);
        else if (field.getType() == BigDecimal.class) field.set(mutated, BigDecimal.ONE);
        else if (field.getName().equals("vendorExtensions")) {
            VendorExtensions mutatedVendorExtensions = new VendorExtensions();