private function runRequest($method, $url, $content, $extraHeaders, $cache, $blocking, $options)
    {
        $deferred = new Deferred();

        $key = 'guzzle.'.sha1($url);
        if ($method === 'get' && $this->cache->has($key)) {
            $deferred->resolve($this->cache->get($key));

            return $deferred->promise();
        }

        $headers = [
            'User-Agent' => $this->getUserAgent(),
        ];

        $headers['authorization'] = $this->token;

        $headers = array_merge($headers, $extraHeaders);

        if (! is_null($content)) {
            $headers['Content-Type']   = 'application/json';
            $content                   = json_encode($content);
            $headers['Content-Length'] = strlen($content);
        }

        if ($blocking) {
            $response = $this->driver->blocking($method, $url, $headers, $content);

            return json_decode($response->getBody());
        }

        $this->driver->runRequest($method, $url, $headers, $content, $options)->then(
            function ($response) use ($method, $cache, $key, $deferred) {
                $json = json_decode($response->getBody());

                if ($method === 'get' && $cache !== false) {
                    $this->cache->set($key, $json, $cache === null ? static::CACHE_TTL : (int) $cache);
                }

                $deferred->resolve($json);
            },
            function ($e) use ($deferred, $url) {
                if (! ($e instanceof \Exception)) {
                    if (is_callable([$e, 'getStatusCode'])) {
                        $e = $this->handleError(
                            $e->getStatusCode(),
                            $e->getReasonPhrase(),
                            $e->getBody(),
                            $url
                        );
                    } else {
                        $e = $this->handleError(
                            0,
                            'unknown',
                            'unknown',
                            $url
                        );
                    }
                }

                $deferred->reject($e);
            },
            function ($content) use ($deferred) {
                $deferred->notify($content);
            }
        );

        return $deferred->promise();
    }