Implemented GET string support from Dan Horrigan and modified it slightly. Also tweaked his regex_match changes.
diff --git a/application/config/autoload.php b/application/config/autoload.php
index 5e97408..90b1a80 100644
--- a/application/config/autoload.php
+++ b/application/config/autoload.php
@@ -18,16 +18,30 @@
 |
 | These are the things you can load automatically:
 |
-| 1. Libraries
-| 2. Helper files
-| 3. Custom config files
-| 4. Language files
-| 5. Models
+| 1. Packages
+| 2. Libraries
+| 3. Helper files
+| 4. Custom config files
+| 5. Language files
+| 6. Models
 |
 */
 
 /*
 | -------------------------------------------------------------------
+|  Auto-load Packges
+| -------------------------------------------------------------------
+| Prototype:
+|
+|  $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
+|
+*/
+
+$autoload['packages'] = array(APPPATH.'third_party');
+
+
+/*
+| -------------------------------------------------------------------
 |  Auto-load Libraries
 | -------------------------------------------------------------------
 | These are the classes located in the system/libraries folder
@@ -98,6 +112,5 @@
 $autoload['model'] = array();
 
 
-
 /* End of file autoload.php */
 /* Location: ./application/config/autoload.php */
\ No newline at end of file
diff --git a/application/config/config.php b/application/config/config.php
index 477d7bf..a844f71 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -10,8 +10,11 @@
 |
 |	http://example.com/
 |
+| If this is not set then CodeIgniter will guess the protocol, domain and
+| path to your installation.
+|
 */
-$config['base_url']	= "http://example.com/";
+$config['base_url']	= '';
 
 /*
 |--------------------------------------------------------------------------
@@ -23,7 +26,7 @@
 | variable so that it is blank.
 |
 */
-$config['index_page'] = "index.php";
+$config['index_page'] = 'index.php';
 
 /*
 |--------------------------------------------------------------------------
@@ -31,7 +34,7 @@
 |--------------------------------------------------------------------------
 |
 | This item determines which server global should be used to retrieve the
-| URI string.  The default setting of "AUTO" works for most servers.
+| URI string.  The default setting of 'AUTO' works for most servers.
 | If your links do not seem to work, try one of the other delicious flavors:
 |
 | 'AUTO'			Default - auto detects
@@ -41,7 +44,7 @@
 | 'ORIG_PATH_INFO'	Uses the ORIG_PATH_INFO
 |
 */
-$config['uri_protocol']	= "AUTO";
+$config['uri_protocol']	= 'AUTO';
 
 /*
 |--------------------------------------------------------------------------
@@ -54,7 +57,7 @@
 | http://codeigniter.com/user_guide/general/urls.html
 */
 
-$config['url_suffix'] = "";
+$config['url_suffix'] = '';
 
 /*
 |--------------------------------------------------------------------------
@@ -66,7 +69,7 @@
 | than english.
 |
 */
-$config['language']	= "english";
+$config['language']	= 'english';
 
 /*
 |--------------------------------------------------------------------------
@@ -77,14 +80,14 @@
 | that require a character set to be provided.
 |
 */
-$config['charset'] = "UTF-8";
+$config['charset'] = 'UTF-8';
 
 /*
 |--------------------------------------------------------------------------
 | Enable/Disable System Hooks
 |--------------------------------------------------------------------------
 |
-| If you would like to use the "hooks" feature you must enable it by
+| If you would like to use the 'hooks' feature you must enable it by
 | setting this variable to TRUE (boolean).  See the user guide for details.
 |
 */
@@ -142,7 +145,7 @@
 |
 | Options are: TRUE or FALSE (boolean)
 |
-| The other items let you set the query string "words" that will
+| The other items let you set the query string 'words' that will
 | invoke your controllers and its functions:
 | example.com/index.php?c=controller&m=function
 |
@@ -151,7 +154,7 @@
 | use segment based URLs.
 |
 */
-$config['allow_get_array'] = TRUE;
+$config['allow_get_array']		= TRUE;
 $config['enable_query_strings'] = FALSE;
 $config['controller_trigger']	= 'c';
 $config['function_trigger']		= 'm';
@@ -221,7 +224,7 @@
 | MUST set an encryption key.  See the user guide for info.
 |
 */
-$config['encryption_key'] = "";
+$config['encryption_key'] = '';
 
 /*
 |--------------------------------------------------------------------------
@@ -261,9 +264,9 @@
 | 'cookie_path'   =  Typically will be a forward slash
 |
 */
-$config['cookie_prefix']	= "";
-$config['cookie_domain']	= "";
-$config['cookie_path']		= "/";
+$config['cookie_prefix']	= '';
+$config['cookie_domain']	= '';
+$config['cookie_path']		= '/';
 
 /*
 |--------------------------------------------------------------------------
@@ -301,7 +304,7 @@
 | means you are prematurely outputting something to your browser. It could
 | even be a line of whitespace at the end of one of your scripts.  For
 | compression to work, nothing can be sent before the output buffer is called
-| by the output class.  Do not "echo" any values with compression enabled.
+| by the output class.  Do not 'echo' any values with compression enabled.
 |
 */
 $config['compress_output'] = FALSE;
@@ -311,9 +314,9 @@
 | Master Time Reference
 |--------------------------------------------------------------------------
 |
-| Options are "local" or "gmt".  This pref tells the system whether to use
-| your server's local time as the master "now" reference, or convert it to
-| GMT.  See the "date helper" page of the user guide for information
+| Options are 'local' or 'gmt'.  This pref tells the system whether to use
+| your server's local time as the master 'now' reference, or convert it to
+| GMT.  See the 'date helper' page of the user guide for information
 | regarding date handling.
 |
 */
diff --git a/application/config/routes.php b/application/config/routes.php
index 614462f..5f9a583 100644
--- a/application/config/routes.php
+++ b/application/config/routes.php
@@ -23,16 +23,23 @@
 | RESERVED ROUTES
 | -------------------------------------------------------------------------
 |
-| There is one reserved routes:
+| There area two reserved routes:
 |
 |	$route['default_controller'] = 'welcome';
 |
 | This route indicates which controller class should be loaded if the
 | URI contains no data. In the above example, the "welcome" class
 | would be loaded.
+|
+|	$route['404_override'] = 'errors/page_missing';
+|
+| This route will tell the Router what URI segments to use if those provided
+| in the URL cannot be matched to a valid route.
+|
 */
 
 $route['default_controller'] = "welcome";
+$route['404_override'] = '';
 
 
 /* End of file routes.php */
diff --git a/system/core/Config.php b/system/core/Config.php
index bdd1b83..8ecfba7 100644
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -47,6 +47,24 @@
 	{
 		$this->config =& get_config();
 		log_message('debug', "Config Class Initialized");
+
+		// Set the base_url automatically if none was provided
+		if ($this->config['base_url'] == '')
+		{
+			if(isset($_SERVER['HTTP_HOST']))
+			{
+				$base_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
+				$base_url .= '://'. $_SERVER['HTTP_HOST'];
+				$base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
+			}
+
+			else
+			{
+				$base_url = 'http://localhost/';
+			}
+
+			$this->set_item('base_url', $base_url);
+		}
 	}
 
 	// --------------------------------------------------------------------
@@ -185,14 +203,7 @@
 			return FALSE;
 		}
 
-		$pref = $this->config[$item];
-
-		if ($pref != '' && substr($pref, -1) != '/')
-		{
-			$pref .= '/';
-		}
-
-		return $pref;
+		return rtrim($this->config[$item], '/').'/';
 	}
 
 	// --------------------------------------------------------------------
@@ -208,14 +219,7 @@
 	{
 		if ($uri == '')
 		{
-			if ($this->item('base_url') == '')
-			{
-				return $this->item('index_page');
-			}
-			else
-			{
-				return $this->slash_item('base_url').$this->item('index_page');
-			}
+			return $this->slash_item('base_url').$this->item('index_page');
 		}
 
 		if ($this->item('enable_query_strings') == FALSE)
@@ -244,14 +248,7 @@
 				$uri = $str;
 			}
 
-			if ($this->item('base_url') == '')
-			{
-				return $this->item('index_page').'?'.$uri;
-			}
-			else
-			{
-				return $this->slash_item('base_url').$this->item('index_page').'?'.$uri;
-			}
+			return $this->slash_item('base_url').$this->item('index_page').'?'.$uri;
 		}
 	}
 
diff --git a/system/core/Input.php b/system/core/Input.php
index 4ddc402..eb2048e 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -49,9 +49,9 @@
 	{
 		log_message('debug', "Input Class Initialized");
 
-		$this->_allow_get_array	= (config_item('allow_get_array') === TRUE) ? TRUE : FALSE;
-		$this->_enable_xss		= (config_item('global_xss_filtering') === TRUE) ? TRUE : FALSE;
-		$this->_enable_csrf		= (config_item('csrf_protection') === TRUE) ? TRUE : FALSE;
+		$this->_allow_get_array	= (config_item('allow_get_array') === TRUE);
+		$this->_enable_xss		= (config_item('global_xss_filtering') === TRUE);
+		$this->_enable_csrf		= (config_item('csrf_protection') === TRUE);
 
 		// Do we need to load the security class?
 		if ($this->_enable_xss == TRUE OR $this->_enable_csrf == TRUE)
@@ -216,14 +216,7 @@
 		}
 		else
 		{
-			if ($expire > 0)
-			{
-				$expire = time() + $expire;
-			}
-			else
-			{
-				$expire = 0;
-			}
+			$expire = ($expire > 0) ? time() + $expire : 0;
 		}
 
 		setcookie($prefix.$name, $value, $expire, $path, $domain, 0);
@@ -492,7 +485,7 @@
 		}
 
 		// We strip slashes if magic quotes is on to keep things consistent
-		if (get_magic_quotes_gpc())
+		if (function_exists('get_magic_quotes_gpc') AND get_magic_quotes_gpc())
 		{
 			$str = stripslashes($str);
 		}
@@ -514,7 +507,7 @@
 		{
 			if (strpos($str, "\r") !== FALSE)
 			{
-				$str = str_replace(array("\r\n", "\r"), "\n", $str);
+				$str = str_replace(array("\r\n", "\r"), PHP_EOL, $str);
 			}
 		}
 
diff --git a/system/core/Lang.php b/system/core/Lang.php
index e7867b3..8ec1797 100644
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
@@ -78,17 +78,21 @@
 		{
 			include($alt_path.'language/'.$idiom.'/'.$langfile);
 		}
-		elseif (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile))
-		{
-			include(APPPATH.'language/'.$idiom.'/'.$langfile);
-		}
 		else
 		{
-			if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile))
+			$found = FALSE;
+
+			foreach (get_instance()->load->get_package_paths(TRUE) as $package_path)
 			{
-				include(BASEPATH.'language/'.$idiom.'/'.$langfile);
+				if (file_exists($package_path.'language/'.$idiom.'/'.$langfile))
+				{
+					include($package_path.'language/'.$idiom.'/'.$langfile);
+					$found = TRUE;
+					break;
+				}
 			}
-			else
+
+			if ($found !== TRUE)
 			{
 				show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
 			}
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 4b6b19e..136cae9 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -81,12 +81,12 @@
 		{
 			foreach($library as $read)
 			{
-				$this->library($read);	
+				$this->library($read);
 			}
-			
+
 			return;
 		}
-		
+
 		if ($library == '' OR isset($this->_base_classes[$library]))
 		{
 			return FALSE;
@@ -527,7 +527,7 @@
 	function add_package_path($path)
 	{
 		$path = rtrim($path, '/').'/';
-		
+
 		array_unshift($this->_ci_library_paths, $path);
 		array_unshift($this->_ci_model_paths, $path);
 		array_unshift($this->_ci_helper_paths, $path);
@@ -540,6 +540,22 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Get Package Paths
+	 *
+	 * Return a list of all package paths, by default it will ignore BASEPATH.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	void
+	 */
+	function get_package_paths($include_base = FALSE)
+	{
+		return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Remove Package Path
 	 *
 	 * Remove a path from the library, model, and helper path arrays if it exists
@@ -563,7 +579,7 @@
 		else
 		{
 			$path = rtrim($path, '/').'/';
-			
+
 			foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var)
 			{
 				if (($key = array_search($path, $this->{$var})) !== FALSE)
diff --git a/system/core/Router.php b/system/core/Router.php
index 9276800..79a8b4f 100644
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -270,19 +270,17 @@
 
 		// 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 (isset($this->routes['404_override']) AND $this->routes['404_override'] != '')
+		if (!empty($this->routes['404_override']))
 		{
-			if (strpos($this->routes['404_override'], '/') !== FALSE)
-			{
-				$x = explode('/', $this->routes['404_override']);
+			$x = explode('/', $this->routes['404_override']);
 
-				$this->set_class($x[0]);
-				$this->set_method($x[1]);
+			$this->set_class($x[0]);
+			$this->set_method(isset($x[1]) ? $x[1] : 'index');
 
-				return $x;
-			}
+			return $x;
 		}
 
+
 		// Nothing else to do at this point but show a 404
 		show_404($segments[0]);
 	}
diff --git a/system/core/URI.php b/system/core/URI.php
index f6487d3..047e3c9 100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -133,23 +133,25 @@
 		if (isset($_SERVER['REQUEST_URI']))
 		{
 			$uri = $_SERVER['REQUEST_URI'];
-			if (strpos($uri, $_SERVER['HTTP_HOST']) !== FALSE)
+			if (strpos($uri, $_SERVER['SERVER_NAME']) !== FALSE)
 			{
-				$uri = preg_replace('/^\w+:\/\/[^\/]+/','',$uri);
+				$uri = preg_replace('/^\w+:\/\/[^\/]+/', '', $uri);
 			}
 		}
+
 		// Now lets check for IIS
 		elseif (isset($_SERVER['HTTP_X_REWRITE_URL']))
 		{
 			$uri = $_SERVER['HTTP_X_REWRITE_URL'];
 		}
+		
 		// Last ditch effort (for older CGI servers, like IIS 5)
 		elseif (isset($_SERVER['ORIG_PATH_INFO']))
 		{
 			$uri = $_SERVER['ORIG_PATH_INFO'];
 			if ( ! empty($_SERVER['QUERY_STRING']))
 			{
-				$uri .= '?'.$_SERVER['QUERY_STRING'];
+				$uri .= '?' . $_SERVER['QUERY_STRING'];
 			}
 		}
 
@@ -173,8 +175,8 @@
 	{
 		// 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)
+		$fc_path = ltrim(FCPATH . SELF, '/');
+		if (strpos($uri, SELF . '?') !== FALSE)
 		{
 			$fc_path .= '?';
 		}
@@ -182,7 +184,7 @@
 		$parsed_uri = explode('/', ltrim($uri, '/'));
 
 		$i = 0;
-		foreach(explode("/", $fc_path) as $segment)
+		foreach (explode("/", $fc_path) as $segment)
 		{
 			if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i])
 			{
@@ -203,7 +205,7 @@
 		}
 
 		// If it is just a / or index.php then just empty it.
-		if ($uri == '/' || $uri == SELF)
+		if ($uri == '/' OR $uri == SELF)
 		{
 			$uri = '';
 		}
@@ -266,7 +268,7 @@
 	 */
 	function _explode_segments()
 	{
-		foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
+		foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
 		{
 			// Filter segments for security
 			$val = trim($this->_filter_uri($val));
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index f40eac8..ce505f4 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -333,6 +333,12 @@
 
 		foreach ($field as $k => $v)
 		{
+			// If no name provided, use the current name
+			if ( ! isset($field[$k]['name']))
+			{
+				$field[$k]['name'] = $k;
+			}
+
 			$this->add_field(array($k => $field[$k]));
 
 			if (count($this->fields) == 0)
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
new file mode 100644
index 0000000..ea31942
--- /dev/null
+++ b/system/libraries/Cache/Cache.php
@@ -0,0 +1,216 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2006 - 2010 EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 2.0
+ * @filesource	
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Caching Class 
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Core
+ * @author		ExpressionEngine Dev Team
+ * @link		
+ */
+class Cache extends CI_Driver_Library {
+	
+	protected $valid_drivers 	= array(
+				'cache_apc', 'cache_file', 'cache_memcached', 'cache_dummy'
+		);
+
+	protected $_cache_path		= NULL;		// Path of cache files (if file-based cache)
+	protected $_adapter			= 'dummy';
+	protected $_backup_driver;
+	
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Constructor
+	 *
+	 * @param array
+	 */
+	public function __construct($config = array())
+	{
+		if ( ! empty($config))
+		{
+			$this->_initialize($config);
+		}
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Get 
+	 *
+	 * Look for a value in the cache.  If it exists, return the data 
+	 * if not, return FALSE
+	 *
+	 * @param 	string	
+	 * @return 	mixed		value that is stored/FALSE on failure
+	 */
+	public function get($id)
+	{	
+		return $this->{$this->_adapter}->get($id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Save
+	 *
+	 * @param 	string		Unique Key
+	 * @param 	mixed		Data to store
+	 * @param 	int			Length of time (in seconds) to cache the data
+	 *
+	 * @return 	boolean		true on success/false on failure
+	 */
+	public function save($id, $data, $ttl = 60)
+	{
+		return $this->{$this->_adapter}->save($id, $data, $ttl);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Delete from Cache
+	 *
+	 * @param 	mixed		unique identifier of the item in the cache
+	 * @return 	boolean		true on success/false on failure
+	 */
+	public function delete($id)
+	{
+		return $this->{$this->_adapter}->delete($id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Clean the cache
+	 *
+	 * @return 	boolean		false on failure/true on success
+	 */
+	public function clean()
+	{
+		return $this->{$this->_adapter}->clean();
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Info
+	 *
+	 * @param 	string		user/filehits
+	 * @return 	mixed		array on success, false on failure	
+	 */
+	public function cache_info($type = 'user')
+	{
+		return $this->{$this->_adapter}->cache_info($type);
+	}
+
+	// ------------------------------------------------------------------------
+	
+	/**
+	 * Get Cache Metadata
+	 *
+	 * @param 	mixed		key to get cache metadata on
+	 * @return 	mixed		return value from child method
+	 */
+	public function get_metadata($id)
+	{
+		return $this->{$this->_adapter}->get_metadata($id);
+	}
+	
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Initialize
+	 *
+	 * Initialize class properties based on the configuration array.
+	 *
+	 * @param	array 	
+	 * @return 	void
+	 */
+	private function _initialize($config)
+	{        
+		$default_config = array(
+				'adapter',
+				'memcached'
+			);
+
+		foreach ($default_config as $key)
+		{
+			if (isset($config[$key]))
+			{
+				$param = '_'.$key;
+
+				$this->{$param} = $config[$key];
+			}
+		}
+
+		if (isset($config['backup']))
+		{
+			if (in_array('cache_'.$config['backup'], $this->valid_drivers))
+			{
+				$this->_backup_driver = $config['backup'];
+			}
+		}
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Is the requested driver supported in this environment?
+	 *
+	 * @param 	string	The driver to test.
+	 * @return 	array
+	 */
+	public function is_supported($driver)
+	{
+		static $support = array();
+
+		if ( ! isset($support[$driver]))
+		{
+			$support[$driver] = $this->{$driver}->is_supported();
+		}
+
+		return $support[$driver];
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * __get()
+	 *
+	 * @param 	child
+	 * @return 	object
+	 */
+	public function __get($child)
+	{
+		$obj = parent::__get($child);
+
+		if ( ! $this->is_supported($child))
+		{
+			$this->_adapter = $this->_backup_driver;
+		}
+
+		return $obj;
+	}
+	
+	// ------------------------------------------------------------------------
+}
+// End Class
+
+/* End of file Cache.php */
+/* Location: ./system/libraries/Cache/Cache.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php
new file mode 100644
index 0000000..9c716a9
--- /dev/null
+++ b/system/libraries/Cache/drivers/Cache_apc.php
@@ -0,0 +1,151 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2006 - 2010 EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 2.0
+ * @filesource	
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter APC Caching Class 
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Core
+ * @author		ExpressionEngine Dev Team
+ * @link		
+ */
+
+class Cache_apc extends CI_Driver {
+
+	/**
+	 * Get 
+	 *
+	 * Look for a value in the cache.  If it exists, return the data 
+	 * if not, return FALSE
+	 *
+	 * @param 	string	
+	 * @return 	mixed		value that is stored/FALSE on failure
+	 */
+	public function get($id)
+	{
+		$data = apc_fetch($id);
+
+		return (is_array($data)) ? $data[0] : FALSE;
+	}
+
+	// ------------------------------------------------------------------------	
+	
+	/**
+	 * Cache Save
+	 *
+	 * @param 	string		Unique Key
+	 * @param 	mixed		Data to store
+	 * @param 	int			Length of time (in seconds) to cache the data
+	 *
+	 * @return 	boolean		true on success/false on failure
+	 */
+	public function save($id, $data, $ttl = 60)
+	{
+		return apc_store($id, array($data, time(), $ttl), $ttl);
+	}
+	
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Delete from Cache
+	 *
+	 * @param 	mixed		unique identifier of the item in the cache
+	 * @param 	boolean		true on success/false on failure
+	 */
+	public function delete($id)
+	{
+		return apc_delete($id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Clean the cache
+	 *
+	 * @return 	boolean		false on failure/true on success
+	 */
+	public function clean()
+	{
+		return apc_clear_cache('user');
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Info
+	 *
+	 * @param 	string		user/filehits
+	 * @return 	mixed		array on success, false on failure	
+	 */
+	 public function cache_info($type = NULL)
+	 {
+		 return apc_cache_info($type);
+	 }
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Get Cache Metadata
+	 *
+	 * @param 	mixed		key to get cache metadata on
+	 * @return 	mixed		array on success/false on failure
+	 */
+	public function get_metadata($id)
+	{
+		$stored = apc_fetch($id);
+
+		if (count($stored) !== 3)
+		{
+			return FALSE;
+		}
+
+		list($value, $time, $ttl) = $stored;
+
+		return array(
+			'expire'	=> $time + $ttl,
+			'mtime'		=> $time,
+			'data'		=> $data
+		);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * is_supported()
+	 *
+	 * Check to see if APC is available on this system, bail if it isn't.
+	 */
+	public function is_supported()
+	{
+		if ( ! extension_loaded('apc') OR ! function_exists('apc_store'))
+		{
+			log_message('error', 'The APC PHP extension must be loaded to use APC Cache.');
+			return FALSE;
+		}
+		
+		return TRUE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	
+}
+// End Class
+
+/* End of file Cache_apc.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_apc.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php
new file mode 100644
index 0000000..13c1f5c
--- /dev/null
+++ b/system/libraries/Cache/drivers/Cache_dummy.php
@@ -0,0 +1,129 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2006 - 2010 EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 2.0
+ * @filesource	
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Dummy Caching Class 
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Core
+ * @author		ExpressionEngine Dev Team
+ * @link		
+ */
+
+class Cache_dummy extends CI_Driver {
+
+	/**
+	 * Get 
+	 *
+	 * Since this is the dummy class, it's always going to return FALSE.
+	 *
+	 * @param 	string	
+	 * @return 	Boolean		FALSE
+	 */
+	public function get($id)
+	{
+		return FALSE;
+	}
+
+	// ------------------------------------------------------------------------	
+	
+	/**
+	 * Cache Save
+	 *
+	 * @param 	string		Unique Key
+	 * @param 	mixed		Data to store
+	 * @param 	int			Length of time (in seconds) to cache the data
+	 *
+	 * @return 	boolean		TRUE, Simulating success
+	 */
+	public function save($id, $data, $ttl = 60)
+	{
+		return TRUE;
+	}
+	
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Delete from Cache
+	 *
+	 * @param 	mixed		unique identifier of the item in the cache
+	 * @param 	boolean		TRUE, simulating success
+	 */
+	public function delete($id)
+	{
+		return TRUE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Clean the cache
+	 *
+	 * @return 	boolean		TRUE, simulating success
+	 */
+	public function clean()
+	{
+		return TRUE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Info
+	 *
+	 * @param 	string		user/filehits
+	 * @return 	boolean		FALSE
+	 */
+	 public function cache_info($type = NULL)
+	 {
+		 return FALSE;
+	 }
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Get Cache Metadata
+	 *
+	 * @param 	mixed		key to get cache metadata on
+	 * @return 	boolean		FALSE
+	 */
+	public function get_metadata($id)
+	{
+		return FALSE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Is this caching driver supported on the system?
+	 * Of course this one is.
+	 * 
+	 * @return TRUE;
+	 */
+	public function is_supported()
+	{
+		return TRUE;
+	}
+
+	// ------------------------------------------------------------------------
+	
+}
+// End Class
+
+/* End of file Cache_apc.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_apc.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
new file mode 100644
index 0000000..bedbfaf
--- /dev/null
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -0,0 +1,196 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2006 - 2010 EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 2.0
+ * @filesource	
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Memcached Caching Class 
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Core
+ * @author		ExpressionEngine Dev Team
+ * @link		
+ */
+
+class Cache_file extends CI_Driver {
+
+	protected $_cache_path;
+
+	/**
+	 * Constructor
+	 */
+	public function __construct()
+	{
+		$CI =& get_instance();
+		$CI->load->helper('file');
+		
+		$path = $CI->config->item('cache_path');
+	
+		$this->_cache_path = ($path == '') ? BASEPATH.'cache/' : $path;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Fetch from cache
+	 *
+	 * @param 	mixed		unique key id
+	 * @return 	mixed		data on success/false on failure
+	 */
+	public function get($id)
+	{
+		if ( ! file_exists($this->_cache_path.$id))
+		{
+			return FALSE;
+		}
+		
+		$data = read_file($this->_cache_path.$id);
+		$data = unserialize($data);
+		
+		if (time() >  $data['time'] + $data['ttl'])
+		{
+			unlink($this->_cache_path.$id);
+			return FALSE;
+		}
+		
+		return $data['data'];
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Save into cache
+	 *
+	 * @param 	string		unique key
+	 * @param 	mixed		data to store
+	 * @param 	int			length of time (in seconds) the cache is valid 
+	 *						- Default is 60 seconds
+	 * @return 	boolean		true on success/false on failure
+	 */
+	public function save($id, $data, $ttl = 60)
+	{		
+		$contents = array(
+				'time'		=> time(),
+				'ttl'		=> $ttl,			
+				'data'		=> $data
+			);
+		
+		if (write_file($this->_cache_path.$id, serialize($contents)))
+		{
+			@chmod($this->_cache_path.$id, 0777);
+			return TRUE;			
+		}
+
+		return FALSE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Delete from Cache
+	 *
+	 * @param 	mixed		unique identifier of item in cache
+	 * @return 	boolean		true on success/false on failure
+	 */
+	public function delete($id)
+	{
+		return unlink($this->_cache_path.$id);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Clean the Cache
+	 *
+	 * @return 	boolean		false on failure/true on success
+	 */	
+	public function clean()
+	{
+		return delete_files($this->_cache_path);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Info
+	 *
+	 * Not supported by file-based caching
+	 *
+	 * @param 	string	user/filehits
+	 * @return 	mixed 	FALSE
+	 */
+	public function cache_info($type = NULL)
+	{
+		return get_dir_file_info($this->_cache_path);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Get Cache Metadata
+	 *
+	 * @param 	mixed		key to get cache metadata on
+	 * @return 	mixed		FALSE on failure, array on success.
+	 */
+	public function get_metadata($id)
+	{
+		if ( ! file_exists($this->_cache_path.$id))
+		{
+			return FALSE;
+		}
+		
+		$data = read_file($this->_cache_path.$id);		
+		$data = unserialize($data);
+		
+		if (is_array($data))
+		{
+			$data = $data['data'];
+			$mtime = filemtime($this->_cache_path.$id);
+
+			if ( ! isset($data['ttl']))
+			{
+				return FALSE;
+			}
+
+			return array(
+				'expire' 	=> $mtime + $data['ttl'],
+				'mtime'		=> $mtime
+			);
+		}
+		
+		return FALSE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Is supported
+	 *
+	 * In the file driver, check to see that the cache directory is indeed writable
+	 * 
+	 * @return boolean
+	 */
+	public function is_supported()
+	{
+		return is_really_writable($this->_cache_path);
+	}
+
+	// ------------------------------------------------------------------------
+}
+// End Class
+
+/* End of file Cache_file.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_file.php */
\ No newline at end of file
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
new file mode 100644
index 0000000..adc7fbf
--- /dev/null
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -0,0 +1,209 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 4.3.2 or newer
+ *
+ * @package		CodeIgniter
+ * @author		ExpressionEngine Dev Team
+ * @copyright	Copyright (c) 2006 - 2010 EllisLab, Inc.
+ * @license		http://codeigniter.com/user_guide/license.html
+ * @link		http://codeigniter.com
+ * @since		Version 2.0
+ * @filesource	
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Memcached Caching Class 
+ *
+ * @package		CodeIgniter
+ * @subpackage	Libraries
+ * @category	Core
+ * @author		ExpressionEngine Dev Team
+ * @link		
+ */
+
+class Cache_memcached extends CI_Driver {
+
+	private $_memcached;	// Holds the memcached object
+
+	protected $_memcache_conf 	= array(
+					'default' => array(
+						'default_host'		=> '127.0.0.1',
+						'default_port'		=> 11211,
+						'default_weight'	=> 1
+					)
+				);
+
+	// ------------------------------------------------------------------------	
+
+	/**
+	 * Fetch from cache
+	 *
+	 * @param 	mixed		unique key id
+	 * @return 	mixed		data on success/false on failure
+	 */	
+	public function get($id)
+	{	
+		$data = $this->_memcached->get($id);
+		
+		return (is_array($data)) ? $data[0] : FALSE;
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Save
+	 *
+	 * @param 	string		unique identifier
+	 * @param 	mixed		data being cached
+	 * @param 	int			time to live
+	 * @return 	boolean 	true on success, false on failure
+	 */
+	public function save($id, $data, $ttl = 60)
+	{
+		return $this->_memcached->add($id, array($data, time(), $ttl), $ttl);
+	}
+
+	// ------------------------------------------------------------------------
+	
+	/**
+	 * Delete from Cache
+	 *
+	 * @param 	mixed		key to be deleted.
+	 * @return 	boolean 	true on success, false on failure
+	 */
+	public function delete($id)
+	{
+		return $this->_memcached->delete($id);
+	}
+
+	// ------------------------------------------------------------------------
+	
+	/**
+	 * Clean the Cache
+	 *
+	 * @return 	boolean		false on failure/true on success
+	 */
+	public function clean()
+	{
+		return $this->_memcached->flush();
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Cache Info
+	 *
+	 * @param 	null		type not supported in memcached
+	 * @return 	mixed 		array on success, false on failure
+	 */
+	public function cache_info($type = NULL)
+	{
+		return $this->_memcached->getStats();
+	}
+
+	// ------------------------------------------------------------------------
+	
+	/**
+	 * Get Cache Metadata
+	 *
+	 * @param 	mixed		key to get cache metadata on
+	 * @return 	mixed		FALSE on failure, array on success.
+	 */
+	public function get_metadata($id)
+	{
+		$stored = $this->_memcached->get($id);
+
+		if (count($stored) !== 3)
+		{
+			return FALSE;
+		}
+
+		list($value, $time, $ttl) = $stored;
+
+		return array(
+			'expire'	=> $time + $ttl,
+			'mtime'		=> $time,
+			'data'		=> $data
+		);
+	}
+
+	// ------------------------------------------------------------------------
+
+	/**
+	 * Setup memcached.
+	 */
+	private function _setup_memcached()
+	{
+		// Try to load memcached server info from the config file.
+		$CI =& get_instance();
+		if ($CI->config->load('memcached', TRUE, TRUE))
+		{
+			if (is_array($CI->config->config['memcached']))
+			{
+				$this->_memcache_conf = NULL;
+
+				foreach ($CI->config->config['memcached'] as $name => $conf)
+				{
+					$this->_memcache_conf[$name] = $conf;
+				}				
+			}			
+		}
+		
+		$this->_memcached = new Memcached();
+
+		foreach ($this->_memcache_conf as $name => $cache_server)
+		{
+			if ( ! array_key_exists('hostname', $cache_server))
+			{
+				$cache_server['hostname'] = $this->_default_options['default_host'];
+			}
+	
+			if ( ! array_key_exists('port', $cache_server))
+			{
+				$cache_server['port'] = $this->_default_options['default_port'];
+			}
+	
+			if ( ! array_key_exists('weight', $cache_server))
+			{
+				$cache_server['weight'] = $this->_default_options['default_weight'];
+			}
+	
+			$this->_memcached->addServer(
+					$cache_server['hostname'], $cache_server['port'], $cache_server['weight']
+			);
+		}
+	}
+
+	// ------------------------------------------------------------------------
+
+
+	/**
+	 * Is supported
+	 *
+	 * Returns FALSE if memcached is not supported on the system.
+	 * If it is, we setup the memcached object & return TRUE
+	 */
+	public function is_supported()
+	{
+		if ( ! extension_loaded('memcached'))
+		{
+			log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.');
+			
+			return FALSE;
+		}
+		
+		$this->_setup_memcached();
+		return TRUE;
+	}
+
+	// ------------------------------------------------------------------------
+
+}
+// End Class
+
+/* End of file Cache_memcached.php */
+/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
\ No newline at end of file
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index a57781c..b4c6d36 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -346,7 +346,7 @@
 					{
 						if ($function !== FALSE && is_callable($function))
 						{
-							$out .= $function($cell);
+							$out .= call_user_func($function, $cell);
 						}
 						else
 						{
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 4ccbdde..b0e1f4c 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -212,7 +212,18 @@
 		if ($this->_file_name_override != '')
 		{
 			$this->file_name = $this->_prep_filename($this->_file_name_override);
-			$this->file_ext  = $this->get_extension($this->file_name);
+
+			// If no extension was provided in the file_name config item, use the uploaded one
+			if(strpos($this->_file_name_override, '.') === FALSE)
+			{
+				$this->file_name .= $this->file_ext;
+			}
+
+			// An extension was provided, lets have it!
+			else
+			{
+				$this->file_ext	 = $this->get_extension($this->_file_name_override);
+			}
 
 			if ( ! $this->is_allowed_filetype(TRUE))
 			{
diff --git a/user_guide/changelog.html b/user_guide/changelog.html
index c3693e5..30734a8 100644
--- a/user_guide/changelog.html
+++ b/user_guide/changelog.html
@@ -76,6 +76,10 @@
 			<li>In-development code is now hosted at <a href="http://bitbucket.org/ellislab/codeigniter/">BitBucket</a>.</li>
 			<li>Removed the deprecated Validation Class.</li>
 			<li>Added CI_ Prefix to all core classes.</li>
+			<li>Package paths can now be set in application/config/autoload.php.</li>
+			<li>Upload library file_name can now be set without an extension, the extension will be taken from the uploaded file instead of the given name.</li>
+			<li>Name can be omitted from $this->dbforge->modify_column()'s 2nd param if you aren't changing the name.</li>
+			<li><kbd>$config['base_url']</kbd> is now empty by default and will guess what it should be.</li>
 		</ul>
 	<li>Libraries
 		<ul>
diff --git a/user_guide/database/forge.html b/user_guide/database/forge.html
index 28b32d9..b9e0442 100644
--- a/user_guide/database/forge.html
+++ b/user_guide/database/forge.html
@@ -205,7 +205,7 @@
 <p>Used to remove a column from a table. </p>
 <p><code>$this-&gt;dbforge-&gt;drop_column('table_name', 'column_to_drop');</code></p>
 <h2>$this-&gt;dbforge-&gt;modify_column()</h2>
-<p>The usage of this function is identical to add_column(), except it alters an existing column rather than adding a new one. In order to use it you must add a &quot;name&quot; key into the field defining array.</p>
+<p>The usage of this function is identical to add_column(), except it alters an existing column rather than adding a new one. In order to change the name you can add a &quot;name&quot; key into the field defining array.</p>
 <p><code>$fields = array(<br />
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'old_name' =&gt; array(<br />
 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'name' =&gt; 'new_name',<br />
diff --git a/user_guide/libraries/caching.html b/user_guide/libraries/caching.html
new file mode 100644
index 0000000..e4651dc
--- /dev/null
+++ b/user_guide/libraries/caching.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Caching Driver : CodeIgniter User Guide</title>
+
+<style type='text/css' media='all'>@import url('../userguide.css');</style>
+<link rel='stylesheet' type='text/css' media='all' href='../userguide.css' />
+
+<script type="text/javascript" src="../nav/nav.js"></script>
+<script type="text/javascript" src="../nav/prototype.lite.js"></script>
+<script type="text/javascript" src="../nav/moo.fx.js"></script>
+<script type="text/javascript" src="../nav/user_guide_menu.js"></script>
+
+<meta http-equiv='expires' content='-1' />
+<meta http-equiv= 'pragma' content='no-cache' />
+<meta name='robots' content='all' />
+<meta name='author' content='ExpressionEngine Dev Team' />
+<meta name='description' content='CodeIgniter User Guide' />
+
+</head>
+<body>
+
+<!-- START NAVIGATION -->
+<div id="nav"><div id="nav_inner"><script type="text/javascript">create_menu('../');</script></div></div>
+<div id="nav2"><a name="top"></a><a href="javascript:void(0);" onclick="myHeight.toggle();"><img src="../images/nav_toggle_darker.jpg" width="154" height="43" border="0" title="Toggle Table of Contents" alt="Toggle Table of Contents" /></a></div>
+<div id="masthead">
+<table cellpadding="0" cellspacing="0" border="0" style="width:100%">
+<tr>
+<td><h1>CodeIgniter User Guide Version 2.0.0</h1></td>
+<td id="breadcrumb_right"><a href="../toc.html">Table of Contents Page</a></td>
+</tr>
+</table>
+</div>
+<!-- END NAVIGATION -->
+
+
+<!-- START BREADCRUMB -->
+<table cellpadding="0" cellspacing="0" border="0" style="width:100%">
+<tr>
+<td id="breadcrumb">
+<a href="http://codeigniter.com/">CodeIgniter Home</a> &nbsp;&#8250;&nbsp;
+<a href="../index.html">User Guide Home</a> &nbsp;&#8250;&nbsp;
+<a href="../general/drivers.html">Drivers</a> &nbsp;&#8250;&nbsp;
+Caching Driver
+</td>
+<td id="searchbox"><form method="get" action="http://www.google.com/search"><input type="hidden" name="as_sitesearch" id="as_sitesearch" value="codeigniter.com/user_guide/" />Search User Guide&nbsp; <input type="text" class="input" style="width:200px;" name="q" id="q" size="31" maxlength="255" value="" />&nbsp;<input type="submit" class="submit" name="sa" value="Go" /></form></td>
+</tr>
+</table>
+<!-- END BREADCRUMB -->
+
+<br clear="all" />
+
+
+<!-- START CONTENT -->
+<div id="content">
+
+<h1>Caching Driver</h1>
+
+<p>CodeIgniter features wrappers around some of the most popular forms of fast and dynamic caching.  All but file-based caching require specific server requirements, and a Fatal Exception will be thrown if server requirements are not met.</p>
+
+<h2>Table of Contents</h2>
+<ul>
+	<li><a href="#example_usage" title="Example Usage">Example Usage</a></li>
+	<li><a href="#function_reference" title="Function Reference">Function Reference</a></li>
+</ul>
+
+<h3>Available Drivers</h3>
+<ul>
+	<li><a href="#apc" title="APC Cache">Alternative PHP Cache (APC) Caching</a></li>
+	<li><a href="#file" title="File Caching">File-based Caching</a></li>
+	<li><a href="#memcached" title="Memcached">Memcached Caching</a></li>
+	<li><a href="#dummy" title="Dummy Caching">Dummy Cache</a></li>
+</ul>
+
+<h2 id="example_usage">Example Usage</h2>
+
+<p>The following example will load the cache driver, specify <a href="#apc" title="APC">APC</a> as the driver to use, and fall back to file-based caching if APC is not available in the hosting environment.</p>
+
+<code>
+$this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));<br />
+<br />
+if ( ! $foo = $this->cache->get('foo'))<br />
+{<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo 'Saving to the cache!&lt;br />';<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$foo = 'foobarbaz!';<br />
+<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Save into the cache for 5 minutes<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->cache->save('foo', $foo, 300);<br />
+}<br />
+<br />
+echo $foo;
+</code>
+
+<h1 id="function_reference">Function Reference</h1>
+
+<h2>is_supported(<var>driver</var>['string'])</h2>
+
+<p>This function is automatically called when accessing drivers via <samp>$this->cache->get()</samp>.  However, if the individual drivers are used, make sure to call this function to ensure the driver is supported in the hosting environment.</p>
+
+<code>
+if ($this->cache->apc->is_supported())<br />
+{<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($data = $this->cache->apc->get('my_cache'))<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do things.<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
+}
+</code>
+
+<h2>get(<var>id</var>['string'])</h2>
+
+<p>This function will attempt to fetch an item from the cache store.  If the item does not exist, the function will return <samp>FALSE</samp>.</p>
+<code>$foo = $this->cache->get('my_cached_item');</code>
+
+<h2>save(<var>id</var>['string'], <var>data</var>['mixed'], <var>ttl</var>['int'])</h2>
+
+<p>This function will save an item to the cache store.  If saving fails, the function will return <samp>FALSE</samp>.</p>
+<p>The optional third parameter (Time To Live) defaults to 60 seconds.</p>
+<code>$this->cache->save('cache_item_id', 'data_to_cache');</code>
+
+<h2>delete(<var>id</var>['string'])</h2>
+
+<p>This function will delete a specific item from the cache store.  If item deletion fails, the function will return <samp>FALSE</samp>.</p>
+<code>$this->cache->delete('cache_item_id');</code>
+
+<h2>clean()</h2>
+
+<p>This function will 'clean' the entire cache.  If the deletion of the cache files fails, the function will return <samp>FALSE</samp>.</p>
+
+<code>$this->cache->clean();</code>
+
+<h2>cache_info()</h2>
+
+<p>This function will return information on the entire cache.</p>
+
+<code>var_dump($this->cache->cache_info());</code>
+
+<h2>get_metadata(<var>id</var>['string'])</h2>
+
+<p>This function will return detailed information on a specific item in the cache.</p>
+
+<code>var_dump($this->cache->get_metadata('my_cached_item'));</code>
+
+<h1>Drivers</h1>
+
+<h2 id="apc">Alternative PHP Cache (APC) Caching</h2>
+
+<p>All of the functions listed above can be accessed without passing a specific adapter to the driver loader as follows:</p>
+<code>$this->load->driver('cache');<br />
+	$this->cache->apc->save('foo', 'bar', 10);</code>
+<p>For more information on APC, please see <a href="http://php.net/apc">http://php.net/apc</a></p>
+
+<h2 id="file">File-based Caching</h2>
+
+<p>Unlike caching from the Output Class, the driver file-based caching allows for pieces of view files to be cached.  Use this with care, and make sure to benchmark your application, as a point can come where disk I/O will negate positive gains by caching.</p>
+
+<p>All of the functions listed above can be accessed without passing a specific adapter to the driver loader as follows:</p>
+<code>$this->load->driver('cache');<br />
+	$this->cache->file->save('foo', 'bar', 10);</code>
+
+<h2 id="memcached">Memcached Caching</h2>
+
+<p>Multiple Memcached servers can be specified in the memcached.php configuration file, located in the <samp>application/config/</samp> directory.
+
+<p>All of the functions listed above can be accessed without passing a specific adapter to the driver loader as follows:</p>
+<code>$this->load->driver('cache');<br />
+	$this->cache->memcached->save('foo', 'bar', 10);</code>
+
+<p>For more information on Memcached, please see <a href="http://php.net/memcached">http://php.net/memcached</a></p>
+
+<h2 id="dummy">Dummy Cache</h2>
+
+<p>This is a caching backend that will always 'miss.'  It stores no data, but lets you keep your caching code in place in environments that don't support your chosen cache.</p>
+
+</div>
+<!-- END CONTENT -->
+
+
+<div id="footer">
+<p>
+Previous Topic:&nbsp;&nbsp;<a href="errors.html">Error Handling</a>
+&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;
+<a href="#top">Top of Page</a>&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;
+<a href="../index.html">User Guide Home</a>&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;
+Next Topic:&nbsp;&nbsp;<a href="profiling.html">Profiling Your Application</a>
+</p>
+<p><a href="http://codeigniter.com">CodeIgniter</a> &nbsp;&middot;&nbsp; Copyright &#169; 2006-2010 &nbsp;&middot;&nbsp; <a href="http://ellislab.com/">EllisLab, Inc.</a></p>
+</div>
+
+</body>
+</html>
\ No newline at end of file