private void CollectConflictsBetweenFragments(
            ValidationContext context,
            List <Conflict> conflicts,
            Dictionary <SelectionSet, CachedField> cachedFieldsAndFragmentNames,
            PairSet comparedFragmentPairs,
            bool areMutuallyExclusive,
            string fragmentName1,
            string fragmentName2)
        {
            // No need to compare a fragment to itself.
            if (fragmentName1 == fragmentName2)
            {
                return;
            }

            // Memoize so two fragments are not compared for conflicts more than once.
            if (comparedFragmentPairs.Has(fragmentName1, fragmentName2, areMutuallyExclusive))
            {
                return;
            }

            comparedFragmentPairs.Add(fragmentName1, fragmentName2, areMutuallyExclusive);

            var fragment1 = context.GetFragment(fragmentName1);
            var fragment2 = context.GetFragment(fragmentName2);

            if (fragment1 == null || fragment2 == null)
            {
                return;
            }

            var cachedField1 =
                GetReferencedFieldsAndFragmentNames(
                    context,
                    cachedFieldsAndFragmentNames,
                    fragment1);

            var fieldMap1      = cachedField1.NodeAndDef;
            var fragmentNames1 = cachedField1.Names;

            var cachedField2 =
                GetReferencedFieldsAndFragmentNames(
                    context,
                    cachedFieldsAndFragmentNames,
                    fragment2);

            var fieldMap2      = cachedField2.NodeAndDef;
            var fragmentNames2 = cachedField2.Names;

            // (F) First, collect all conflicts between these two collections of fields
            // (not including any nested fragments).
            CollectConflictsBetween(
                context,
                conflicts,
                cachedFieldsAndFragmentNames,
                comparedFragmentPairs,
                areMutuallyExclusive,
                fieldMap1,
                fieldMap2);

            // (G) Then collect conflicts between the first fragment and any nested
            // fragments spread in the second fragment.
            for (var j = 0; j < fragmentNames2.Count; j++)
            {
                CollectConflictsBetweenFragments(
                    context,
                    conflicts,
                    cachedFieldsAndFragmentNames,
                    comparedFragmentPairs,
                    areMutuallyExclusive,
                    fragmentName1,
                    fragmentNames2[j]);
            }

            // (G) Then collect conflicts between the second fragment and any nested
            // fragments spread in the first fragment.
            for (var i = 0; i < fragmentNames1.Count; i++)
            {
                CollectConflictsBetweenFragments(
                    context,
                    conflicts,
                    cachedFieldsAndFragmentNames,
                    comparedFragmentPairs,
                    areMutuallyExclusive,
                    fragmentNames1[i],
                    fragmentName2);
            }
        }