public function mapToCollection(CollectionType $collectionType, callable $mapperCallback = null, callable $reverseMapperCallback = null)
    {
        $collectionClass = $collectionType->getCollectionClass();

        if ($collectionClass === TypedCollection::class || $collectionClass === ITypedCollection::class) {
            $collectionFactory = function (array $input) use ($collectionType) {
                return new TypedCollection($collectionType->getElementType(), $input);
            };
        } elseif ($collectionClass === EntityIdCollection::class) {
            $collectionFactory = function (array $input) use ($collectionType) {
                return new EntityIdCollection($input);
            };
        } elseif ($collectionType->isSubsetOf(TypedObject::collectionType())) {
            $objectType = $collectionType->getElementType()->asTypeString();
            $collectionFactory = function (array $input) use ($objectType) {
                /** @var string|TypedObject $objectType */
                return $objectType::collection($input);
            };
        } else {
            throw InvalidArgumentException::format(
                'Invalid collection type supplied to %s: expecting one of (%s), %s given',
                get_class($this) . '::' . __FUNCTION__,
                Debug::formatValues([TypedCollection::class, EntityIdCollection::class, TypedObject::collectionType()->asTypeString()]),
                $collectionType->asTypeString()
            );
        }

        $this->customProcessorCallbacks[] = function (IType $currentType) use (
            $collectionType,
            $collectionFactory,
            $mapperCallback,
            $reverseMapperCallback
        ) {
            return new CustomProcessor(
                $currentType->isNullable() ? $collectionType->nullable() : $collectionType,
                function (array $elements) use ($collectionFactory, $mapperCallback) {
                    $elements = $mapperCallback ? array_map($mapperCallback, $elements) : $elements;

                    return $collectionFactory($elements);
                },
                function (ITypedCollection $collection) use ($collectionType, $reverseMapperCallback) {
                    $elements = [];

                    foreach ($collection as $key => $element) {
                        $elements[$key] = $element;
                    }

                    return $reverseMapperCallback ? array_map($reverseMapperCallback, $elements) : $elements;
                }
            );
        };

        return $this;
    }