Updated the auto URI detection so that it works in more scenarios.  Fixes #3
diff --git a/system/core/URI.php b/system/core/URI.php
index 769dacd..9d28d89 100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -61,13 +61,6 @@
 	{
 		if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
 		{
-			// Let's try the REQUEST_URI first, this will work in most situations
-			if ($uri = $this->_get_request_uri())
-			{
-				$this->uri_string = $this->_parse_request_uri($uri);
-				return;
-			}
-
 			// Arguments exist, it must be a command line request
 			if ( ! empty($_SERVER['argv']))
 			{
@@ -75,6 +68,13 @@
 				return;
 			}
 
+			// Let's try the REQUEST_URI first, this will work in most situations
+			if ($uri = $this->_detect_uri())
+			{
+				$this->uri_string = $uri;
+				return;
+			}
+
 			// Is there a PATH_INFO variable?
 			// Note: some servers seem to have trouble with getenv() so we'll test it two ways
 			$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
@@ -108,7 +108,7 @@
 
 			if ($uri == 'REQUEST_URI')
 			{
-				$this->uri_string = $this->_parse_request_uri($this->_get_request_uri());
+				$this->uri_string = $this->_detect_uri();
 				return;
 			}
 			elseif ($uri == 'CLI')
@@ -130,99 +130,53 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Get REQUEST_URI
+	 * Detects the URI
 	 *
-	 * Retrieves the REQUEST_URI, or equivelent for IIS.
+	 * This function will detect the URI automatically and fix the query string
+	 * if necessary.
 	 *
 	 * @access	private
 	 * @return	string
 	 */
-	function _get_request_uri()
+	private function _detect_uri()
 	{
-		$uri = FALSE;
-
-		// Let's check for standard servers first
-		if (isset($_SERVER['REQUEST_URI']))
+		if ( ! isset($_SERVER['REQUEST_URI']))
 		{
-			$uri = $_SERVER['REQUEST_URI'];
-			if (strpos($uri, $_SERVER['SERVER_NAME']) !== FALSE)
-			{
-				$uri = preg_replace('/^\w+:\/\/[^\/]+/', '', $uri);
-			}
+			return '';
 		}
 
-		// Now lets check for IIS
-		elseif (isset($_SERVER['HTTP_X_REWRITE_URL']))
+		$uri = $_SERVER['REQUEST_URI'];
+		if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
 		{
-			$uri = $_SERVER['HTTP_X_REWRITE_URL'];
+			$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
+		}
+		elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
+		{
+			$uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
 		}
 
-		// Last ditch effort (for older CGI servers, like IIS 5)
-		elseif (isset($_SERVER['ORIG_PATH_INFO']))
+		// This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
+		// URI is found, and also fixes the QUERY_STRING server var and $_GET array.
+		if (strncmp($uri, '?/', 2) === 0)
 		{
-			$uri = $_SERVER['ORIG_PATH_INFO'];
-			if ( ! empty($_SERVER['QUERY_STRING']))
-			{
-				$uri .= '?' . $_SERVER['QUERY_STRING'];
-			}
+			$uri = substr($uri, 2);
 		}
-
-		return $uri;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Parse REQUEST_URI
-	 *
-	 * Due to the way REQUEST_URI works it usually contains path info
-	 * that makes it unusable as URI data.  We'll trim off the unnecessary
-	 * data, hopefully arriving at a valid URI that we can use.
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	private function _parse_request_uri($uri)
-	{
-		// Some server's require URL's like index.php?/whatever If that is the case,
-		// then we need to add that to our parsing.
-		$fc_path = ltrim(FCPATH . SELF, '/');
-		if (strpos($uri, SELF . '?') !== FALSE)
+		$parts = preg_split('#\?#i', $uri, 2);
+		$uri = $parts[0];
+		if (isset($parts[1]))
 		{
-			$fc_path .= '?';
-		}
-
-		$parsed_uri = explode('/', ltrim($uri, '/'));
-
-		$i = 0;
-		foreach (explode("/", $fc_path) as $segment)
-		{
-			if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i])
-			{
-				$i++;
-			}
-		}
-
-		$uri = implode("/", array_slice($parsed_uri, $i));
-
-		// Let's take off any query string and re-assign $_SERVER['QUERY_STRING'] and $_GET.
-		// This is only needed on some servers.  However, we are forced to use it to accomodate
-		// them.
-		if (($qs_pos = strpos($uri, '?')) !== FALSE)
-		{
-			$_SERVER['QUERY_STRING'] = substr($uri, $qs_pos + 1);
+			$_SERVER['QUERY_STRING'] = $parts[1];
 			parse_str($_SERVER['QUERY_STRING'], $_GET);
-			$uri = substr($uri, 0, $qs_pos);
 		}
-
-		// If it is just a / or index.php then just empty it.
-		if ($uri == '/' OR $uri == SELF)
+		else
 		{
-			$uri = '';
+			$_SERVER['QUERY_STRING'] = '';
+			$_GET = array();
 		}
+		$uri = parse_url($uri, PHP_URL_PATH);
 
-		return $uri;
+		// Do some final cleaning of the URI and return it
+		return str_replace(array('//', '../'), '/', trim($uri, '/'));
 	}
 
 	// --------------------------------------------------------------------