/**
  * Internal method to do the actual copying.
  *
  * For behavior of the $detachedCopy parameter, see method Node::createRecursiveCopy().
  *
  * @param NodeInterface $referenceNode
  * @param $nodeName
  * @param boolean $detachedCopy
  * @return NodeInterface
  * @throws NodeConstraintException
  * @throws NodeExistsException
  */
 protected function copyIntoInternal(NodeInterface $referenceNode, $nodeName, $detachedCopy)
 {
     if ($referenceNode->getNode($nodeName) !== null) {
         throw new NodeExistsException('Node with path "' . $referenceNode->getPath() . '/' . $nodeName . '" already exists.', 1292503467);
     }
     // On copy we basically re-recreate an existing node on a new location. As we skip the constraints check on
     // node creation we should do the same while writing the node on the new location.
     if (!$referenceNode->willChildNodeBeAutoCreated($nodeName) && !$referenceNode->isNodeTypeAllowedAsChildNode($this->getNodeType())) {
         throw new NodeConstraintException(sprintf('Cannot copy "%s" into "%s" due to node type constraints.', $this->__toString(), $referenceNode->__toString()), 1404648177);
     }
     $copiedNode = $this->createRecursiveCopy($referenceNode, $nodeName, $detachedCopy);
     $this->context->getFirstLevelNodeCache()->flush();
     $this->emitNodeAdded($copiedNode);
     return $copiedNode;
 }