/**
  * Build a ContentType object
  *
  * This method takes the root (a node) of the page's content tree (records from the contents table))
  * and transforms it into a corresponding tree of content elements for rendering.
  *
  * The database fields have the following meaning:
  *
  * `name`         - a page-wide unique name (id) for the element. SHOULD be used as id attribute.
  * `content_type` - fully qualified classname of the content element.
  * `content_args` - constructor parameters for the content element.
  * `component`    - name of the entity containing data for the content element.
  * `selection`    - selection criteria for the data entity.
  * `params`       - additional parameters for use by the layout file.
  *
  * @param Content $root
  *
  * @return ContentTypeInterface[]
  */
 private function toContentType($root)
 {
     #echo "<pre>" . __METHOD__ . ' ' . $this->dumpEntity($root) . "\n";
     #echo "Data selection: " . $root->component . ' ' . print_r($root->selection, true) . "\n";
     $contentType = $root->contentType;
     $data = $this->findData($root->component, $root->selection);
     $reflector = new \ReflectionClass($contentType);
     $constructor = $reflector->getConstructor();
     $constructorParameters = null;
     if (!empty($constructor)) {
         $constructorParameters = $constructor->getParameters();
     }
     $all = [];
     foreach (array_values($data) as $index => $item) {
         #echo "<pre>";
         #echo "Data item: " . $this->dumpEntity($item) . "\n";
         /** @var AbstractContentType $content */
         $providedArguments = empty($root->contentArgs) ? [] : get_object_vars($root->contentArgs);
         $actualArguments = [];
         foreach ($constructorParameters as $parameter) {
             $name = $parameter->getName();
             $defaultValue = $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null;
             if ($name == 'item') {
                 $defaultValue = $item;
             }
             $actualArguments[$name] = isset($providedArguments[$name]) ? $providedArguments[$name] : $defaultValue;
         }
         $content = $reflector->newInstanceArgs($actualArguments);
         $content->setId($index == 0 ? $root->name : $root->name . '-' . $index);
         $content->setParameters($root->params);
         if (!empty($root->customCss)) {
             $this->output->addCss($content->getId(), $root->customCss);
         }
         #echo "Content: " . get_class($content) . "\n";
         if ($content instanceof CompoundTypeInterface) {
             /** @noinspection PhpUndefinedFieldInspection */
             foreach ($root->children as $node) {
                 #echo "<pre>";
                 #echo "Child: " . $node->name . " (" . $node->contentType . ")\n";
                 foreach ($this->toContentType($node) as $child) {
                     #echo "Result: " . get_class($child) . "\n";
                     $content->add($child);
                 }
                 #echo "</pre>";
             }
         }
         $all[] = $content;
         #echo "</pre>";
     }
     #echo "</pre>";
     return $all;
 }