public function request($method, $url, $body = [], $query = [], $headers = [])
    {
        list($body, $query, $headers) = $this->setupVariables($body, $query, $headers);

        if (!empty($body)) {
            $body = encode($body);
            $headers['Content-Type'] = 'application/json';
        } else {
            $body = null;
        }

        $headers = array_merge($this->global_headers, $headers);

        try {
            $response = $this->client->request($method, $url, [
                'query'   => $query,
                'body'    => $body,
                'headers' => $headers,
            ]);
            $response_body = (string) $response->getBody();
        } catch (BadResponseException $exception) {
            self::handleError($exception);
        }

        switch ($this->mode) {
            case -1:
                return $response;
            case 0:
                return $response_body;
            case 1:
                if (!empty($response_body)) {
                    return decode($response_body);
                }

                return;
            case 2:
                if (!empty($response_body)) {
                    return CollectionManager::build(decode($response_body));
                }

                return;
            default:
                throw new JSONLibraryException('unknown_mode_set');
        }
    }