public function parse_callback($response, $headers = null)
	{
		// Shorten this so we have a (mostly) single code path
		if (isset($response->body))
		{
			if (is_string($response->body))
			{
				$body = $response->body;
			}
			else
			{
				return $response;
			}
		}
		elseif (is_string($response))
		{
			$body = $response;
		}
		else
		{
			return $response;
		}

		// Decompress gzipped content
		if (isset($headers['content-encoding']))
		{
			switch (strtolower(trim($headers['content-encoding'], "\x09\x0A\x0D\x20")))
			{
				case 'gzip':
				case 'x-gzip':
					if (strpos($headers['_info']['url'], 'monitoring.') !== false)
					{
						// CloudWatch incorrectly uses the deflate algorithm when they say gzip.
						if (($uncompressed = gzuncompress($body)) !== false)
						{
							$body = $uncompressed;
						}
						elseif (($uncompressed = gzinflate($body)) !== false)
						{
							$body = $uncompressed;
						}
						break;
					}
					else
					{
						// Everyone else uses gzip correctly.
						$decoder = new CFGzipDecode($body);
						if ($decoder->parse())
						{
							$body = $decoder->data;
						}
						break;
					}

				case 'deflate':
					if (strpos($headers['_info']['url'], 'monitoring.') !== false)
					{
						// CloudWatch incorrectly does nothing when they say deflate.
						continue;
					}
					else
					{
						// Everyone else uses deflate correctly.
						if (($uncompressed = gzuncompress($body)) !== false)
						{
							$body = $uncompressed;
						}
						elseif (($uncompressed = gzinflate($body)) !== false)
						{
							$body = $uncompressed;
						}
					}
					break;
			}
		}

		// Look for XML cues
		if (
			(isset($headers['content-type']) && ($headers['content-type'] === 'text/xml' || $headers['content-type'] === 'application/xml')) || // We know it's XML
			(!isset($headers['content-type']) && (stripos($body, '<?xml') === 0 || strpos($body, '<Error>') === 0) || preg_match('/^<(\w*) xmlns="http(s?):\/\/(\w*).amazon(aws)?.com/im', $body)) // Sniff for XML
		)
		{
			// Strip the default XML namespace to simplify XPath expressions
			$body = str_replace("xmlns=", "ns=", $body);

			// Parse the XML body
			$body = new $this->parser_class($body);
		}
		// Look for JSON cues
		elseif (
			(isset($headers['content-type']) && $headers['content-type'] === 'application/json') || // We know it's JSON
			(!isset($headers['content-type']) && $this->util->is_json($body)) // Sniff for JSON
		)
		{
			// Normalize JSON to a CFSimpleXML object
			$body = CFJSON::to_xml($body);
		}

		// Put the parsed data back where it goes
		if (isset($response->body))
		{
			$response->body = $body;
		}
		else
		{
			$response = $body;
		}

		return $response;
	}