public function whereCollectionContains(string $collectionMemberExpression, $item)
    {
        $expression           = $this->memberExpressionParser->parse($this->class, $collectionMemberExpression);
        $isEntityIdCollection = $expression->getResultingType()->nonNullable()->isSubsetOf(EntityIdCollection::type());

        if ($isEntityIdCollection) {
            $memberParts                = explode('.', $collectionMemberExpression);
            $lastPart                   = array_pop($memberParts);
            $memberParts[]              = 'loadAll(' . $lastPart . ')';
            $collectionMemberExpression = implode('.', $memberParts);
            $expression                 = $this->memberExpressionParser->parse($this->class, $collectionMemberExpression);
        }

        /** @var CollectionType $collectionType */
        $collectionType = $expression->getResultingType()->nonNullable();
        if (!$collectionType->isSubsetOf(Type::collectionOf(TypedObject::type()))) {
            throw InvalidMemberExpressionException::format(
                'Invalid collection member expression supplied to %s: expecting type %s, %s (\'%s\') given',
                __METHOD__, Type::collectionOf(TypedObject::type())->asTypeString(),
                $collectionType->asTypeString(), $collectionMemberExpression
            );
        }

        /** @var string|TypedObject $objectType */
        $objectType = $collectionType->getElementType()->asTypeString();

        if ($isEntityIdCollection) {
            if (!is_int($item)) {
                throw InvalidArgumentException::format(
                    'Invalid collection item supplied to %s: expecting type %s, %s given',
                    __METHOD__, $objectType, Type::from($item)->asTypeString()
                );
            }

            $specification = $objectType::specification(function (SpecificationDefinition $match) use ($item) {
                $match->where(Entity::ID, '=', $item);
            });
        } else {
            if (!($item instanceof $objectType)) {
                throw InvalidArgumentException::format(
                    'Invalid collection item supplied to %s: expecting type %s, %s given',
                    __METHOD__, $objectType, Type::from($item)->asTypeString()
                );
            }

            $specification = $objectType::specification(function (SpecificationDefinition $match) use ($item) {
                $match->where('this', '=', $item);
            });
        }

        return $this->whereHasAny($collectionMemberExpression, $specification);
    }