/**
  * Appends (copies) a child $source and all its descendants to $this node
  *
  * @param  SimpleXMLElement|\SimpleXMLElement  $source
  * @param  callback                            $callBack to check/transform data or attributes of a node: $destinationData = function ( string|array $sourceData, SimpleXMLElement $sourceNode, SimpleXMLElement $destinationParentNode );
  * @return SimpleXMLElement
  */
 public function &addChildWithDescendants(&$source, $callBack = null)
 {
     if ($callBack === null) {
         $child = $this->addChildWithAttr($source->getName(), $source->data(), null, $source->attributes());
     } else {
         $child = $this->addChildWithAttr($source->getName(), call_user_func_array($callBack, array($source->data(), $source, $this)), null, call_user_func_array($callBack, array($source->attributes(), $source, $this)));
     }
     foreach ($source->children() as $sourceChild) {
         $child->addChildWithDescendants($sourceChild, $callBack);
     }
     return $child;
 }