public function copyBefore(NodeInterface $referenceNode, $nodeName)
{
if ($referenceNode->getParent()->getNode($nodeName) !== null) {
throw new NodeExistsException('Node with path "' . $referenceNode->getParent()->getPath() . '/' . $nodeName . '" already exists.', 1292503465);
}
if (!$referenceNode->getParent()->isNodeTypeAllowedAsChildNode($this->getNodeType())) {
throw new NodeConstraintException('Cannot copy ' . $this->__toString() . ' before ' . $referenceNode->__toString(), 1402050232);
}
$this->emitBeforeNodeCopy($this, $referenceNode->getParent());
$copiedNode = $this->createRecursiveCopy($referenceNode->getParent(), $nodeName, $this->getNodeType()->isAggregate());
$copiedNode->moveBefore($referenceNode);
$this->context->getFirstLevelNodeCache()->flush();
$this->emitNodeAdded($copiedNode);
$this->emitAfterNodeCopy($copiedNode, $referenceNode->getParent());
return $copiedNode;
}