public function headers($key = null, $value = null, $replace = true) {
		if ($key === null && $value === null) {
			$headers = [];

			foreach ($this->headers as $key => $value) {
				if (is_scalar($value)) {
					$headers[] = "{$key}: {$value}";
					continue;
				}
				foreach ($value as $val) {
					$headers[] = "{$key}: {$val}";
				}
			}
			return $headers;
		}
		if ($value === null && is_string($key) && strpos($key, ':') === false) {
			return isset($this->headers[$key]) ? $this->headers[$key] : null;
		}

		if (is_string($key)) {
			if (strpos($key, ':') !== false && preg_match('/(.*?):(.+)/', $key, $match)) {
				$key = $match[1];
				$value = trim($match[2]);
			} elseif ($value === false) {
				unset($this->headers[$key]);
				return;
			}
			if ($replace || !isset($this->headers[$key])) {
				$this->headers[$key] = $value;
			} elseif ($value !== $this->headers[$key]) {
				$this->headers[$key] = (array) $this->headers[$key];

				if (is_string($value)) {
					$this->headers[$key][] = $value;
				} else {
					$this->headers[$key] = array_merge($this->headers[$key], $value);
				}
			}
		} else {
			$replace = ($value === false) ? $value : $replace;

			foreach ((array) $key as $header => $value) {
				if (is_string($header)) {
					$this->headers($header, $value, $replace);
					continue;
				}
				$this->headers($value, null, $replace);
			}
		}
	}