protected function collectConflictsBetweenFieldsAndFragment(
        ComparisonContext $context,
        array &$comparedFragments,
        array $fieldMap,
        string $fragmentName,
        bool $areMutuallyExclusive
    ): void {
        // Memoize so a fragment is not compared for conflicts more than once.
        if (isset($comparedFragments[$fragmentName])) {
            return;
        }

        $comparedFragments[$fragmentName] = true;

        $fragment = $this->getContext()->getFragment($fragmentName);

        if (null === $fragment) {
            return;
        }

        $contextB = $this->getReferencedFieldsAndFragmentNames($fragment);

        $fieldMapB = $contextB->getFieldMap();

        // Do not compare a fragment's fieldMap to itself.
        if ($fieldMap == $fieldMapB) {
            return;
        }

        // (D) First collect any conflicts between the provided collection of fields
        // and the collection of fields represented by the given fragment.
        $this->collectConflictsBetween(
            $context,
            $fieldMap,
            $fieldMapB,
            $areMutuallyExclusive
        );

        $fragmentNamesB = $contextB->getFragmentNames();

        // (E) Then collect any conflicts between the provided collection of fields
        // and any fragment names found in the given fragment.
        if (!empty($fragmentNamesB)) {
            $fragmentNamesBCount = \count($fragmentNamesB);

            /** @noinspection ForeachInvariantsInspection */
            for ($i = 0; $i < $fragmentNamesBCount; $i++) {
                $this->collectConflictsBetweenFieldsAndFragment(
                    $context,
                    $comparedFragments,
                    $fieldMap,
                    $fragmentNamesB[$i],
                    $areMutuallyExclusive
                );
            }
        }
    }