// Path: src/main/java/com/nfl/glitr/Glitr.java
// public class Glitr {
// 
//     private final TypeRegistry typeRegistry;
//     private final GraphQLCodeRegistry.Builder codeRegistryBuilder;
//     private final RelayHelper relayHelper;
//     private GraphQLSchema schema;
//     private QueryComplexityCalculator queryComplexityCalculator;
//     private static ObjectMapper objectMapper;
// 
// 
//     public Glitr(TypeRegistry typeRegistry,
//                  GraphQLCodeRegistry.Builder codeRegistryBuilder,
//                  Class queryRoot,
//                  @Nullable GraphqlFieldVisibility fieldVisibility,
//                  @Nullable ObjectMapper objectMapper,
//                  @Nullable Class mutationRoot,
//                  @Nullable Class subscriptionRoot,
//                  @Nullable QueryComplexityCalculator queryComplexityCalculator) {
//         this(typeRegistry, codeRegistryBuilder, queryRoot, fieldVisibility, objectMapper, null, mutationRoot, subscriptionRoot, queryComplexityCalculator);
//     }
// 
//     public Glitr(TypeRegistry typeRegistry,
//                  GraphQLCodeRegistry.Builder codeRegistryBuilder,
//                  Class queryRoot,
//                  @Nullable GraphqlFieldVisibility fieldVisibility,
//                  @Nullable ObjectMapper objectMapper,
//                  @Nullable RelayHelper relayHelper,
//                  @Nullable Class mutationRoot,
//                  @Nullable Class subscriptionRoot,
//                  @Nullable QueryComplexityCalculator queryComplexityCalculator) {
//         this.codeRegistryBuilder = assertNotNull(codeRegistryBuilder, "codeRegistryBuilder can't be null");
//         this.typeRegistry = assertNotNull(typeRegistry, "TypeRegistry can't be null");
//         assertNotNull(queryRoot, "queryRoot class can't be null");
//         this.relayHelper = relayHelper;
// 
//         Glitr.objectMapper = objectMapper;
//         this.schema = buildSchema(queryRoot, mutationRoot, subscriptionRoot, fieldVisibility);
// 
//         if (nonNull(queryComplexityCalculator)) {
//             this.queryComplexityCalculator = queryComplexityCalculator.withSchema(this.schema);
//         }
//     }
// 
//     public TypeRegistry getTypeRegistry() {
//         return typeRegistry;
//     }
// 
//     @Nullable
//     public QueryComplexityCalculator getQueryComplexityCalculator() {
//         return queryComplexityCalculator;
//     }
// 
//     @Nullable
//     public RelayHelper getRelayHelper() {
//         return relayHelper;
//     }
// 
//     public GraphQLSchema getSchema() {
//         return schema;
//     }
// 
//     public static ObjectMapper getObjectMapper() {
//         if (objectMapper == null) {
//             throw new RuntimeException("Serialization Impossible. Can't find an ObjectMapper implementation. Please configure GLiTR to use an ObjectMapper.");
//         }
//         return objectMapper;
//     }
// 
//     private GraphQLSchema buildSchema(Class queryRoot, Class mutationRoot, Class subscriptionRoot, GraphqlFieldVisibility fieldVisibility) {
//         // create GraphQL Schema
//         GraphQLObjectType mutationType = null;
//         if (mutationRoot != null) {
//             mutationType = typeRegistry.createRelayMutationType(mutationRoot);
//         }
//         GraphQLObjectType subscriptionType = null;
//         if (subscriptionRoot != null) {
//             subscriptionType = (GraphQLObjectType) typeRegistry.lookup(subscriptionRoot);
//         }
//         GraphQLObjectType queryType = (GraphQLObjectType) typeRegistry.lookup(queryRoot);
// 
//         if (fieldVisibility != null) {
//             codeRegistryBuilder.fieldVisibility(fieldVisibility);
// 
//             return GraphQLSchema.newSchema()
//                     .query(queryType)
//                     .mutation(mutationType)
//                     .subscription(subscriptionType)
//                     .additionalTypes(typeRegistry.getTypeDictionary())
//                     .codeRegistry(codeRegistryBuilder.build())
//                     .build();
//         }
// 
//         return GraphQLSchema.newSchema()
//                 .query(queryType)
//                 .mutation(mutationType)
//                 .subscription(subscriptionType)
//                 .additionalTypes(typeRegistry.getTypeDictionary())
//                 .codeRegistry(codeRegistryBuilder.build())
//                 .build();
//     }
// 
//     public GraphQLSchema reloadSchema(Class queryRoot, Class mutationRoot, Class subscriptionRoot, GraphqlFieldVisibility fieldVisibility) {
//         this.schema = buildSchema(queryRoot, mutationRoot, subscriptionRoot, fieldVisibility);
//         return this.schema;
//     }
// }
// 
// Path: src/main/java/com/nfl/glitr/exception/GlitrValidationException.java
// public class GlitrValidationException extends GlitrException {
// 
//     private final Set<ConstraintViolation<Object>> violations;
// 
// 
//     public GlitrValidationException(String message, Set<ConstraintViolation<Object>> violations) {
//         super(message);
//         this.violations = violations;
//     }
// 
//     public Set<ConstraintViolation<Object>> getViolations() {
//         return violations;
//     }
// }


import com.nfl.glitr.Glitr;
import com.nfl.glitr.exception.GlitrValidationException;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Map;
import java.util.Set;
package com.nfl.glitr.registry.mutation;



/**
 * DataFetcher used when GraphQL operation is a mutation
 */
public class RelayMutationDataFetcher implements DataFetcher {

    @SuppressWarnings("unused")
    private static final Logger logger = LoggerFactory.getLogger(RelayMutationDataFetcher.class);

    private final Class mutationInputClass;
    private final Validator validator;
    private final RelayMutation mutationFunc;


    public RelayMutationDataFetcher(Class mutationInputClass, RelayMutation mutationFunc) {
        this(mutationInputClass, mutationFunc, null);
    }


    public RelayMutationDataFetcher(Class mutationInputClass, RelayMutation mutationFunc, @Nullable Validator validator) {
        this.mutationInputClass = mutationInputClass;
        this.validator = validator;
        this.mutationFunc = mutationFunc;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Object get(DataFetchingEnvironment env) {
        Map<String, Object> inputMap = env.getArgument("input");

        // map fields from input map to mutationInputClass
// Path: src/main/java/com/nfl/glitr/Glitr.java
// public class Glitr {
// 
//     private final TypeRegistry typeRegistry;
//     private final GraphQLCodeRegistry.Builder codeRegistryBuilder;
//     private final RelayHelper relayHelper;
//     private GraphQLSchema schema;
//     private QueryComplexityCalculator queryComplexityCalculator;
//     private static ObjectMapper objectMapper;
// 
// 
//     public Glitr(TypeRegistry typeRegistry,
//                  GraphQLCodeRegistry.Builder codeRegistryBuilder,
//                  Class queryRoot,
//                  @Nullable GraphqlFieldVisibility fieldVisibility,
//                  @Nullable ObjectMapper objectMapper,
//                  @Nullable Class mutationRoot,
//                  @Nullable Class subscriptionRoot,
//                  @Nullable QueryComplexityCalculator queryComplexityCalculator) {
//         this(typeRegistry, codeRegistryBuilder, queryRoot, fieldVisibility, objectMapper, null, mutationRoot, subscriptionRoot, queryComplexityCalculator);
//     }
// 
//     public Glitr(TypeRegistry typeRegistry,
//                  GraphQLCodeRegistry.Builder codeRegistryBuilder,
//                  Class queryRoot,
//                  @Nullable GraphqlFieldVisibility fieldVisibility,
//                  @Nullable ObjectMapper objectMapper,
//                  @Nullable RelayHelper relayHelper,
//                  @Nullable Class mutationRoot,
//                  @Nullable Class subscriptionRoot,
//                  @Nullable QueryComplexityCalculator queryComplexityCalculator) {
//         this.codeRegistryBuilder = assertNotNull(codeRegistryBuilder, "codeRegistryBuilder can't be null");
//         this.typeRegistry = assertNotNull(typeRegistry, "TypeRegistry can't be null");
//         assertNotNull(queryRoot, "queryRoot class can't be null");
//         this.relayHelper = relayHelper;
// 
//         Glitr.objectMapper = objectMapper;
//         this.schema = buildSchema(queryRoot, mutationRoot, subscriptionRoot, fieldVisibility);
// 
//         if (nonNull(queryComplexityCalculator)) {
//             this.queryComplexityCalculator = queryComplexityCalculator.withSchema(this.schema);
//         }
//     }
// 
//     public TypeRegistry getTypeRegistry() {
//         return typeRegistry;
//     }
// 
//     @Nullable
//     public QueryComplexityCalculator getQueryComplexityCalculator() {
//         return queryComplexityCalculator;
//     }
// 
//     @Nullable
//     public RelayHelper getRelayHelper() {
//         return relayHelper;
//     }
// 
//     public GraphQLSchema getSchema() {
//         return schema;
//     }
// 
//     public static ObjectMapper getObjectMapper() {
//         if (objectMapper == null) {
//             throw new RuntimeException("Serialization Impossible. Can't find an ObjectMapper implementation. Please configure GLiTR to use an ObjectMapper.");
//         }
//         return objectMapper;
//     }
// 
//     private GraphQLSchema buildSchema(Class queryRoot, Class mutationRoot, Class subscriptionRoot, GraphqlFieldVisibility fieldVisibility) {
//         // create GraphQL Schema
//         GraphQLObjectType mutationType = null;
//         if (mutationRoot != null) {
//             mutationType = typeRegistry.createRelayMutationType(mutationRoot);
//         }
//         GraphQLObjectType subscriptionType = null;
//         if (subscriptionRoot != null) {
//             subscriptionType = (GraphQLObjectType) typeRegistry.lookup(subscriptionRoot);
//         }
//         GraphQLObjectType queryType = (GraphQLObjectType) typeRegistry.lookup(queryRoot);
// 
//         if (fieldVisibility != null) {
//             codeRegistryBuilder.fieldVisibility(fieldVisibility);
// 
//             return GraphQLSchema.newSchema()
//                     .query(queryType)
//                     .mutation(mutationType)
//                     .subscription(subscriptionType)
//                     .additionalTypes(typeRegistry.getTypeDictionary())
//                     .codeRegistry(codeRegistryBuilder.build())
//                     .build();
//         }
// 
//         return GraphQLSchema.newSchema()
//                 .query(queryType)
//                 .mutation(mutationType)
//                 .subscription(subscriptionType)
//                 .additionalTypes(typeRegistry.getTypeDictionary())
//                 .codeRegistry(codeRegistryBuilder.build())
//                 .build();
//     }
// 
//     public GraphQLSchema reloadSchema(Class queryRoot, Class mutationRoot, Class subscriptionRoot, GraphqlFieldVisibility fieldVisibility) {
//         this.schema = buildSchema(queryRoot, mutationRoot, subscriptionRoot, fieldVisibility);
//         return this.schema;
//     }
// }
// 
// Path: src/main/java/com/nfl/glitr/exception/GlitrValidationException.java
// public class GlitrValidationException extends GlitrException {
// 
//     private final Set<ConstraintViolation<Object>> violations;
// 
// 
//     public GlitrValidationException(String message, Set<ConstraintViolation<Object>> violations) {
//         super(message);
//         this.violations = violations;
//     }
// 
//     public Set<ConstraintViolation<Object>> getViolations() {
//         return violations;
//     }
// }


// Path: src/main/java/com/nfl/glitr/registry/mutation/RelayMutationDataFetcher.java
import com.nfl.glitr.Glitr;
import com.nfl.glitr.exception.GlitrValidationException;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Map;
import java.util.Set;

package com.nfl.glitr.registry.mutation;



/**
 * DataFetcher used when GraphQL operation is a mutation
 */
public class RelayMutationDataFetcher implements DataFetcher {

    @SuppressWarnings("unused")
    private static final Logger logger = LoggerFactory.getLogger(RelayMutationDataFetcher.class);

    private final Class mutationInputClass;
    private final Validator validator;
    private final RelayMutation mutationFunc;


    public RelayMutationDataFetcher(Class mutationInputClass, RelayMutation mutationFunc) {
        this(mutationInputClass, mutationFunc, null);
    }


    public RelayMutationDataFetcher(Class mutationInputClass, RelayMutation mutationFunc, @Nullable Validator validator) {
        this.mutationInputClass = mutationInputClass;
        this.validator = validator;
        this.mutationFunc = mutationFunc;
    }

    @Override
    @SuppressWarnings("unchecked")
    public Object get(DataFetchingEnvironment env) {
        Map<String, Object> inputMap = env.getArgument("input");

        // map fields from input map to mutationInputClass
        Object inputPayloadMtn = Glitr.getObjectMapper().convertValue(inputMap, mutationInputClass);