public function call()
    {
        if (empty($this->options)) {
            $this->options = $this->app->config('bono.controllers');
        }

        if (empty($this->options['mapping'])) {
            return $this->next->call();
        }

        $mapping = $this->options['mapping'];

        $resourceUri = $this->app->request->getResourceUri();
        if ($mapping) {
            foreach ($mapping as $uri => $Map) {
                if (is_int($uri)) {
                    $uri = $Map;
                    $Map = null;
                }

                $matcher = preg_replace('/:\w+/', '(\w+)', '/^'.addcslashes($uri, '\/').'(?:\/.*)*$/');
                $matches = '';
                $isMatch = preg_match($matcher, $resourceUri, $matches);

                if ($isMatch)  {
                    if (is_null($Map)) {
                        if (isset($this->options['default'])) {
                            $Map = $this->options['default'];
                        } else {
                            throw new \Exception('URI "'.$uri.'" does not have suitable controller class "'.$Map.'"');
                        }
                    }
                    $this->app->controller = $controller = new $Map($this->app, $uri);
                    if (!($controller instanceof \Bono\Controller\Controller)) {
                        throw new \Exception(
                            'Controller "'.$Map.'" should be instance of Bono\Controller\Controller.'
                        );
                    }
                    break;
                }
            }
        }

        $this->next->call();
    }