// Path: src/main/java/com/michaelfotiadis/validator/annotated/SupportedAnnotationContainer.java
// public final class SupportedAnnotationContainer {
// 
//     private static final String PACKAGE_NAME = "com.michaelfotiadis.validator.annotated.annotations";
//     private static final List<Class> SUPPORTED_CLASSES = new ArrayList<>();
// 
//     private SupportedAnnotationContainer() {
//         // NOOP
//     }
// 
//     /*package*/
//     static boolean isSupported(final Class<?> type) {
//         return getSupportedClasses().contains(type);
//     }
// 
//     public static List<Class> getSupportedClasses() {
//         if (SUPPORTED_CLASSES.isEmpty()) {
//             final Class[] supportedArray;
//             try {
//                 supportedArray = ReflectionUtils.getClasses(PACKAGE_NAME);
//                 SUPPORTED_CLASSES.addAll(Arrays.asList(supportedArray));
//             } catch (ClassNotFoundException | IOException e) {
//                 e.printStackTrace();
//             }
//         }
//         return SUPPORTED_CLASSES;
//     }
// 
// 
// }
// 
// Path: src/main/java/com/michaelfotiadis/validator/annotated/processor/SearchPolicy.java
// public enum SearchPolicy {
//     SHALLOW,
//     DEEP
// }


import com.michaelfotiadis.validator.annotated.SupportedAnnotationContainer;
import com.michaelfotiadis.validator.annotated.processor.SearchPolicy;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
        final List<Field> declaredFields = Arrays.asList(type.getDeclaredFields());

        for (final Field field : declaredFields) {
            if (visitedFields.contains(field)) {
                System.out.println("Found cyclic reference for field " + field.getName() + " in class " + field.getDeclaringClass());
            } else {
                fields.add(field);
            }
        }

        if (type.getSuperclass() != null) {
            fields = getDeclaredFieldsRecursively(fields, type.getSuperclass());
        }

        return fields;
    }

    public static List<Field> getAnnotatedFields(final Object root,
                                                 final SearchPolicy searchPolicy) throws ReflectiveOperationException {
        return getAnnotatedFields(root, searchPolicy, new HashSet<>());
    }

    private static List<Field> getAnnotatedFields(final Object root,
                                                  final SearchPolicy searchPolicy,
                                                  final Set<Object> inspected) throws ReflectiveOperationException {



        final List<Field> annotatedValues = new ArrayList<>();
        if (inspected.contains(root)) { // Prevents stack overflow.
// Path: src/main/java/com/michaelfotiadis/validator/annotated/SupportedAnnotationContainer.java
// public final class SupportedAnnotationContainer {
// 
//     private static final String PACKAGE_NAME = "com.michaelfotiadis.validator.annotated.annotations";
//     private static final List<Class> SUPPORTED_CLASSES = new ArrayList<>();
// 
//     private SupportedAnnotationContainer() {
//         // NOOP
//     }
// 
//     /*package*/
//     static boolean isSupported(final Class<?> type) {
//         return getSupportedClasses().contains(type);
//     }
// 
//     public static List<Class> getSupportedClasses() {
//         if (SUPPORTED_CLASSES.isEmpty()) {
//             final Class[] supportedArray;
//             try {
//                 supportedArray = ReflectionUtils.getClasses(PACKAGE_NAME);
//                 SUPPORTED_CLASSES.addAll(Arrays.asList(supportedArray));
//             } catch (ClassNotFoundException | IOException e) {
//                 e.printStackTrace();
//             }
//         }
//         return SUPPORTED_CLASSES;
//     }
// 
// 
// }
// 
// Path: src/main/java/com/michaelfotiadis/validator/annotated/processor/SearchPolicy.java
// public enum SearchPolicy {
//     SHALLOW,
//     DEEP
// }


// Path: src/main/java/com/michaelfotiadis/validator/annotated/parser/FieldParser.java
import com.michaelfotiadis.validator.annotated.SupportedAnnotationContainer;
import com.michaelfotiadis.validator.annotated.processor.SearchPolicy;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

        final List<Field> declaredFields = Arrays.asList(type.getDeclaredFields());

        for (final Field field : declaredFields) {
            if (visitedFields.contains(field)) {
                System.out.println("Found cyclic reference for field " + field.getName() + " in class " + field.getDeclaringClass());
            } else {
                fields.add(field);
            }
        }

        if (type.getSuperclass() != null) {
            fields = getDeclaredFieldsRecursively(fields, type.getSuperclass());
        }

        return fields;
    }

    public static List<Field> getAnnotatedFields(final Object root,
                                                 final SearchPolicy searchPolicy) throws ReflectiveOperationException {
        return getAnnotatedFields(root, searchPolicy, new HashSet<>());
    }

    private static List<Field> getAnnotatedFields(final Object root,
                                                  final SearchPolicy searchPolicy,
                                                  final Set<Object> inspected) throws ReflectiveOperationException {



        final List<Field> annotatedValues = new ArrayList<>();
        if (inspected.contains(root)) { // Prevents stack overflow.
            System.out.println("*** Breaking for already inspected");