protected function unmarshall(DOMElement $element, QtiComponent $rootComponent = null)
    {
        // Reset.
        $this->resetTrail();
        $this->resetFinal();
        $this->resetMark();
        $this->resetProcessed();

        $this->pushTrail($element);

        // Begin the traversing of the n-ary tree... as a graph!
        while ($this->countTrail() > 0) {
            $node = $this->popTrail();

            if (!$node instanceof QtiComponent && !$this->isMarked($node) && !$this->isElementFinal($node)) {
                // Hierarchical node, first pass.
                $this->mark($node);
                $this->pushTrail($node); // repush for a second pass.
                $children = array_reverse($this->getChildrenElements($node)); // further exploration.

                foreach ($children as $c) {
                    $this->pushTrail($c);
                }
            } elseif ($this->isMarked($node)) {
                // Hierarchical node, second pass.

                // Push the result on the trail.
                $finals = $this->emptyFinal(count($this->getChildrenElements($node)));
                $componentCollection = $this->createCollection($node);
                foreach ($finals as $f) {
                    $componentCollection[] = $f;
                }

                $marshaller = $this->getMarshallerFactory()->createMarshaller($node);

                // Root node?
                if ($node === $element && !empty($rootComponent)) {
                    $component = $marshaller->unmarshallChildrenKnown($node, $componentCollection, $rootComponent);
                } else {
                    if ($marshaller instanceof RecursiveMarshaller) {
                        $component = $marshaller->unmarshallChildrenKnown($node, $componentCollection);
                    } else {
                        $component = $marshaller->unmarshall($node);
                    }
                }

                $this->pushProcessed($component);

                // Root node ?
                if ($node === $element) {
                    // Second pass on the root element, we can return.
                    return $component;
                } else {
                    $this->pushTrail($component);
                }
            } else {
                // Leaf node.
                if ($node instanceof QtiComponent) {
                    $this->pushFinal($node);
                } else {

                    if ($node instanceof DOMText) {
                        $node = self::getDOMCradle()->createElement('textRun', preg_replace('/&(?!\w+;)/', '&amp;', $node->wholeText));
                    }

                    // Process it and make its a final element to be used by hierarchical nodes.
                    $marshaller = $this->getMarshallerFactory()->createMarshaller($node);
                    $processed = $marshaller->unmarshall($node);
                    $this->pushFinal($processed);
                    $this->pushProcessed($processed);
                }
            }
        }
    }