protected function invoke($method, array $params = [])
    {
        $qualifiedClassName = get_class($this);

        if (false !== $pos = strrpos($qualifiedClassName, '\\')) {
            $methodRef = substr($qualifiedClassName, $pos + 1) . ':' . $method;
        } else {
            $methodRef = $qualifiedClassName . ':' . $method;
        }

        $invoker = $this->user->getInvoker();

        return $invoker(function () use ($methodRef, $method, $params) {
            $this->dispatcher->dispatch(
                Events::BEFORE_REQUEST,
                new PreCallEvent($methodRef, $params, $this->user)
            );

            try {
                $response = $this->__soapCall($method, $params);
            } catch (\Exception $ex) {
                if ($ex instanceof \SoapFault) {
                    if (strtolower($ex->faultcode) === 'http') {
                        $ex = new NetworkException($ex->getMessage(), 0, $ex);
                    } else {
                        $ex = $this->handleFault($ex, $methodRef, $params);
                    }
                }

                $this->dispatcher->dispatch(
                    Events::FAIL_REQUEST,
                    new FailCallEvent($methodRef, $params, $this->user, $this, $ex, $this->fetchUtits())
                );

                throw $ex;
            }

            $this->dispatcher->dispatch(
                Events::AFTER_REQUEST,
                new PostCallEvent($methodRef, $params, $this->user, $this, $response, $this->fetchUtits())
            );

            return $response;
        });
    }