public function dispatch(RouteInfo $routeInfo)
    {
        $this->setRouteInfo($routeInfo);
        $method = $this->_routeInfo->getAction();
        $controller = $this->getController($method);
        $inspector = new Inspector($controller);
        $methodExists = $inspector->hasMethod($method);

        if (
            !$methodExists ||
            $inspector->getMethodAnnotations($method)
                ->hasAnnotation('@private') ||
            $inspector->getMethodAnnotations($method)
                ->hasAnnotation('@protected')
        ) {
            throw new Exception\ActionNotFoundException(
                "Action '{$method}' not found"
            );
        }
        $methodMeta = $inspector->getMethodAnnotations($method);


        /**
         * @param Inspector\AnnotationsList $meta
         * @param string $type
         */
        $hooks = function ($meta, $type) use ($inspector, $controller) {
            static $run;
            if (is_null($run)) {
                $run = array();
            }

            if ($meta->hasAnnotation($type)) {
                $methods = $meta->getAnnotation($type)->getValue();
                if (is_string($methods)) {
                    $methods = explode(
                        ', ',
                        $meta->getAnnotation($type)->getParameter('_raw')
                    );
                }
                foreach ($methods as $method) {
                    $hookMeta = $inspector->getMethodAnnotations($method);
                    if (
                        in_array($method, $run) &&
                        $hookMeta->hasAnnotation('@once')
                    ) {
                        continue;
                    }
                    $run[] = $method;
                    $controller->$method();
                }

            }
        };

        $hooks($methodMeta, "@before");
        $arguments = is_array($this->_routeInfo->getArguments()) ?
            $this->_routeInfo->getArguments() : [];

        $controller->arguments = $arguments;
        $filterEvent = new Filter(
            [
                'controller' => $controller,
                'routeInfo' => $this->_routeInfo
            ],
            'FilterEvent'
        );
        $this->_application->getEventManager()
            ->trigger(Filter::BEFORE_FILTER, $this, $filterEvent);

        call_user_func_array(
            array(
                $filterEvent->controller,
                $method
            ),
            $arguments
        );


        $hooks($methodMeta, "@after");
        $this->_application->getEventManager()
            ->trigger(Filter::AFTER_FILTER, $this, $filterEvent);

        $this->_controller = $controller;

        return $this->_render();
    }