public function reorder(TreeNodeInterface $node, TreeNodeInterface $beforeNode)
    {
        if ($beforeNode->getParentNode()->getId() !== $node->getParentNode()->getId()) {
            throw new InvalidNodeMoveException('Node and targetNode need to have the same parent.');
        }

        if ($node->getParentNode()->getSortMode() !== 'free') {
            return;
        }

        $sort = $beforeNode->getSort() + 1;

        $event = new ReorderNodeEvent($node, $sort);
        if ($this->dispatcher->dispatch(TreeEvents::BEFORE_REORDER_NODE, $event)->isPropagationStopped()) {
            return;
        }

        $updatesNodes = [];

        $currentSort = $sort + 1;
        foreach ($this->getChildren($node->getParentNode()) as $childNode) {
            if ($childNode->getSort() <= $sort) {
                $childNode->setSort($currentSort++);
                $updatesNodes[] = $childNode;
            }
        }

        $node->setSort($sort);
        $updateNodes[] = $node;

        $this->updateNodes($updateNodes);

        $event = new NodeEvent($node);
        $this->dispatcher->dispatch(TreeEvents::REORDER_NODE, $event);

        return;
    }