private static bool DoParentTypesNotMatch(NodeAndDefinitions field1, NodeAndDefinitions field2)
        {
            if (field1.ParentType != null && field2.ParentType != null)
            {
                return(field1.ParentType.Name != field2.ParentType.Name);
            }

            if (field1.PresumedParentName != null || field2.PresumedParentName != null)
            {
                return(field1.PresumedParentName != field2.PresumedParentName);
            }

            return(false);
        }
        private Conflict SubfieldConflicts(
            IEnumerable <Conflict> conflicts,
            string responseName,
            NodeAndDefinitions field1,
            NodeAndDefinitions field2)
        {
            var field1List = new List <GraphQLFieldSelection> {
                field1.Selection
            };

            field1List.AddRange(conflicts.SelectMany(e => e.Field1));

            var field2List = new List <GraphQLFieldSelection> {
                field2.Selection
            };

            field2List.AddRange(conflicts.SelectMany(e => e.Field2));

            var fields = new Dictionary <string, Conflict>();

            foreach (var conflict in conflicts)
            {
                if (!fields.ContainsKey(conflict.ResponseName))
                {
                    fields.Add(conflict.ResponseName, conflict);
                }
            }

            return(new Conflict()
            {
                Field1 = field1List.ToArray(),
                Field2 = field2List.ToArray(),
                ResponseName = responseName,
                Subreasons = fields.Values.ToArray()
            });
        }
        private Conflict FindConflict(
            bool parentFieldsAreMutuallyExclusive,
            string responseName,
            NodeAndDefinitions field1,
            NodeAndDefinitions field2)
        {
            var areMutuallyExclusive =
                parentFieldsAreMutuallyExclusive ||
                DoParentTypesNotMatch(field1, field2);

            var             name1 = field1.Selection.Name.Value;
            var             name2 = field2.Selection.Name.Value;
            GraphQLBaseType type1 = null;
            GraphQLBaseType type2 = null;

            if (field1.ParentType is GraphQLComplexType)
            {
                var complexType = field1.ParentType as GraphQLComplexType;
                type1 = complexType.GetFieldInfo(name1)?.GetGraphQLType(this.SchemaRepository);
            }

            if (field2.ParentType is GraphQLComplexType)
            {
                var complexType = field2.ParentType as GraphQLComplexType;
                type2 = complexType.GetFieldInfo(name2)?.GetGraphQLType(this.SchemaRepository);
            }

            if (!areMutuallyExclusive)
            {
                if (name1 != name2)
                {
                    return(new Conflict()
                    {
                        ResponseName = responseName,
                        Reason = $"{name1} and {name2} are different fields",
                        Field1 = new[] { field1.Selection },
                        Field2 = new[] { field2.Selection }
                    });
                }

                if (!this.HaveSameArguments(field1.Selection, field2.Selection))
                {
                    return(new Conflict()
                    {
                        ResponseName = responseName,
                        Reason = "they have differing arguments",
                        Field1 = new[] { field1.Selection },
                        Field2 = new[] { field2.Selection }
                    });
                }
            }

            if (type1 != null && type2 != null && this.DoTypesConflict(type1, type2))
            {
                return(new Conflict()
                {
                    ResponseName = responseName,
                    Reason = $"they return conflicting types {type1} and {type2}",
                    Field1 = new[] { field1.Selection },
                    Field2 = new[] { field2.Selection }
                });
            }

            var selectionSet1 = field1.Selection?.SelectionSet;
            var selectionSet2 = field2.Selection?.SelectionSet;

            if (selectionSet1 != null && selectionSet2 != null)
            {
                var conflicts = this.FindConflictsBetweenSubSelectionSets(
                    type1,
                    type2,
                    selectionSet1,
                    selectionSet2,
                    areMutuallyExclusive);

                if (conflicts.Any())
                {
                    return(this.SubfieldConflicts(conflicts, responseName, field1, field2));
                }
            }

            return(null);
        }