public function handle(CollectionCommand $command)
    {
        $target = $command->getTarget();
        $collection = $command->getCollection();
        $options = $command->getOptions();
        $direction = $options->getDirection();
        $comparator = $collection->getComparator();
        if ($direction->isDown()) {
            $comparator = $comparator->getReverse();
        }

        // filter to only get versions that need to be migrated
        $filter = function (DeltaInterface $v) use ($target, $comparator, $direction) {
            return ($direction->isUp() ^ $v->isMigrated()) // direction must be opposite to migration status
                    && $comparator->compare($v, $target) <= 0; // version must be before or be equal to target (not
                                                               // affected by direction because comparator is reversed)
        };
        $scheduled = $collection->filter($filter)->sort($comparator);
        // we don't check if $scheduled is empty after filtering because the collection-before and -after events should
        // still be triggered by the runner

        $event = $this->createRunnerFor($scheduled)->run($target, $options);

        return $command->getVersionRepository()->updateAll($event->getCollection());
    }