public function execute(Request $request)
    {

        $phases = ['prepare', 'respond', 'close'];
        $response = null;

        foreach ($phases as $phase) {

            $key = 0;

            if ($phase === 'respond' && is_null($response)) {
                throw new StackException;
            } else if ($phase === 'close' && $key === 0) {
                $response->send();
            }

            if ($phase === 'prepare' && count($this->{$phase . 'ableMiddlewares'}) === 0) {
                throw new StackException('You must at least add one prepareableMiddleware that generates a Response.');
            } else if (count($this->{$phase . 'ableMiddlewares'}) === 0) {
                continue;
            }

            $next_middleware_spec = $this->{$phase . 'ableMiddlewares'}[$key];

            //Use a while so that middlewares can add other middlewares to execute
            while ($next_middleware_spec) {
                //Get the middleware
                $middleware = array_shift($next_middleware_spec);

                if (!is_null($response)) {
                    array_unshift($next_middleware_spec, $response);
                }

                //Put request as first parameter for the middleware
                array_unshift($next_middleware_spec, $request);

                $return = call_user_func_array([$middleware, $phase], $next_middleware_spec);

                if ($phase === 'prepare' && $return instanceof Response) {
                    $response = $return;
                    break;
                } else if ($phase === 'respond') {
                    //Reassign response in case it was recreated during that phase
                    $response = $return;
                }
                $key++;
                $next_middleware_spec = isset($this->{$phase . 'ableMiddlewares'}[$key]) ? $this->{$phase . 'ableMiddlewares'}[$key] : false;
            }
        }
    }