public function invokeMethod(RequestInterface $request, ResponseInterface $response, $sendResponse = true)
    {
        $method = $request->getMethod();

        if (!$this->emit('beforeMethod:'.$method, [$request, $response])) {
            return;
        }

        if (self::$exposeVersion) {
            $response->setHeader('X-Sabre-Version', Version::VERSION);
        }

        $this->transactionType = strtolower($method);

        if (!$this->checkPreconditions($request, $response)) {
            $this->sapi->sendResponse($response);

            return;
        }

        if ($this->emit('method:'.$method, [$request, $response])) {
            $exMessage = 'There was no plugin in the system that was willing to handle this '.$method.' method.';
            if ('GET' === $method) {
                $exMessage .= ' Enable the Browser plugin to get a better result here.';
            }

            // Unsupported method
            throw new Exception\NotImplemented($exMessage);
        }

        if (!$this->emit('afterMethod:'.$method, [$request, $response])) {
            return;
        }

        if (null === $response->getStatus()) {
            throw new Exception('No subsystem set a valid HTTP status code. Something must have interrupted the request without providing further detail.');
        }
        if ($sendResponse) {
            $this->sapi->sendResponse($response);
            $this->emit('afterResponse', [$request, $response]);
        }
    }