protected function parseTemplateRecursive(&$input, &$template)
    {
        if (!is_array($input) || empty($input)) {
            return;
        }

        while (true) {
            $tag = current($input);
            next($input);

            if ($tag === false) {
                break;
            }

            $firstChar = substr($tag, 0, 1);

            switch ($firstChar) {
                // is closing TAG
                case '/':
                    return substr($tag, 1);
                break;

                // is TAG
                case '$':

                    $tag = substr($tag, 1);

                    $full_tag = $this->regTag($tag);
                    $template[$full_tag] = '';  // empty value
                    $this->tags[$tag][] = &$template[$full_tag];

                    // eat next chunk
                    $chunk = current($input); next($input);
                    if ($chunk !== false && $chunk !== null) {
                        $template[] = $chunk;
                    }

                break;

                // recurse
                default:

                    $full_tag = $this->regTag($tag);

                    // next would be prefix
                    $prefix = current($input); next($input);
                    $template[$full_tag] = ($prefix === false || $prefix === null) ? [] : [$prefix];

                    $this->tags[$tag][] = &$template[$full_tag];

                    $this->parseTemplateRecursive($input, $template[$full_tag]);

                    $chunk = current($input); next($input);
                    if ($chunk !== false && !empty($chunk)) {
                        $template[] = $chunk;
                    }

                break;
            }
        }
    }