private function prepareRouterData()
    {
        $routers = [];
        $reverse = [];
        $path = Application::getInstance()->getPath() . '/modules/*/controllers/*.php';
        foreach (new \GlobIterator($path) as $file) {
            /* @var \SplFileInfo $file */
            $module = $file->getPathInfo()->getPathInfo()->getBasename();
            $controller = $file->getBasename('.php');
            $controllerInstance = new Controller($module, $controller);
            $meta = $controllerInstance->getMeta();
            if ($routes = $meta->getRoute()) {
                foreach ($routes as $route => $pattern) {
                    if (!isset($reverse[$module])) {
                        $reverse[$module] = [];
                    }

                    $reverse[$module][$controller] = ['route' => $route, 'params' => $meta->getParams()];

                    $rule = [
                        $route => [
                            'pattern' => $pattern,
                            'module' => $module,
                            'controller' => $controller,
                            'params' => $meta->getParams()
                        ]
                    ];

                    // static routers should be first, than routes with variables `$...`
                    // all routes begin with slash `/`
                    if (strpos($route, '$')) {
                        $routers[] = $rule;
                    } else {
                        array_unshift($routers, $rule);
                    }
                }
            }
        }
        $routers = array_merge(...$routers);
        return [$routers, $reverse];
    }