/**
  * Creates a component corresponding to the specified tag and optionally sets its published properties.
  *
  * <p>This is called by the parser.
  *
  * @param string     $tagName  It may contain an XML namespace prefix, ex: 'x:tag'
  * @param Component  $parent   The component's container component.
  * @param string[]   $props    A map of property names to property values.
  *                             Properties specified via this argument come only from markup attributes, not
  *                             from subtags.
  * @param array|null $bindings A map of attribute names and corresponding databinding expressions.
  * @param bool       $generic  If true, an instance of GenericComponent is created.
  * @param boolean    $strict   If true, failure to find a component class will throw an exception.
  *                             If false, an attempt is made to load a macro with the same name,
  * @return Component Component instance. For macros, an instance of Macro is returned.
  * @throws ComponentException
  * @throws MatisseException
  */
 function createComponentFromTag($tagName, Component $parent, array $props = null, array $bindings = null, $generic = false, $strict = false)
 {
     $s = explode(':', $tagName, 2);
     if (count($s) > 1) {
         list($prefix, $tagName) = $s;
     } else {
         $prefix = '';
     }
     if ($prefix) {
         throw new MatisseException("XML namespaces are not yet supported.<p>Tag: <kbd>&lt;<b>{$prefix}:</b>{$tagName}&gt;</kbd>");
     }
     if ($generic) {
         $component = new GenericHtmlComponent($tagName, $props);
         return $component;
     }
     $class = $this->getClassForTag($tagName);
     /** @var DocumentContext $this */
     if (!$class) {
         if ($strict) {
             Component::throwUnknownComponent($this, $tagName, $parent);
         }
         // Component class not found.
         // Convert the tag to a MacroInstance component instance that will attempt to load a macro with the same
         // name as the tag name.
         if (is_null($props)) {
             $props = [];
         }
         $props['macro'] = $tagName;
         $component = new MacroCall();
     } else {
         $component = $this->injector->make($class);
     }
     // For both types of components:
     if (!$component instanceof Component) {
         throw new ComponentException(null, sprintf("Class <kbd>%s</kbd> is not a subclass of <kbd>Component</kbd>", get_class($component)));
     }
     $component->setTagName($tagName);
     return $component->setup($parent, $this, $props, $bindings);
 }