public function moveAfter(NodeInterface $referenceNode, string $newName = null): void
    {
        if ($referenceNode === $this) {
            return;
        }

        if ($this->isRoot()) {
            throw new NodeException('The root node cannot be moved.', 1316361483);
        }

        $name = $newName !== null ? $newName : $this->getName();
        $referenceParentNode = $referenceNode->getParent();

        if ($referenceParentNode !== $this->getParent() && $referenceParentNode->getNode($name) !== null) {
            throw new NodeExistsException(sprintf('Node with path "%s" already exists.', $name), 1292503469);
        }

        if (($referenceParentNode instanceof Node && !$referenceParentNode->willChildNodeBeAutoCreated($name)) && !$referenceParentNode->isNodeTypeAllowedAsChildNode($this->getNodeType())) {
            throw new NodeConstraintException(sprintf('Cannot move %s after %s', $this, $referenceNode), 1404648100);
        }

        $this->emitBeforeNodeMove($this, $referenceNode, NodeDataRepository::POSITION_AFTER);
        if ($referenceNode->getParentPath() !== $this->getParentPath()) {
            $this->setPath(NodePaths::addNodePathSegment($referenceNode->getParentPath(), $name));
            $this->nodeDataRepository->persistEntities();
        } else {
            if (!$this->isNodeDataMatchingContext()) {
                $this->materializeNodeData();
            }
        }

        $this->nodeDataRepository->setNewIndex($this->nodeData, NodeDataRepository::POSITION_AFTER, $referenceNode);
        $this->context->getFirstLevelNodeCache()->flush();
        $this->emitAfterNodeMove($this, $referenceNode, NodeDataRepository::POSITION_AFTER);
        $this->emitNodeUpdated($this);
    }