// Path: src/main/java/com/bretpatterson/schemagen/graphql/IGraphQLObjectMapper.java
// public interface IGraphQLObjectMapper {
// 
// 	/**
// 	 * Get the object responsible for naming GraphQL types.
// 	 * @return
// 	 */
// 	ITypeNamingStrategy getTypeNamingStrategy();
// 
// 	/**
// 	 * Get an input definition for the specified type.
// 	 * @param type
// 	 */
// 	GraphQLInputType getInputType(Type type);
// 
// 	/**
// 	 * Get an output definition for the specified type.
// 	 * @param type
// 	 */
// 	GraphQLOutputType getOutputType(Type type);
// 
// 	/**
// 	 * Get the Input Type cache. This is useful for custom type mappers who
// 	 * might need to add TypeReference's to the cache when they need to process
// 	 * an object that contains a two way dependency between itself and another object.
// 	 */
// 	IGraphQLTypeCache<GraphQLInputType> getInputTypeCache();
// 
// 	/**
// 	 * Get the Input Type cache. This is useful for custom type mappers who
// 	 * might need to add TypeReference's to the cache when they need to process
// 	 * an object that contains a two way dependency between itself and another object.
// 	 */
// 	IGraphQLTypeCache<GraphQLOutputType> getOutputTypeCache();
// 
// 	/**
// 	 * Returns the object responsible for object type conversion.
// 	 * @return
// 	 */
// 	ITypeFactory getTypeFactory();
// 
// 	/**
// 	 * Get the raw type of this object for generic types
// 	 * @param type
// 	 * @return
// 	 */
// 	Class<?> getClassFromType(Type type);
// 
// 	/**
// 	 * Returns all input types created.
// 	 * @return
// 	 */
// 	Set<GraphQLType> getInputTypes();
// 
// 	/**
// 	 * Get the datafetcher factory
// 	 * @return
// 	 */
// 	IDataFetcherFactory getDataFetcherFactory() ;
// 
// 	/**
// 	 *
// 	 * @param dataFetcherFactory
// 	 */
// 	void setDataFetcherFactory(IDataFetcherFactory dataFetcherFactory);
// 
// 	/**
// 	 * Get the default datafetcher for methods
// 	 * @return
// 	 */
// 	Class<? extends IDataFetcher> getDefaultMethodDataFetcher();
// 
// 	/**
// 	 * Set the default data fetcher used for methods
// 	 * @param defaultMethodDataFetcher
// 	 */
// 	void setDefaultMethodDataFetcher(Class<? extends IDataFetcher> defaultMethodDataFetcher);
// 
// 	Collection<GraphQLFieldDefinition> getGraphQLFieldDefinitions(Optional<Object> targetObject, Type type, Class<?> classItem, Optional<List<Field>> fields, Optional<List<Method>> methods);
// }
// 
// Path: src/main/java/com/bretpatterson/schemagen/graphql/impl/DefaultDataFetcherFactory.java
// public class DefaultDataFetcherFactory implements IDataFetcherFactory {
// 
// 	@Override
// 	public DataFetcher newFieldDataFetcher(final IGraphQLObjectMapper objectMapper, final Optional<Object> targetObject, final Field field, String fieldName, Class<? extends DataFetcher> dataFetcher) {
// 		if (dataFetcher != null) {
// 			try {
// 				return dataFetcher.newInstance();
// 			} catch (IllegalAccessException | InstantiationException ex) {
// 				throw Throwables.propagate(ex);
// 			}
// 		} else {
// 			return new PropertyDataFetcher(fieldName);
// 		}
// 	}
// 
// 	@Override
// 	public DataFetcher newMethodDataFetcher(final IGraphQLObjectMapper graphQLObjectMapper,
// 			final Optional<Object> targetObject,
// 			final Method method,
// 			final String fieldName,
// 			final Class<? extends DataFetcher> dataFetcher) {
// 		DataFetcher dataFetcherObject;
// 		try {
// 			dataFetcherObject = dataFetcher.newInstance();
// 			if (!IMethodDataFetcher.class.isAssignableFrom(dataFetcher)) {
// 				throw new InvalidParameterException("This Data Fetcher Factory only supports IMethodDataFetchers");
// 			}
// 			IMethodDataFetcher methodDataFetcher = (IMethodDataFetcher) dataFetcherObject;
// 			methodDataFetcher.setFieldName(fieldName);
// 			methodDataFetcher.setTypeFactory(graphQLObjectMapper.getTypeFactory());
// 			if (targetObject.isPresent()) {
// 				methodDataFetcher.setTargetObject(targetObject.get());
// 			}
// 			methodDataFetcher.setMethod(method);
// 		} catch (Exception ex) {
// 			throw Throwables.propagate(ex);
// 		}
// 		return dataFetcherObject;
// 	}
// }


import com.bretpatterson.schemagen.graphql.IGraphQLObjectMapper;
import com.bretpatterson.schemagen.graphql.annotations.GraphQLSpringELDataFetcher;
import com.bretpatterson.schemagen.graphql.impl.DefaultDataFetcherFactory;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import graphql.schema.DataFetcher;
import org.springframework.beans.factory.access.el.SpringBeanELResolver;
import org.springframework.context.ApplicationContext;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static com.google.common.base.Preconditions.checkNotNull;
package com.bretpatterson.schemagen.graphql.datafetchers.spring;




/**
 * Supports methods/fields annotated with the @GraphQLSpringDataFetcher annotation. This allows you to execute Spring EL expressions as part
 * of your datafetching environment.
 */
public class SpringDataFetcherFactory extends DefaultDataFetcherFactory {

	ApplicationContext context;
	SpringBeanELResolver springBeanELResolver;

	public SpringDataFetcherFactory(ApplicationContext context) {
		this.context = context;
	}

	@Override
// Path: src/main/java/com/bretpatterson/schemagen/graphql/IGraphQLObjectMapper.java
// public interface IGraphQLObjectMapper {
// 
// 	/**
// 	 * Get the object responsible for naming GraphQL types.
// 	 * @return
// 	 */
// 	ITypeNamingStrategy getTypeNamingStrategy();
// 
// 	/**
// 	 * Get an input definition for the specified type.
// 	 * @param type
// 	 */
// 	GraphQLInputType getInputType(Type type);
// 
// 	/**
// 	 * Get an output definition for the specified type.
// 	 * @param type
// 	 */
// 	GraphQLOutputType getOutputType(Type type);
// 
// 	/**
// 	 * Get the Input Type cache. This is useful for custom type mappers who
// 	 * might need to add TypeReference's to the cache when they need to process
// 	 * an object that contains a two way dependency between itself and another object.
// 	 */
// 	IGraphQLTypeCache<GraphQLInputType> getInputTypeCache();
// 
// 	/**
// 	 * Get the Input Type cache. This is useful for custom type mappers who
// 	 * might need to add TypeReference's to the cache when they need to process
// 	 * an object that contains a two way dependency between itself and another object.
// 	 */
// 	IGraphQLTypeCache<GraphQLOutputType> getOutputTypeCache();
// 
// 	/**
// 	 * Returns the object responsible for object type conversion.
// 	 * @return
// 	 */
// 	ITypeFactory getTypeFactory();
// 
// 	/**
// 	 * Get the raw type of this object for generic types
// 	 * @param type
// 	 * @return
// 	 */
// 	Class<?> getClassFromType(Type type);
// 
// 	/**
// 	 * Returns all input types created.
// 	 * @return
// 	 */
// 	Set<GraphQLType> getInputTypes();
// 
// 	/**
// 	 * Get the datafetcher factory
// 	 * @return
// 	 */
// 	IDataFetcherFactory getDataFetcherFactory() ;
// 
// 	/**
// 	 *
// 	 * @param dataFetcherFactory
// 	 */
// 	void setDataFetcherFactory(IDataFetcherFactory dataFetcherFactory);
// 
// 	/**
// 	 * Get the default datafetcher for methods
// 	 * @return
// 	 */
// 	Class<? extends IDataFetcher> getDefaultMethodDataFetcher();
// 
// 	/**
// 	 * Set the default data fetcher used for methods
// 	 * @param defaultMethodDataFetcher
// 	 */
// 	void setDefaultMethodDataFetcher(Class<? extends IDataFetcher> defaultMethodDataFetcher);
// 
// 	Collection<GraphQLFieldDefinition> getGraphQLFieldDefinitions(Optional<Object> targetObject, Type type, Class<?> classItem, Optional<List<Field>> fields, Optional<List<Method>> methods);
// }
// 
// Path: src/main/java/com/bretpatterson/schemagen/graphql/impl/DefaultDataFetcherFactory.java
// public class DefaultDataFetcherFactory implements IDataFetcherFactory {
// 
// 	@Override
// 	public DataFetcher newFieldDataFetcher(final IGraphQLObjectMapper objectMapper, final Optional<Object> targetObject, final Field field, String fieldName, Class<? extends DataFetcher> dataFetcher) {
// 		if (dataFetcher != null) {
// 			try {
// 				return dataFetcher.newInstance();
// 			} catch (IllegalAccessException | InstantiationException ex) {
// 				throw Throwables.propagate(ex);
// 			}
// 		} else {
// 			return new PropertyDataFetcher(fieldName);
// 		}
// 	}
// 
// 	@Override
// 	public DataFetcher newMethodDataFetcher(final IGraphQLObjectMapper graphQLObjectMapper,
// 			final Optional<Object> targetObject,
// 			final Method method,
// 			final String fieldName,
// 			final Class<? extends DataFetcher> dataFetcher) {
// 		DataFetcher dataFetcherObject;
// 		try {
// 			dataFetcherObject = dataFetcher.newInstance();
// 			if (!IMethodDataFetcher.class.isAssignableFrom(dataFetcher)) {
// 				throw new InvalidParameterException("This Data Fetcher Factory only supports IMethodDataFetchers");
// 			}
// 			IMethodDataFetcher methodDataFetcher = (IMethodDataFetcher) dataFetcherObject;
// 			methodDataFetcher.setFieldName(fieldName);
// 			methodDataFetcher.setTypeFactory(graphQLObjectMapper.getTypeFactory());
// 			if (targetObject.isPresent()) {
// 				methodDataFetcher.setTargetObject(targetObject.get());
// 			}
// 			methodDataFetcher.setMethod(method);
// 		} catch (Exception ex) {
// 			throw Throwables.propagate(ex);
// 		}
// 		return dataFetcherObject;
// 	}
// }


// Path: schemagen-graphql-spring/src/main/java/com/bretpatterson/schemagen/graphql/datafetchers/spring/SpringDataFetcherFactory.java
import com.bretpatterson.schemagen.graphql.IGraphQLObjectMapper;
import com.bretpatterson.schemagen.graphql.annotations.GraphQLSpringELDataFetcher;
import com.bretpatterson.schemagen.graphql.impl.DefaultDataFetcherFactory;
import com.google.common.base.Optional;
import com.google.common.base.Throwables;
import graphql.schema.DataFetcher;
import org.springframework.beans.factory.access.el.SpringBeanELResolver;
import org.springframework.context.ApplicationContext;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static com.google.common.base.Preconditions.checkNotNull;

package com.bretpatterson.schemagen.graphql.datafetchers.spring;




/**
 * Supports methods/fields annotated with the @GraphQLSpringDataFetcher annotation. This allows you to execute Spring EL expressions as part
 * of your datafetching environment.
 */
public class SpringDataFetcherFactory extends DefaultDataFetcherFactory {

	ApplicationContext context;
	SpringBeanELResolver springBeanELResolver;

	public SpringDataFetcherFactory(ApplicationContext context) {
		this.context = context;
	}

	@Override
	public DataFetcher newFieldDataFetcher(final IGraphQLObjectMapper graphQLObjectMapper, final Optional<Object> targetObject, final Field field, final String fieldName, Class<? extends DataFetcher> dataFetcher) {