public function send() {
		
		$url = $this->url();

		// Set fields for post or put requests.
		$this->curl = curl_init();
		curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $this->method);
		if (in_array($this->method, ['POST', 'PUT'])) {
			$this->buildBody();
		} else {
			$this->header('Content-Type', null);
		}
		curl_setopt($this->curl, CURLOPT_URL, $url);
		curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);

		// Capture rate limit response headers.
		$rate_limit = [];
		curl_setopt($this->curl, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$rate_limit) {
			$parts = explode(':', trim($header), 2);
			if (isset($parts[1]) && preg_match('/^X-RateLimit-(.*)/', $parts[0], $match)) {
				$rate_limit[$match[1]] = (int) $parts[1];
			}
			return strlen($header);
		});

		// Set authorization.
		$access_token = $this->client->accessToken();
		if ($access_token === null) {
			$this->setBearerToken($this->client->id());
		} else {
			$this->setBearerToken($access_token);
		}

		// Add headers.
		$headers = [];
		foreach ($this->headers as $name => $value) {
			if ($value !== null) {
				$headers[] = $name . ': ' . $value;
			}
			curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
		}

		// Allow the client to access the request before it is sent.
		$before = $this->client->before();
		if (is_callable($before)) {
			$before($this);
		}

		// Get response,
		$body = @curl_exec($this->curl);

		// Allow the client to access the request after it is sent.
		$after = $this->client->after();
		if (is_callable($after)) {
			$after($this);
		}

		// Get status and error info before closing the handle.
		$http_status = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
		$error_code = curl_errno($this->curl);
		$error_message = curl_error($this->curl);
		@curl_close($this->curl);

		// Check for curl error.
		if ($error_code > 0) {
			throw new NetworkException($error_message, $error_code);
		}

		return new Response($body, $http_status, $rate_limit);
	}