Fix a directory/404_override bug and some routing-related optimizations
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 633be7f..12747c5 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -267,9 +267,11 @@
 	{
 		if ( ! empty($RTR->routes['404_override']))
 		{
-			$x = explode('/', $RTR->routes['404_override'], 2);
-			$class = $x[0];
-			$method = isset($x[1]) ? $x[1] : 'index';
+			if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+			{
+				$method = 'index';
+			}
+
 			if ( ! class_exists($class))
 			{
 				if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
@@ -327,9 +329,11 @@
 			// Check and see if we are using a 404 override and use it.
 			if ( ! empty($RTR->routes['404_override']))
 			{
-				$x = explode('/', $RTR->routes['404_override'], 2);
-				$class = $x[0];
-				$method = isset($x[1]) ? $x[1] : 'index';
+				if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+				{
+					$method = 'index';
+				}
+
 				if ( ! class_exists($class))
 				{
 					if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
diff --git a/system/core/Router.php b/system/core/Router.php
index 48c157f..67e9b30 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -142,7 +142,7 @@
 			include(APPPATH.'config/routes.php');
 		}
 
-		$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
+		$this->routes = (isset($route) && is_array($route)) ? $route : array();
 		unset($route);
 
 		// Set the default controller so we can display it in the event
@@ -179,25 +179,20 @@
 	 */
 	protected function _set_default_controller()
 	{
-		if ($this->default_controller === FALSE)
+		if (empty($this->default_controller))
 		{
 			show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
 		}
 
 		// Is the method being specified?
-		if (strpos($this->default_controller, '/') !== FALSE)
+		if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
 		{
-			$x = explode('/', $this->default_controller);
-			$this->set_class($x[0]);
-			$this->set_method($x[1]);
-			$this->_set_request($x);
+			$method = 'index';
 		}
-		else
-		{
-			$this->set_class($this->default_controller);
-			$this->set_method('index');
-			$this->_set_request(array($this->default_controller, 'index'));
-		}
+
+		$this->set_class($class);
+		$this->set_method($method);
+		$this->_set_request(array($class, $method));
 
 		// re-index the routed segments array so it starts with 1 rather than 0
 		$this->uri->_reindex_segments();
@@ -227,17 +222,8 @@
 
 		$this->set_class($segments[0]);
 
-		if (isset($segments[1]))
-		{
-			// A standard method request
-			$this->set_method($segments[1]);
-		}
-		else
-		{
-			// This lets the "routed" segment array identify that the default
-			// index method is being used.
-			$segments[1] = 'index';
-		}
+		isset($segments[1]) OR $segments[1] = 'index';
+		$this->set_method($segments[1]);
 
 		// Update our "routed" segment array to contain the segments.
 		// Note: If there is no custom routing, this array will be
@@ -276,9 +262,7 @@
 		if (is_dir(APPPATH.'controllers/'.$segments[0]))
 		{
 			// Set the directory and remove it from the segment array
-			$this->set_directory($segments[0]);
-			$segments = array_slice($segments, 1);
-
+			$this->set_directory(array_shift($segments));
 			if (count($segments) > 0)
 			{
 				$segments[0] = str_replace('-', '_', $segments[0]);
@@ -289,12 +273,8 @@
 				{
 					if ( ! empty($this->routes['404_override']))
 					{
-						$x = explode('/', $this->routes['404_override']);
-						$this->set_directory('');
-						$this->set_class($x[0]);
-						$this->set_method(isset($x[1]) ? $x[1] : 'index');
-
-						return $x;
+						$this->directory = '';
+						return explode('/', $this->routes['404_override'], 2);
 					}
 					else
 					{
@@ -305,40 +285,26 @@
 			else
 			{
 				// Is the method being specified in the route?
-				if (strpos($this->default_controller, '/') !== FALSE)
-				{
-					$x = explode('/', $this->default_controller);
-					$this->set_class($x[0]);
-					$this->set_method($x[1]);
-				}
-				else
-				{
-					$this->set_class($this->default_controller);
-					$this->set_method('index');
-				}
-
-				// Does the default controller exist in the sub-folder?
-				if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.'.php'))
+				$segments = explode('/', $this->default_controller);
+				if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php'))
 				{
 					$this->directory = '';
-					return array();
 				}
-
 			}
 
 			return $segments;
 		}
 
-
 		// If we've gotten this far it means that the URI does not correlate to a valid
 		// controller class. We will now see if there is an override
 		if ( ! empty($this->routes['404_override']))
 		{
-			$x = explode('/', $this->routes['404_override']);
-			$this->set_class($x[0]);
-			$this->set_method(isset($x[1]) ? $x[1] : 'index');
+			if (sscanf($this->routes['404_override'], '%[^/]/%s', $class, $method) !== 2)
+			{
+				$method = 'index';
+			}
 
-			return $x;
+			return array($class, $method);
 		}
 
 		// Nothing else to do at this point but show a 404
@@ -533,7 +499,7 @@
 
 		if (isset($routing['function']))
 		{
-			$routing['function'] = ($routing['function'] == '') ? 'index' : $routing['function'];
+			$routing['function'] = empty($routing['function']) ? 'index' : $routing['function'];
 			$this->set_method($routing['function']);
 		}
 	}
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index a4af272..164c6ad 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -412,6 +412,7 @@
 -  Fixed a bug (#1938) - :doc:`Email Library <libraries/email>` removed multiple spaces inside a pre-formatted plain text message.
 -  Fixed a bug (#388, #705) - :doc:`URI Library <libraries/uri>` didn't apply URL-decoding to URI segments that it got from **REQUEST_URI** and/or **QUERY_STRING**.
 -  Fixed a bug (#122) - :doc:`URI Library <libraries/uri>` method ``ruri_string()`` didn't include a directory if one is used.
+-  Fixed a bug - :doc:`Routing Library <general/routing>` didn't properly handle *404_override* in a subdirectory when a method is also specified.
 
 Version 2.1.3
 =============