public static function dispatch()
    {
        $vars = [];

        $request = Request::createFromGlobals();

        $dispatcher = new Dispatcher(static::instance()->getData());
        $routeInfo = $dispatcher->dispatch(
            $request->getMethod(),
            $request->getUri()->getPath()
        );

        $controller = "\\Barebone\\Controller";
        $action = "index";

        switch ($routeInfo[0]) {
        case Dispatcher::NOT_FOUND:
            $action = 'routerError';
            $vars['error'] = static::ERR_NOT_FOUND;
            $vars['subject'] = $request->getUri()->getPath();
            break;

        case Dispatcher::METHOD_NOT_ALLOWED:
            $action = 'routerError';
            $vars['error'] = static::ERR_BAD_METHOD;
            $vars['subject'] = $routeInfo[1];
            break;

        case Dispatcher::FOUND:
            $handler = $routeInfo[1];
            $vars = $routeInfo[2];

            if (!class_exists($handler[0])) {
                $action = 'routerError';
                $vars['error'] = static::ERR_MISSING_CONTROLLER;
                $vars['subject'] = $handler[0];
            } elseif (!method_exists($handler[0], $handler[1])) {
                $action = 'routerError';
                $vars['error'] = static::ERR_MISSING_ACTION;
                $vars['subject'] = $handler[0] . '::' . $handler[1];
            } else {
                $controller = $handler[0];
                $action = $handler[1];
            }
            break;
        }

        // Start with an empty response
        $response = new Response();
        $request->setAction($action);

        // @var Controller $instance
        $instance = new $controller($request, $response);
        $instance->initController();

        // Get Middleware stacks
        $before = $instance->getMiddlewareBefore();
        $after = $instance->getMiddlewareAfter();

        // Append the action call to the middleware stack
        $before[] = function (Request $request, Response $response,
            callable $next = null
        ) use ($instance, $action, $vars) {

            // assigned updated objects
            $instance->setRequest($request);
            $instance->setResponse($response);

            // get updated response from action
            $response = call_user_func_array([$instance, $action], $vars);

            // continue
            return $next($instance->getRequest(), $response);
        };

        // Run the middleware stack and return the Response
        $middlewares = array_reverse(array_merge($before, $after));
        $runner = \Sirius\Middleware\Runner::factory($middlewares);

        return $runner($request, $response);
    }