protected function findConflictsBetweenSubSelectionSets(
        ?NamedTypeInterface $parentTypeA,
        SelectionSetNode $selectionSetA,
        ?NamedTypeInterface $parentTypeB,
        SelectionSetNode $selectionSetB,
        bool $areMutuallyExclusive
    ): array {
        $context = new ComparisonContext();

        $contextA = $this->getFieldsAndFragmentNames($selectionSetA, $parentTypeA);
        $contextB = $this->getFieldsAndFragmentNames($selectionSetB, $parentTypeB);

        $fieldMapA = $contextA->getFieldMap();
        $fieldMapB = $contextB->getFieldMap();

        $fragmentNamesA = $contextA->getFragmentNames();
        $fragmentNamesB = $contextB->getFragmentNames();

        $fragmentNamesACount = \count($fragmentNamesA);
        $fragmentNamesBCount = \count($fragmentNamesB);

        // (H) First, collect all conflicts between these two collections of field.
        $this->collectConflictsBetween(
            $context,
            $fieldMapA,
            $fieldMapB,
            $areMutuallyExclusive
        );

        // (I) Then collect conflicts between the first collection of fields and
        // those referenced by each fragment name associated with the second.
        if (!empty($fragmentNamesB)) {
            $comparedFragments = [];

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

        // (I) Then collect conflicts between the second collection of fields and
        // those referenced by each fragment name associated with the first.
        if (!empty($fragmentNamesA)) {
            $comparedFragments = [];

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

        /** @noinspection ForeachInvariantsInspection */
        for ($i = 0; $i < $fragmentNamesACount; $i++) {
            /** @noinspection ForeachInvariantsInspection */
            for ($j = 0; $j < $fragmentNamesBCount; $j++) {
                $this->collectConflictsBetweenFragments(
                    $context,
                    $fragmentNamesA[$i],
                    $fragmentNamesB[$j],
                    $areMutuallyExclusive
                );
            }
        }

        return $context->getConflicts();
    }