public static function request($url, $headers = array(), $data = array(), $type = self::GET, $options = array()) {
		if (!preg_match('/^http(s)?:\/\//i', $url)) {
			throw new Requests_Exception('Only HTTP requests are handled.', 'nonhttp', $url);
		}
		$defaults = array(
			'timeout' => 10,
			'useragent' => 'php-requests/' . self::VERSION,
			'redirected' => 0,
			'redirects' => 10,
			'follow_redirects' => true,
			'blocking' => true,
			'type' => $type,
			'filename' => false,
			'auth' => false,
			'idn' => true,
			'hooks' => null,
			'transport' => null,
		);
		$options = array_merge($defaults, $options);

		if (empty($options['hooks'])) {
			$options['hooks'] = new Requests_Hooks();
		}

		// Special case for simple basic auth
		if (is_array($options['auth'])) {
			$options['auth'] = new Requests_Auth_Basic($options['auth']);
		}
		if ($options['auth'] !== false) {
			$options['auth']->register($options['hooks']);
		}

		$options['hooks']->dispatch('requests.before_request', array(&$url, &$headers, &$data, &$type, &$options));

		if ($options['idn'] !== false) {
			$iri = new Requests_IRI($url);
			$iri->host = Requests_IDNAEncoder::encode($iri->ihost);
			$url = $iri->uri;
		}

		if (!empty($options['transport'])) {
			$transport = $options['transport'];

			if (is_string($options['transport'])) {
				$transport = new $transport();
			}
		}
		else {
			$transport = self::get_transport();
		}
		$response = $transport->request($url, $headers, $data, $options);

		$options['hooks']->dispatch('requests.before_parse', array(&$response, $url, $headers, $data, $type, $options));

		return self::parse_response($response, $url, $headers, $data, $options);
	}