protected function encapsulate()
    {
        $this->encapsulated = true;
        $args = func_get_args();
        $function = array_shift($args);

        $content = '';

        ob_start(
            function ($buffer) use (&$content) {
                $content .= $buffer;

                return '';
            }
        );

        $level = ob_get_level();

        $applicationClosed = null;

        $statusCodeBefore = http_response_code();

        $this->encapsulatedException = null;

        try {
            call_user_func_array($function, $args);
        } catch (ApplicationClosedException $e) {
            // nothing
        } catch (\Exception $e) {
            $this->encapsulatedException = $e;
        }

        $this->restoreBufferLevel($level);
        ob_end_clean();

        $newStatusCode = http_response_code();

        $this->response->setStatusCode($newStatusCode);

        if ($statusCodeBefore != $newStatusCode) {
            http_response_code($statusCodeBefore);
        }

        $headers = $this->cleanHeaders();

        foreach ($headers as $name => $value) {
            $this->response->headers->set($name, $value);
        }

        $this->encapsulated = false;

        if ($this->encapsulatedException != null) {
            throw new JoomlaRequestException(
                "Encapsulated request to joomla failed",
                0,
                $this->encapsulatedException
            );
        }

        return $content;
    }