public function nestedList(array $data, string $content, int $level = 0, array $isActiveCallback = null): string
    {
        $tabs = "\n" . str_repeat('	', $level * 2);
        $liTabs = $tabs . '	';

        $output = $tabs . '<ul>';
        foreach ($data as $record) {
            $liClasses = [];
            $liContent = $content;
            if ($isActiveCallback !== null) {
                $additionalArguments = !empty($isActiveCallback['arguments']) ? $isActiveCallback['arguments'] : [];
                $isActive = call_user_func_array($isActiveCallback['callback'], [&$record, $additionalArguments]);
                if ($isActive) {
                    $liClasses[] = 'active';
                }
            }

            // find the model variables
            preg_match_all("/\{\{([a-z0-9\._]+)\}\}/i", $liContent, $matches);
            if (!empty($matches)) {
                $variables = array_unique($matches[1]);
                foreach ($variables as $modelField) {
                    $liContent = str_replace('{{' . $modelField . '}}', $record[$modelField], $liContent);
                }
            }
            if (!empty($record['children'])) {
                $liClasses[] = 'has-children';
            }

            $output .= $liTabs . '<li class="' . implode(' ', $liClasses) . '">' . $liContent;
            if (isset($record['children'][0])) {
                $output .= $this->nestedList($record['children'], $content, $level + 1, $isActiveCallback);
                $output .= $liTabs . '</li>';
            } else {
                $output .= '</li>';
            }
        }
        $output .= $tabs . '</ul>';

        return $output;
    }