/**
  * @param Configuration $config
  * @param Request       $request
  */
 public function __construct(Configuration $config, Request $request)
 {
     $this->request = $request;
     $container = $config->get('routes', []);
     if (!$container) {
         throw new \InvalidArgumentException('Routes must be defined in the configuration');
     }
     if ($config->get('cache.config.enabled', FALSE)) {
         $cachePath = $config->getApplicationPath() . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'router';
         if (file_exists($cachePath)) {
             $oldRouter = unserialize(file_get_contents($cachePath));
             foreach ($oldRouter as $prop => $value) {
                 $this->{$prop} = $value;
             }
             return;
         }
     }
     parent::__construct(new RouteCollection(new RouteFactory('Arhitect\\Router\\Adapter\\RouteAdapter')), new Generator());
     foreach ($container as $routeName => $details) {
         if (isset($details['middlewares'])) {
             if (is_array($details['middlewares'])) {
                 $this->middlewares[$routeName] = $details['middlewares'];
             }
         }
         if (isset($details['extends']) && FALSE != $details['extends']) {
             $path = [$routeName];
             $parent = isset($container[$details['extends']]) ? $container[$details['extends']] : NULL;
             $parentName = isset($container[$details['extends']]) ? $details['extends'] : NULL;
             while ($parent) {
                 $path[] = $parentName;
                 if (isset($parent['extends'])) {
                     $parentName = $parent['extends'];
                     $parent = $container[$parent['extends']];
                 } else {
                     $parent = NULL;
                 }
             }
             $call = [];
             $that = $this;
             foreach ($path as $offset => $item) {
                 if (!$call) {
                     $call[$item] = function ($router) use($that, $container, $item) {
                         /** @var Route $route */
                         $route = $router->add($item, $container[$item]['path']);
                         $container[$item]['path'] = $route->path;
                         $tmp = $that->addRoute($route->name, $container[$item]);
                         $router->offsetSet($route->name, $tmp);
                     };
                     continue;
                 }
                 if ($offset == count($path) - 1) {
                     break;
                 }
                 $call[$item] = function ($router) use($container, $item, $call, $offset, $path) {
                     $router->attach($item, $container[$item]['path'], $call[$path[$offset - 1]]);
                 };
             }
             $this->attach($path[$offset], $container[$path[$offset]]['path'], $call[$path[$offset - 1]]);
             continue;
         }
         if (!$this->offsetExists($routeName)) {
             $this->offsetSet($routeName, $this->addRoute($routeName, $details));
         }
     }
     if ($config->get('cache.config.enabled', FALSE)) {
         file_put_contents($cachePath, serialize($this));
     }
 }