Merged recent Core changes and fixed conflict.
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 0d0fffb..6ac333a 100644
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -39,7 +39,7 @@
  *  Define the CodeIgniter Branch (Core = TRUE, Reactor = FALSE)
  * ------------------------------------------------------
  */
-	define('CI_CORE', TRUE);
+	define('CI_CORE', FALSE);
 
 /*
  * ------------------------------------------------------
@@ -87,7 +87,7 @@
 	{
 		get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
 	}
-	
+
 /*
  * ------------------------------------------------------
  *  Set a liberal script execution time limit
@@ -296,7 +296,28 @@
 		// methods, so we'll use this workaround for consistent behavior
 		if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))
 		{
-			show_404("{$class}/{$method}");
+			// 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']);
+				$class = $x[0];
+				$method = (isset($x[1]) ? $x[1] : 'index');
+				if ( ! class_exists($class))
+				{
+					if ( ! file_exists(APPPATH.'controllers/'.$class.EXT))
+					{
+						show_404("{$class}/{$method}");
+					}
+
+					include_once(APPPATH.'controllers/'.$class.EXT);
+					unset($CI);
+					$CI = new $class();
+				}
+			}
+			else
+			{
+				show_404("{$class}/{$method}");
+			}
 		}
 
 		// Call the requested method.
@@ -344,4 +365,4 @@
 
 
 /* End of file CodeIgniter.php */
-/* Location: ./system/core/CodeIgniter.php */
\ No newline at end of file
+/* Location: ./system/core/CodeIgniter.php */
diff --git a/system/core/Common.php b/system/core/Common.php
index b5adfac..cd6b933 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -208,15 +208,20 @@
 			return $_config[0];
 		}
 
+		$file_path = APPPATH.'config/'.ENVIRONMENT.'/config'.EXT;
+
 		// Fetch the config file
-		if ( ! file_exists(APPPATH.'config/config'.EXT))
+		if ( ! file_exists($file_path))
 		{
-			exit('The configuration file does not exist.');
+			$file_path = APPPATH.'config/config'.EXT;
+			
+			if ( ! file_exists($file_path))
+			{
+				exit('The configuration file does not exist.');
+			}
 		}
-		else
-		{
-			require(APPPATH.'config/config'.EXT);
-		}
+	
+		require($file_path);
 
 		// Does the $config array exist in the file?
 		if ( ! isset($config) OR ! is_array($config))
diff --git a/system/core/Config.php b/system/core/Config.php
index 7fc8044..75f945e 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);
+		}
 	}
 
 	// --------------------------------------------------------------------
@@ -56,6 +74,8 @@
 	 *
 	 * @access	public
 	 * @param	string	the config file name
+	 * @param   boolean  if configuration values should be loaded into their own section
+	 * @param   boolean  true if errors should just return false, false if an error message should be displayed
 	 * @return	boolean	if the file was loaded correctly
 	 */
 	function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
@@ -63,9 +83,9 @@
 		$file = ($file == '') ? 'config' : str_replace(EXT, '', $file);
 		$loaded = FALSE;
 
-		foreach($this->_config_paths as $path)
-		{
-			$file_path = $path.'config/'.$file.EXT;
+		foreach ($this->_config_paths as $path)
+		{			
+			$file_path = $path.'config/'.ENVIRONMENT.'/'.$file.EXT;
 
 			if (in_array($file_path, $this->is_loaded, TRUE))
 			{
@@ -73,11 +93,17 @@
 				continue;
 			}
 
-			if ( ! file_exists($path.'config/'.$file.EXT))
+			if ( ! file_exists($file_path))
 			{
-				continue;
+				log_message('debug', 'Config for '.ENVIRONMENT.' environment is not found. Trying global config.');
+				$file_path = $path.'config/'.$file.EXT;
+				
+				if ( ! file_exists($file_path))
+				{
+					continue;
+				}
 			}
-
+			
 			include($file_path);
 
 			if ( ! isset($config) OR ! is_array($config))
@@ -118,9 +144,9 @@
 			{
 				return FALSE;
 			}
-			show_error('The configuration file '.$file.EXT.' does not exist.');
+			show_error('The configuration file '.ENVIRONMENT.'/'.$file.EXT.' and '.$file.EXT.' do not exist.');
 		}
-
+		
 		return TRUE;
 	}
 
@@ -185,14 +211,7 @@
 			return FALSE;
 		}
 
-		$pref = $this->config[$item];
-
-		if ($pref != '' && substr($pref, -1) != '/')
-		{
-			$pref .= '/';
-		}
-
-		return $pref;
+		return rtrim($this->config[$item], '/').'/';
 	}
 
 	// --------------------------------------------------------------------
@@ -208,14 +227,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)
@@ -225,8 +237,9 @@
 				$uri = implode('/', $uri);
 			}
 
+			$index = $this->item('index_page') == '' ? '' : $this->slash_item('index_page');
 			$suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
-			return $this->slash_item('base_url').$this->slash_item('index_page').trim($uri, '/').$suffix;
+			return $this->slash_item('base_url').$index.trim($uri, '/').$suffix;
 		}
 		else
 		{
@@ -244,14 +257,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 c2db94d..6262453 100644
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -30,7 +30,7 @@
 
 	var $ip_address				= FALSE;
 	var $user_agent				= FALSE;
-	var $_allow_get_array		= FALSE;
+	var $_allow_get_array		= TRUE;
 	var $_standardize_newlines	= TRUE;
 	var $_enable_xss			= FALSE; // Set automatically based on config setting
 	var $_enable_csrf			= FALSE; // Set automatically based on config setting
@@ -49,9 +49,9 @@
 	{
 		log_message('debug', "Input Class Initialized");
 
-		$this->_allow_get_array	= (config_item('enable_query_strings') === 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)
@@ -109,8 +109,21 @@
 	* @param	bool
 	* @return	string
 	*/
-	function get($index = '', $xss_clean = FALSE)
+	function get($index = NULL, $xss_clean = FALSE)
 	{
+		// Check if a field has been provided
+		if ($index === NULL AND ! empty($_GET))
+		{
+			$get = array();
+
+			// loop through the full _GET array
+			foreach (array_keys($_GET) as $key)
+			{
+				$get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean);
+			}
+			return $get;
+		}
+
 		return $this->_fetch_from_array($_GET, $index, $xss_clean);
 	}
 
@@ -124,8 +137,21 @@
 	* @param	bool
 	* @return	string
 	*/
-	function post($index = '', $xss_clean = FALSE)
+	function post($index = NULL, $xss_clean = FALSE)
 	{
+		// Check if a field has been provided
+		if ($index === NULL AND ! empty($_POST))
+		{
+			$post = array();
+
+			// Loop through the full _POST array and return it
+			foreach (array_keys($_POST) as $key)
+			{
+				$post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean);
+			}
+			return $post;
+		}
+		
 		return $this->_fetch_from_array($_POST, $index, $xss_clean);
 	}
 
@@ -182,13 +208,15 @@
 	* @param	string	the cookie domain.  Usually:  .yourdomain.com
 	* @param	string	the cookie path
 	* @param	string	the cookie prefix
+	* @param	bool	true makes the cookie secure
 	* @return	void
 	*/
-	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '')
+	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
 	{
 		if (is_array($name))
 		{
-			foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'name') as $item)
+			// always leave 'name' in last place, as the loop will break otherwise, due to $$item
+			foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'name') as $item)
 			{
 				if (isset($name[$item]))
 				{
@@ -209,6 +237,10 @@
 		{
 			$path = config_item('cookie_path');
 		}
+		if ($secure == FALSE AND config_item('cookie_secure') != FALSE)
+		{
+			$secure = config_item('cookie_secure');
+		}
 
 		if ( ! is_numeric($expire))
 		{
@@ -216,19 +248,10 @@
 		}
 		else
 		{
-			if ($expire > 0)
-			{
-				$expire = time() + $expire;
-			}
-			else
-			{
-				$expire = 0;
-			}
+			$expire = ($expire > 0) ? time() + $expire : 0;
 		}
-		
-		$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
 
-		setcookie($prefix.$name, $value, $expire, $path, $domain, $secure_cookie);
+		setcookie($prefix.$name, $value, $expire, $path, $domain, $secure);
 	}
 
 	// --------------------------------------------------------------------
@@ -422,7 +445,7 @@
 		{
 			if (is_array($_GET) AND count($_GET) > 0)
 			{
-				foreach($_GET as $key => $val)
+				foreach ($_GET as $key => $val)
 				{
 					$_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
 				}
@@ -432,7 +455,7 @@
 		// Clean $_POST Data
 		if (is_array($_POST) AND count($_POST) > 0)
 		{
-			foreach($_POST as $key => $val)
+			foreach ($_POST as $key => $val)
 			{
 				$_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
 			}
@@ -450,7 +473,7 @@
 			unset($_COOKIE['$Path']);
 			unset($_COOKIE['$Domain']);
 
-			foreach($_COOKIE as $key => $val)
+			foreach ($_COOKIE as $key => $val)
 			{
 				$_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
 			}
@@ -494,7 +517,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);
 		}
@@ -516,7 +539,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);
 			}
 		}
 
@@ -627,21 +650,35 @@
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Is ajax Request?
 	 *
 	 * Test to see if a request contains the HTTP_X_REQUESTED_WITH header
 	 *
-	 * @return 	boolean 	
+	 * @return 	boolean
 	 */
 	public function is_ajax_request()
 	{
 		return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Is cli Request?
+	 *
+	 * Test to see if a request was made from the command line
+	 *
+	 * @return 	boolean
+	 */
+	public function is_cli_request()
+	{
+		return (bool) defined('STDIN');
+	}
+
 }
 // END Input class
 
 /* End of file Input.php */
-/* Location: ./system/core/Input.php */
\ No newline at end of file
+/* Location: ./system/core/Input.php */
diff --git a/system/core/Lang.php b/system/core/Lang.php
index 6805d0e..fb17790 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 8b1986b..7003318 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -79,14 +79,14 @@
 	{
 		if (is_array($library))
 		{
-			foreach($library as $read)
+			foreach ($library as $read)
 			{
-				$this->library($read);	
+				$this->library($read);
 			}
-			
+
 			return;
 		}
-		
+
 		if ($library == '' OR isset($this->_base_classes[$library]))
 		{
 			return FALSE;
@@ -127,7 +127,7 @@
 	{
 		if (is_array($model))
 		{
-			foreach($model as $babe)
+			foreach ($model as $babe)
 			{
 				$this->model($babe);
 			}
@@ -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)
@@ -854,15 +870,39 @@
 		// Is there an associated config file for this class?  Note: these should always be lowercase
 		if ($config === NULL)
 		{
-			// We test for both uppercase and lowercase, for servers that
-			// are case-sensitive with regard to file names
-			if (file_exists(APPPATH.'config/'.strtolower($class).EXT))
+			// Fetch the config paths containing any package paths
+			$config_component = $this->_ci_get_component('config');
+
+			if (is_array($config_component->_config_paths))
 			{
-				include_once(APPPATH.'config/'.strtolower($class).EXT);
-			}
-			elseif (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT))
-			{
-				include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT);
+				// Break on the first found file, thus package files
+				// are not overridden by default paths
+				foreach ($config_component->_config_paths as $path)
+				{
+					// We test for both uppercase and lowercase, for servers that
+					// are case-sensitive with regard to file names. Check for environment
+					// first, global next
+					if (file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT))
+					{
+						include_once($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT);
+						break;
+					}
+					elseif (file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT))
+					{
+						include_once($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT);
+						break;
+					}
+					elseif (file_exists($path .'config/'.strtolower($class).EXT))
+					{
+						include_once($path .'config/'.strtolower($class).EXT);
+						break;
+					}
+					elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).EXT))
+					{
+						include_once($path .'config/'.ucfirst(strtolower($class)).EXT);
+						break;
+					}
+				}
 			}
 		}
 
diff --git a/system/core/Output.php b/system/core/Output.php
index 7fb9f79..6644b3b 100644
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -28,19 +28,24 @@
  */
 class CI_Output {
 
-	var $final_output;
-	var $cache_expiration	= 0;
-	var $headers			= array();
-	var $enable_profiler	= FALSE;
-	var $parse_exec_vars	= TRUE;	// whether or not to parse variables like {elapsed_time} and {memory_usage}
+	protected $final_output;
+	protected $cache_expiration	= 0;
+	protected $headers			= array();
+	protected $mime_types			= array();
+	protected $enable_profiler	= FALSE;
+	protected $parse_exec_vars	= TRUE;	// whether or not to parse variables like {elapsed_time} and {memory_usage}
 
-	var $_zlib_oc			= FALSE;
-	var $_profiler_sections = array();
+	protected $_zlib_oc			= FALSE;
+	protected $_profiler_sections = array();
 
 	function __construct()
 	{
 		$this->_zlib_oc = @ini_get('zlib.output_compression');
 
+		// Get mime types for later
+		include APPPATH.'config/mimes'.EXT;
+		$this->mime_types = $mimes;
+		
 		log_message('debug', "Output Class Initialized");
 	}
 
@@ -73,6 +78,8 @@
 	function set_output($output)
 	{
 		$this->final_output = $output;
+		
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -96,6 +103,8 @@
 		{
 			$this->final_output .= $output;
 		}
+
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -125,6 +134,42 @@
 		}
 
 		$this->headers[] = array($header, $replace);
+
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Set Content Type Header
+	 *
+	 * @access	public
+	 * @param	string	extension of the file we're outputting
+	 * @return	void
+	 */
+	function set_content_type($mime_type)
+	{
+		if (strpos($mime_type, '/') === FALSE)
+		{
+			$extension = ltrim($mime_type, '.');
+
+			// Is this extension supported?
+			if (isset($this->mime_types[$extension]))
+			{
+				$mime_type =& $this->mime_types[$extension];
+
+				if (is_array($mime_type))
+				{
+					$mime_type = current($mime_type);
+				}
+			}
+		}
+
+		$header = 'Content-Type: '.$mime_type;
+
+		$this->headers[] = array($header, TRUE);
+		
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -141,6 +186,8 @@
 	function set_status_header($code = 200, $text = '')
 	{
 		set_status_header($code, $text);
+
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -155,6 +202,8 @@
 	function enable_profiler($val = TRUE)
 	{
 		$this->enable_profiler = (is_bool($val)) ? $val : TRUE;
+
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -174,6 +223,8 @@
 		{
 			$this->_profiler_sections[$section] = ($enable !== FALSE) ? TRUE : FALSE;
 		}
+
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -188,6 +239,8 @@
 	function cache($time)
 	{
 		$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
+
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/core/Router.php b/system/core/Router.php
index bb4eb0e..6893e6e 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 a991118..c43cde0 100644
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -61,13 +61,17 @@
 	{
 		if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
 		{
-			// If the URL has a question mark then it's simplest to just
-			// build the URI string from the zero index of the $_GET array.
-			// This avoids having to deal with $_SERVER variables, which
-			// can be unreliable in some environments
-			if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
+			// Is the request coming from the command line?
+			if (defined('STDIN'))
 			{
-				$this->uri_string = key($_GET);
+				$this->uri_string = $this->_parse_cli_args();
+				return;
+			}
+
+			// Let's try the REQUEST_URI first, this will work in most situations
+			if ($uri = $this->_detect_uri())
+			{
+				$this->uri_string = $uri;
 				return;
 			}
 
@@ -88,12 +92,10 @@
 				return;
 			}
 
-			// No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists?
-			$path = str_replace($_SERVER['SCRIPT_NAME'], '', (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO'));
-			if (trim($path, '/') != '' && $path != "/".SELF)
+			// As a last ditch effort lets try using the $_GET array
+			if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
 			{
-				// remove path and script information so we have good URI data
-				$this->uri_string = $path;
+				$this->uri_string = key($_GET);
 				return;
 			}
 
@@ -106,7 +108,12 @@
 
 			if ($uri == 'REQUEST_URI')
 			{
-				$this->uri_string = $this->_parse_request_uri();
+				$this->uri_string = $this->_detect_uri();
+				return;
+			}
+			elseif ($uri == 'CLI')
+			{
+				$this->uri_string = $this->_parse_cli_args();
 				return;
 			}
 
@@ -123,54 +130,76 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Parse the REQUEST_URI
+	 * Detects the 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.
+	 * This function will detect the URI automatically and fix the query string
+	 * if necessary.
 	 *
 	 * @access	private
 	 * @return	string
 	 */
-	function _parse_request_uri()
+	private function _detect_uri()
 	{
-		if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '')
+		if ( ! isset($_SERVER['REQUEST_URI']))
 		{
 			return '';
 		}
 
-		$request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI']));
-
-		if ($request_uri == '' OR $request_uri == SELF)
+		$uri = $_SERVER['REQUEST_URI'];
+		if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
 		{
-			return '';
+			$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
+		}
+		elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
+		{
+			$uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
 		}
 
-		$fc_path = FCPATH.SELF;
-		if (strpos($request_uri, '?') !== FALSE)
+		// 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)
 		{
-			$fc_path .= '?';
+			$uri = substr($uri, 2);
 		}
-
-		$parsed_uri = explode("/", $request_uri);
-
-		$i = 0;
-		foreach(explode("/", $fc_path) as $segment)
+		$parts = preg_split('#\?#i', $uri, 2);
+		$uri = $parts[0];
+		if (isset($parts[1]))
 		{
-			if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i])
-			{
-				$i++;
-			}
+			$_SERVER['QUERY_STRING'] = $parts[1];
+			parse_str($_SERVER['QUERY_STRING'], $_GET);
 		}
-
-		$parsed_uri = implode("/", array_slice($parsed_uri, $i));
-
-		if ($parsed_uri != '')
+		else
 		{
-			$parsed_uri = '/'.$parsed_uri;
+			$_SERVER['QUERY_STRING'] = '';
+			$_GET = array();
 		}
+		
+		if ($uri == '/' || empty($uri))
+		{
+			return '/';
+		}
+				
+		$uri = parse_url($uri, PHP_URL_PATH);
 
-		return $parsed_uri;
+		// Do some final cleaning of the URI and return it
+		return str_replace(array('//', '../'), '/', trim($uri, '/'));
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Parse cli arguments
+	 *
+	 * Take each command line argument and assume it is a URI segment.
+	 *
+	 * @access	private
+	 * @return	string
+	 */
+	private function _parse_cli_args()
+	{
+		$args = array_slice($_SERVER['argv'], 1);
+
+		return $args ? '/' . implode('/', $args) : '';
 	}
 
 	// --------------------------------------------------------------------
@@ -228,7 +257,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));
@@ -484,7 +513,7 @@
 	{
 		$leading	= '/';
 		$trailing	= '/';
-		
+
 		if ($where == 'trailing')
 		{
 			$leading	= '';
@@ -493,7 +522,7 @@
 		{
 			$trailing	= '';
 		}
-		
+
 		return $leading.$this->$which($n).$trailing;
 	}
 
@@ -573,7 +602,7 @@
 	 */
 	function ruri_string()
 	{
-		return '/'.implode('/', $this->rsegment_array()).'/';
+		return '/'.implode('/', $this->rsegment_array());
 	}
 
 }
diff --git a/system/database/DB.php b/system/database/DB.php
index fb0516b..93ee392 100644
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -27,7 +27,21 @@
 	// Load the DB config file if a DSN string wasn't passed
 	if (is_string($params) AND strpos($params, '://') === FALSE)
 	{
-		include(APPPATH.'config/database'.EXT);
+		
+		$file_path = APPPATH.'config/'.ENVIRONMENT.'/database'.EXT;
+		
+		if ( ! file_exists($file_path))
+		{
+			log_message('debug', 'Database config for '.ENVIRONMENT.' environment is not found. Trying global config.');
+			$file_path = APPPATH.'config/database'.EXT;
+			
+			if ( ! file_exists($file_path))
+			{
+				continue;
+			}
+		}
+		
+		include($file_path);
 
 		if ( ! isset($db) OR count($db) == 0)
 		{
@@ -74,7 +88,7 @@
 		{
 			parse_str($dns['query'], $extra);
 
-			foreach($extra as $key => $val)
+			foreach ($extra as $key => $val)
 			{
 				// booleans please
 				if (strtoupper($val) == "TRUE")
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
index ce9d1c1..ee72dbb 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_active_rec.php
@@ -954,7 +954,7 @@
 			}
 			else
 			{
-				$this->ar_set[$this->_protect_identifiers($k)] = $this->escape($v);
+				$this->ar_set[$this->_protect_identifiers($k, FALSE, TRUE)] = $this->escape($v);
 			}
 		}
 
@@ -1156,7 +1156,7 @@
 				$this->ar_set[] = array();
 				return;
 			}
-		
+
 			ksort($row); // puts $row in the same order as our keys
 
 			if ($escape === FALSE)
@@ -1167,7 +1167,7 @@
 			{
 				$clean = array();
 
-				foreach($row as $value)
+				foreach ($row as $value)
 				{
 					$clean[] = $this->escape($value);
 				}
@@ -1425,7 +1425,7 @@
 			$index_set = FALSE;
 			$clean = array();
 
-			foreach($v as $k2 => $v2)
+			foreach ($v as $k2 => $v2)
 			{
 				if ($k2 == $index)
 				{
@@ -1569,7 +1569,7 @@
 		}
 		elseif (is_array($table))
 		{
-			foreach($table as $single_table)
+			foreach ($table as $single_table)
 			{
 				$this->delete($single_table, $where, $limit, FALSE);
 			}
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 2d8f592..e7a9de4 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -767,7 +767,7 @@
 
 		if ($query->num_rows() > 0)
 		{
-			foreach($query->result_array() as $row)
+			foreach ($query->result_array() as $row)
 			{
 				if (isset($row['TABLE_NAME']))
 				{
@@ -834,7 +834,7 @@
 		$query = $this->query($sql);
 
 		$retval = array();
-		foreach($query->result_array() as $row)
+		foreach ($query->result_array() as $row)
 		{
 			if (isset($row['COLUMN_NAME']))
 			{
@@ -904,7 +904,7 @@
 		$fields = array();
 		$values = array();
 
-		foreach($data as $key => $val)
+		foreach ($data as $key => $val)
 		{
 			$fields[] = $this->_escape_identifiers($key);
 			$values[] = $this->escape($val);
@@ -932,7 +932,7 @@
 		}
 
 		$fields = array();
-		foreach($data as $key => $val)
+		foreach ($data as $key => $val)
 		{
 			$fields[$this->_protect_identifiers($key)] = $this->escape($val);
 		}
@@ -1175,7 +1175,7 @@
 
 		$trace = debug_backtrace();
 
-		foreach($trace as $call)
+		foreach ($trace as $call)
 		{
 			if (isset($call['file']) && strpos($call['file'], BASEPATH.'database') === FALSE)
 			{
@@ -1248,7 +1248,7 @@
 		{
 			$escaped_array = array();
 
-			foreach($item as $k => $v)
+			foreach ($item as $k => $v)
 			{
 				$escaped_array[$this->_protect_identifiers($k)] = $this->_protect_identifiers($v);
 			}
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index e6a64f3..a71fca7 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -99,7 +99,7 @@
 	{
 		if (is_array($key))
 		{
-			foreach($key as $one)
+			foreach ($key as $one)
 			{
 				$this->add_key($one, $primary);
 			}
@@ -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/database/DB_result.php b/system/database/DB_result.php
index fb791cf..76e1d6a 100644
--- a/system/database/DB_result.php
+++ b/system/database/DB_result.php
@@ -28,13 +28,14 @@
  */
 class CI_DB_result {
 
-	var $conn_id		= NULL;
-	var $result_id		= NULL;
-	var $result_array	= array();
-	var $result_object	= array();
-	var $current_row	= 0;
-	var $num_rows		= 0;
-	var $row_data		= NULL;
+	var $conn_id		      = NULL;
+	var $result_id		      = NULL;
+	var $result_array	      = array();
+	var $result_object	      = array();
+    var $custom_result_object = array();
+	var $current_row	      = 0;
+	var $num_rows		      = 0;
+	var $row_data		      = NULL;
 
 
 	/**
@@ -46,11 +47,48 @@
 	 */
 	function result($type = 'object')
 	{
-		return ($type == 'object') ? $this->result_object() : $this->result_array();
+        if ($type == 'array') return $this->result_array();
+        else if ($type == 'object') return $this->result_object();
+        else return $this->custom_result_object($type);
 	}
 
 	// --------------------------------------------------------------------
 
+    /**
+     * Custom query result.
+     *
+     * @param  class_name  A string that represents the type of object you want back
+     * @return array of objects
+     */
+    function custom_result_object($class_name)
+    {
+        if (array_key_exists($class_name, $this->custom_result_object))
+        {
+            return $this->custom_result_object[$class_name];
+        }
+        
+        if ($this->result_id === FALSE OR $this->num_rows() == 0)
+        {
+            return array();
+        }
+
+        // add the data to the object
+        $this->_data_seek(0);
+        $result_object = array();
+		while ($row = $this->_fetch_object())
+        {
+            $object = new $class_name();
+            foreach ($row as $key => $value)
+            {
+                $object->$key = $value;
+            }
+			$result_object[] = $object;
+		}
+
+        // return the array
+        return $this->custom_result_object[$class_name] = $result_object;
+    }
+
 	/**
 	 * Query result.  "object" version.
 	 *
@@ -142,7 +180,9 @@
 			$n = 0;
 		}
 
-		return ($type == 'object') ? $this->row_object($n) : $this->row_array($n);
+        if ($type == 'object') return $this->row_object($n);
+        else if ($type == 'array') return $this->row_array($n);
+        else return $this->custom_row_object($n, $type);
 	}
 
 	// --------------------------------------------------------------------
@@ -179,7 +219,30 @@
 
 	// --------------------------------------------------------------------
 
-	/**
+    /**
+	 * Returns a single result row - custom object version
+	 *
+	 * @access	public
+	 * @return	object
+	 */
+	function custom_row_object($n, $type)
+	{
+		$result = $this->custom_result_object($type);
+
+		if (count($result) == 0)
+		{
+			return $result;
+		}
+
+		if ($n != $this->current_row AND isset($result[$n]))
+		{
+			$this->current_row = $n;
+		}
+
+		return $result[$this->current_row];
+	}
+
+    /**
 	 * Returns a single result row - object version
 	 *
 	 * @access	public
@@ -339,4 +402,4 @@
 // END DB_result class
 
 /* End of file DB_result.php */
-/* Location: ./system/database/DB_result.php */
\ No newline at end of file
+/* Location: ./system/database/DB_result.php */
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 5a69132..5048c0b 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -253,7 +253,7 @@
 	{
 		if (is_array($str))
 		{
-			foreach($str as $key => $val)
+			foreach ($str as $key => $val)
 			{
 				$str[$key] = $this->escape_str($val, $like);
 			}
@@ -551,7 +551,7 @@
 	 */
 	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
 			$valstr[] = $key." = ".$val;
 		}
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index df18c91..4ff9b0a 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -286,13 +286,13 @@
 	{
 		if (is_array($str))
 		{
-			foreach($str as $key => $val)
-			{
+			foreach ($str as $key => $val)
+	   		{
 				$str[$key] = $this->escape_str($val, $like);
-			}
+	   		}
 
-			return $str;
-		}
+	   		return $str;
+	   	}
 
 		if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))
 		{
@@ -590,9 +590,9 @@
 	 */
 	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key . ' = ' . $val;
 		}
 
 		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
@@ -627,11 +627,11 @@
 		$ids = array();
 		$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
 
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
 			$ids[] = $val[$index];
 
-			foreach(array_keys($val) as $field)
+			foreach (array_keys($val) as $field)
 			{
 				if ($field != $index)
 				{
@@ -643,7 +643,7 @@
 		$sql = "UPDATE ".$table." SET ";
 		$cases = '';
 
-		foreach($final as $k => $v)
+		foreach ($final as $k => $v)
 		{
 			$cases .= $k.' = CASE '."\n";
 			foreach ($v as $row)
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index c02b8cb..529ec98 100644
--- a/system/database/drivers/mysql/mysql_forge.php
+++ b/system/database/drivers/mysql/mysql_forge.php
@@ -87,11 +87,26 @@
 				if (array_key_exists('TYPE', $attributes))
 				{
 					$sql .=  ' '.$attributes['TYPE'];
-				}
 
-				if (array_key_exists('CONSTRAINT', $attributes))
-				{
-					$sql .= '('.$attributes['CONSTRAINT'].')';
+					if (array_key_exists('CONSTRAINT', $attributes))
+					{
+						switch ($attributes['TYPE'])
+						{
+							case 'decimal':
+							case 'float':
+							case 'numeric':
+								$sql .= '('.implode(',', $attributes['CONSTRAINT']).')';
+							break;
+
+							case 'enum':
+							case 'set':
+								$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
+							break;
+
+							default:
+								$sql .= '('.$attributes['CONSTRAINT'].')';
+						}
+					}
 				}
 
 				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 8942100..ccdabce 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -287,7 +287,7 @@
 	{
 		if (is_array($str))
 		{
-			foreach($str as $key => $val)
+			foreach ($str as $key => $val)
 			{
 				$str[$key] = $this->escape_str($val, $like);
 			}
@@ -571,7 +571,7 @@
 	 */
 	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
 			$valstr[] = $key." = ".$val;
 		}
@@ -607,11 +607,11 @@
 		$ids = array();
 		$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
 
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
 			$ids[] = $val[$index];
 
-			foreach(array_keys($val) as $field)
+			foreach (array_keys($val) as $field)
 			{
 				if ($field != $index)
 				{
@@ -623,7 +623,7 @@
 		$sql = "UPDATE ".$table." SET ";
 		$cases = '';
 
-		foreach($final as $k => $v)
+		foreach ($final as $k => $v)
 		{
 			$cases .= $k.' = CASE '."\n";
 			foreach ($v as $row)
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 64f53cc..14df104 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -253,7 +253,7 @@
 		$sql = "begin $package.$procedure(";
 
 		$have_cursor = FALSE;
-		foreach($params as $param)
+		foreach ($params as $param)
 		{
 			$sql .= $param['name'] . ",";
 
@@ -395,7 +395,7 @@
 	{
 		if (is_array($str))
 		{
-			foreach($str as $key => $val)
+			foreach ($str as $key => $val)
 			{
 				$str[$key] = $this->escape_str($val, $like);
 			}
@@ -655,7 +655,7 @@
 	 */
 	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
 			$valstr[] = $key." = ".$val;
 		}
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index c8e03c3..81e0d7c 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -264,7 +264,7 @@
 	{
 		if (is_array($str))
 		{
-			foreach($str as $key => $val)
+			foreach ($str as $key => $val)
 			{
 				$str[$key] = $this->escape_str($val, $like);
 			}
@@ -523,7 +523,7 @@
 	 */
 	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
 			$valstr[] = $key." = ".$val;
 		}
diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php
index a81a2b8..5d64a46 100644
--- a/system/database/drivers/odbc/odbc_result.php
+++ b/system/database/drivers/odbc/odbc_result.php
@@ -188,7 +188,7 @@
 	 */
 	function _odbc_fetch_object(& $odbc_result) {
 		$rs = array();
-		$rs_obj = false;
+		$rs_obj = FALSE;
 		if (odbc_fetch_into($odbc_result, $rs)) {
 			foreach ($rs as $k=>$v) {
 				$field_name= odbc_field_name($odbc_result, $k+1);
@@ -210,7 +210,7 @@
 	 */
 	function _odbc_fetch_array(& $odbc_result) {
 		$rs = array();
-		$rs_assoc = false;
+		$rs_assoc = FALSE;
 		if (odbc_fetch_into($odbc_result, $rs)) {
 			$rs_assoc=array();
 			foreach ($rs as $k=>$v) {
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 0bb7974..47ff362 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -283,7 +283,7 @@
 	{
 		if (is_array($str))
 		{
-			foreach($str as $key => $val)
+			foreach ($str as $key => $val)
 			{
 				$str[$key] = $this->escape_str($val, $like);
 			}
@@ -330,21 +330,21 @@
 		$v = $this->_version();
 		$v = $v['server'];
 
-		$table	= func_num_args() > 0 ? func_get_arg(0) : null;
-		$column	= func_num_args() > 1 ? func_get_arg(1) : null;
+		$table	= func_num_args() > 0 ? func_get_arg(0) : NULL;
+		$column	= func_num_args() > 1 ? func_get_arg(1) : NULL;
 
-		if ($table == null && $v >= '8.1')
+		if ($table == NULL && $v >= '8.1')
 		{
 			$sql='SELECT LASTVAL() as ins_id';
 		}
-		elseif ($table != null && $column != null && $v >= '8.0')
+		elseif ($table != NULL && $column != NULL && $v >= '8.0')
 		{
 			$sql = sprintf("SELECT pg_get_serial_sequence('%s','%s') as seq", $table, $column);
 			$query = $this->query($sql);
 			$row = $query->row();
 			$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $row->seq);
 		}
-		elseif ($table != null)
+		elseif ($table != NULL)
 		{
 			// seq_name passed in table parameter
 			$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
@@ -568,7 +568,7 @@
 	 */
 	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
 			$valstr[] = $key." = ".$val;
 		}
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index 5bfc1f5..eb4e585 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_driver.php
@@ -280,7 +280,7 @@
 	{
 		if (is_array($str))
 		{
-			foreach($str as $key => $val)
+			foreach ($str as $key => $val)
 			{
 				$str[$key] = $this->escape_str($val, $like);
 			}
@@ -537,7 +537,7 @@
 	 */
 	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
 			$valstr[] = $key." = ".$val;
 		}
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index c0e3798..19ec0c7 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -87,7 +87,7 @@
 
 		$current_dir = @opendir($img_path);
 
-		while($filename = @readdir($current_dir))
+		while ($filename = @readdir($current_dir))
 		{
 			if ($filename != "." and $filename != ".." and $filename != "index.html")
 			{
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
index 7701d50..7cee028 100644
--- a/system/helpers/cookie_helper.php
+++ b/system/helpers/cookie_helper.php
@@ -44,11 +44,11 @@
  */
 if ( ! function_exists('set_cookie'))
 {
-	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '')
+	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
 	{
 		// Set the config file options
 		$CI =& get_instance();
-		$CI->input->set_cookie($name, $value, $expire, $domain, $path, $prefix);
+		$CI->input->set_cookie($name, $value, $expire, $domain, $path, $prefix, $secure);
 	}
 }
 
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 334eef8..9518e48 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -128,7 +128,7 @@
 			return FALSE;
 		}
 
-		while(FALSE !== ($filename = @readdir($current_dir)))
+		while (FALSE !== ($filename = @readdir($current_dir)))
 		{
 			if ($filename != "." and $filename != "..")
 			{
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
index ed9ab5f..4cd7486 100644
--- a/system/helpers/inflector_helper.php
+++ b/system/helpers/inflector_helper.php
@@ -93,7 +93,7 @@
 		}
 		elseif ($end == 'h')
 		{
-			if (substr($str, -2) == 'ch' || substr($str, -2) == 'sh')
+			if (substr($str, -2) == 'ch' OR substr($str, -2) == 'sh')
 			{
 				$str .= 'es';
 			}
diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php
index 68c1a1f..ac0d69d 100644
--- a/system/helpers/language_helper.php
+++ b/system/helpers/language_helper.php
@@ -1,4 +1,4 @@
-<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php
index a2caea5..6117775 100644
--- a/system/helpers/number_helper.php
+++ b/system/helpers/number_helper.php
@@ -1,4 +1,4 @@
-<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
index 80a8d79..463881f 100644
--- a/system/helpers/smiley_helper.php
+++ b/system/helpers/smiley_helper.php
@@ -59,7 +59,7 @@
 
 				if (is_array($alias))
 				{
-					foreach($alias as $name => $id)
+					foreach ($alias as $name => $id)
 					{
 						$m[] = '"'.$name.'" : "'.$id.'"';
 					}
@@ -101,7 +101,7 @@
 		{
 			if (is_array($alias))
 			{
-				foreach($alias as $name => $id)
+				foreach ($alias as $name => $id)
 				{
 					$r .= 'smiley_map["'.$name.'"] = "'.$id.'";'."\n";
 				}
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
index e1b56c9..96afd4c 100644
--- a/system/helpers/text_helper.php
+++ b/system/helpers/text_helper.php
@@ -364,30 +364,21 @@
  */
 if ( ! function_exists('convert_accented_characters'))
 {
-	function convert_accented_characters($match)
+	function convert_accented_characters($str)
 	{
 		if ( ! file_exists(APPPATH.'config/foreign_chars'.EXT))
 		{
-			return $match;
+			return $str;
 		}
 
 		include APPPATH.'config/foreign_chars'.EXT;
 
 		if ( ! isset($foreign_characters))
 		{
-			return $match;
+			return $str;
 		}
 
-		$ord = ord($match['1']);
-
-		if (isset($foreign_characters[$ord]))
-		{
-			return $foreign_characters[$ord];
-		}
-		else
-		{
-			return $match['1'];
-		}
+		return preg_replace(array_keys($foreign_characters), array_values($foreign_characters), $str);
 	}
 }
 
@@ -452,7 +443,7 @@
 			}
 
 			$temp = '';
-			while((strlen($line)) > $charlim)
+			while ((strlen($line)) > $charlim)
 			{
 				// If the over-length word is a URL we won't wrap it
 				if (preg_match("!\[url.+\]|://|wwww.!", $line))
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index 99ed70a..b018850 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -15,6 +15,7 @@
 $lang['numeric']			= "The %s field must contain only numbers.";
 $lang['is_numeric']			= "The %s field must contain only numeric characters.";
 $lang['integer']			= "The %s field must contain an integer.";
+$lang['regex_match']		= "The %s field is not in the correct format.";
 $lang['matches']			= "The %s field does not match the %s field.";
 $lang['is_natural']			= "The %s field must contain only positive numbers.";
 $lang['is_natural_no_zero']	= "The %s field must contain a number greater than zero.";
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
new file mode 100644
index 0000000..d3f6105
--- /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 - 2011 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..4b995c7
--- /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 - 2011 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($data, $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..74f6892
--- /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 - 2011 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..86d1a3b
--- /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 - 2011 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 == '') ? APPPATH.'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..5f5a315
--- /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 - 2011 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($data, $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/Driver.php b/system/libraries/Driver.php
index 15fc3da..02e093d 100644
--- a/system/libraries/Driver.php
+++ b/system/libraries/Driver.php
@@ -1,4 +1,4 @@
-<?php  if (!defined('BASEPATH')) exit('No direct script access allowed');
+<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
@@ -36,7 +36,7 @@
 	// subsequents calls will go straight to the proper child.
 	function __get($child)
 	{
-		if (! isset($this->lib_name))
+		if ( ! isset($this->lib_name))
 		{
 			$this->lib_name = get_class($this);
 		}
@@ -143,7 +143,7 @@
 				}
 			}
 
-			foreach($r->getProperties() as $prop)
+			foreach ($r->getProperties() as $prop)
 			{
 				if ($prop->isPublic())
 				{
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index c6d8944..6c21f11 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -82,7 +82,7 @@
 	 *
 	 * The constructor can be passed an array of config values
 	 */
-	function __construct($config = array())
+	public function __construct($config = array())
 	{
 		if (count($config) > 0)
 		{
@@ -106,9 +106,8 @@
 	 * @param	array
 	 * @return	void
 	 */
-	function initialize($config = array())
+	public function initialize($config = array())
 	{
-		$this->clear();
 		foreach ($config as $key => $val)
 		{
 			if (isset($this->$key))
@@ -125,9 +124,12 @@
 				}
 			}
 		}
+		$this->clear();
 
 		$this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
 		$this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE;
+
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -138,7 +140,7 @@
 	 * @access	public
 	 * @return	void
 	 */
-	function clear($clear_attachments = FALSE)
+	public function clear($clear_attachments = FALSE)
 	{
 		$this->_subject		= "";
 		$this->_body		= "";
@@ -160,7 +162,7 @@
 			$this->_attach_type = array();
 			$this->_attach_disp = array();
 		}
-		
+
 		return $this;
 	}
 
@@ -174,7 +176,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function from($from, $name = '')
+	public function from($from, $name = '')
 	{
 		if (preg_match( '/\<(.*)\>/', $from, $match))
 		{
@@ -203,7 +205,7 @@
 
 		$this->_set_header('From', $name.' <'.$from.'>');
 		$this->_set_header('Return-Path', '<'.$from.'>');
-		
+
 		return $this;
 	}
 
@@ -217,7 +219,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function reply_to($replyto, $name = '')
+	public function reply_to($replyto, $name = '')
 	{
 		if (preg_match( '/\<(.*)\>/', $replyto, $match))
 		{
@@ -254,7 +256,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function to($to)
+	public function to($to)
 	{
 		$to = $this->_str_to_array($to);
 		$to = $this->clean_email($to);
@@ -271,14 +273,15 @@
 
 		switch ($this->_get_protocol())
 		{
-			case 'smtp'		: $this->_recipients = $to;
+			case 'smtp'		:
+				$this->_recipients = $to;
 			break;
-			case 'sendmail'	: $this->_recipients = implode(", ", $to);
-			break;
-			case 'mail'		: $this->_recipients = implode(", ", $to);
+			case 'sendmail'	:
+			case 'mail'		:
+				$this->_recipients = implode(", ", $to);
 			break;
 		}
-		
+
 		return $this;
 	}
 
@@ -291,7 +294,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function cc($cc)
+	public function cc($cc)
 	{
 		$cc = $this->_str_to_array($cc);
 		$cc = $this->clean_email($cc);
@@ -307,7 +310,7 @@
 		{
 			$this->_cc_array = $cc;
 		}
-		
+
 		return $this;
 	}
 
@@ -321,7 +324,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function bcc($bcc, $limit = '')
+	public function bcc($bcc, $limit = '')
 	{
 		if ($limit != '' && is_numeric($limit))
 		{
@@ -345,7 +348,7 @@
 		{
 			$this->_set_header('Bcc', implode(", ", $bcc));
 		}
-		
+
 		return $this;
 	}
 
@@ -358,7 +361,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function subject($subject)
+	public function subject($subject)
 	{
 		$subject = $this->_prep_q_encoding($subject);
 		$this->_set_header('Subject', $subject);
@@ -374,7 +377,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function message($body)
+	public function message($body)
 	{
 		$this->_body = stripslashes(rtrim(str_replace("\r", "", $body)));
 		return $this;
@@ -389,7 +392,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function attach($filename, $disposition = 'attachment')
+	public function attach($filename, $disposition = 'attachment')
 	{
 		$this->_attach_name[] = $filename;
 		$this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename))));
@@ -407,7 +410,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function _set_header($header, $value)
+	private function _set_header($header, $value)
 	{
 		$this->_headers[$header] = $value;
 	}
@@ -421,7 +424,7 @@
 	 * @param	string
 	 * @return	array
 	 */
-	function _str_to_array($email)
+	private function _str_to_array($email)
 	{
 		if ( ! is_array($email))
 		{
@@ -447,7 +450,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function set_alt_message($str = '')
+	public function set_alt_message($str = '')
 	{
 		$this->alt_message = ($str == '') ? '' : $str;
 		return $this;
@@ -462,7 +465,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function set_mailtype($type = 'text')
+	public function set_mailtype($type = 'text')
 	{
 		$this->mailtype = ($type == 'html') ? 'html' : 'text';
 		return $this;
@@ -477,7 +480,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function set_wordwrap($wordwrap = TRUE)
+	public function set_wordwrap($wordwrap = TRUE)
 	{
 		$this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE;
 		return $this;
@@ -492,7 +495,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function set_protocol($protocol = 'mail')
+	public function set_protocol($protocol = 'mail')
 	{
 		$this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);
 		return $this;
@@ -507,7 +510,7 @@
 	 * @param	integer
 	 * @return	void
 	 */
-	function set_priority($n = 3)
+	public function set_priority($n = 3)
 	{
 		if ( ! is_numeric($n))
 		{
@@ -534,7 +537,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function set_newline($newline = "\n")
+	public function set_newline($newline = "\n")
 	{
 		if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r")
 		{
@@ -543,7 +546,7 @@
 		}
 
 		$this->newline	= $newline;
-		
+
 		return $this;
 	}
 
@@ -556,7 +559,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	function set_crlf($crlf = "\n")
+	public function set_crlf($crlf = "\n")
 	{
 		if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r")
 		{
@@ -565,7 +568,7 @@
 		}
 
 		$this->crlf	= $crlf;
-		
+
 		return $this;
 	}
 
@@ -577,7 +580,7 @@
 	 * @access	private
 	 * @return	void
 	 */
-	function _set_boundaries()
+	private function _set_boundaries()
 	{
 		$this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative
 		$this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary
@@ -591,7 +594,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _get_message_id()
+	private function _get_message_id()
 	{
 		$from = $this->_headers['Return-Path'];
 		$from = str_replace(">", "", $from);
@@ -609,7 +612,7 @@
 	 * @param	bool
 	 * @return	string
 	 */
-	function _get_protocol($return = TRUE)
+	private function _get_protocol($return = TRUE)
 	{
 		$this->protocol = strtolower($this->protocol);
 		$this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;
@@ -629,7 +632,7 @@
 	 * @param	bool
 	 * @return	string
 	 */
-	function _get_encoding($return = TRUE)
+	private function _get_encoding($return = TRUE)
 	{
 		$this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;
 
@@ -655,7 +658,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _get_content_type()
+	private function _get_content_type()
 	{
 		if	($this->mailtype == 'html' &&  count($this->_attach_name) == 0)
 		{
@@ -683,7 +686,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _set_date()
+	private function _set_date()
 	{
 		$timezone = date("Z");
 		$operator = (strncmp($timezone, '-', 1) == 0) ? '-' : '+';
@@ -701,7 +704,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _get_mime_message()
+	private function _get_mime_message()
 	{
 		return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";
 	}
@@ -715,7 +718,7 @@
 	 * @param	string
 	 * @return	bool
 	 */
-	function validate_email($email)
+	public function validate_email($email)
 	{
 		if ( ! is_array($email))
 		{
@@ -744,7 +747,7 @@
 	 * @param	string
 	 * @return	bool
 	 */
-	function valid_email($address)
+	public function valid_email($address)
 	{
 		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;
 	}
@@ -758,7 +761,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function clean_email($email)
+	public function clean_email($email)
 	{
 		if ( ! is_array($email))
 		{
@@ -794,7 +797,7 @@
 	/**
 	 * Build alternative plain text message
 	 *
-	 * This function provides the raw message for use
+	 * This public function provides the raw message for use
 	 * in plain-text headers of HTML-formatted emails.
 	 * If the user hasn't specified his own alternative message
 	 * it creates one by stripping the HTML
@@ -802,7 +805,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _get_alt_message()
+	private function _get_alt_message()
 	{
 		if ($this->alt_message != "")
 		{
@@ -847,7 +850,7 @@
 	 * @param	integer
 	 * @return	string
 	 */
-	function word_wrap($str, $charlim = '')
+	public function word_wrap($str, $charlim = '')
 	{
 		// Se the character limit
 		if ($charlim == '')
@@ -876,7 +879,7 @@
 			}
 		}
 
-		// Use PHP's native function to do the initial wordwrap.
+		// Use PHP's native public function to do the initial wordwrap.
 		// We set the cut flag to FALSE so that any individual words that are
 		// too long get left alone.  In the next step we'll deal with them.
 		$str = wordwrap($str, $charlim, "\n", FALSE);
@@ -894,7 +897,7 @@
 			}
 
 			$temp = '';
-			while((strlen($line)) > $charlim)
+			while ((strlen($line)) > $charlim)
 			{
 				// If the over-length word is a URL we won't wrap it
 				if (preg_match("!\[url.+\]|://|wwww.!", $line))
@@ -942,7 +945,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function _build_headers()
+	private function _build_headers()
 	{
 		$this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));
 		$this->_set_header('X-Mailer', $this->useragent);
@@ -959,7 +962,7 @@
 	 * @access	private
 	 * @return	void
 	 */
-	function _write_headers()
+	private function _write_headers()
 	{
 		if ($this->protocol == 'mail')
 		{
@@ -970,7 +973,7 @@
 		reset($this->_headers);
 		$this->_header_str = "";
 
-		foreach($this->_headers as $key => $val)
+		foreach ($this->_headers as $key => $val)
 		{
 			$val = trim($val);
 
@@ -994,7 +997,7 @@
 	 * @access	private
 	 * @return	void
 	 */
-	function _build_message()
+	private function _build_message()
 	{
 		if ($this->wordwrap === TRUE  AND  $this->mailtype != 'html')
 		{
@@ -1023,7 +1026,7 @@
 				{
 					$this->_finalbody = $hdr . $this->newline . $this->newline . $this->_body;
 				}
-				
+
 				return;
 
 			break;
@@ -1048,10 +1051,10 @@
 					$body .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
 					$body .= "Content-Transfer-Encoding: quoted-printable" . $this->newline . $this->newline;
 				}
-				
+
 				$this->_finalbody = $body . $this->_prep_quoted_printable($this->_body) . $this->newline . $this->newline;
-				
-				
+
+
 				if ($this->_get_protocol() == 'mail')
 				{
 					$this->_header_str .= $hdr;
@@ -1077,8 +1080,8 @@
 				if ($this->_get_protocol() == 'mail')
 				{
 					$this->_header_str .= $hdr;
-				}				
-				
+				}
+
 				$body .= $this->_get_mime_message() . $this->newline . $this->newline;
 				$body .= "--" . $this->_atc_boundary . $this->newline;
 
@@ -1091,7 +1094,7 @@
 			case 'html-attach' :
 
 				$hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline . $this->newline;
-				
+
 				if ($this->_get_protocol() == 'mail')
 				{
 					$this->_header_str .= $hdr;
@@ -1152,7 +1155,7 @@
 		}
 
 		$body .= implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
-		
+
 
 		if ($this->_get_protocol() == 'mail')
 		{
@@ -1162,7 +1165,7 @@
 		{
 			$this->_finalbody = $hdr . $body;
 		}
-		
+
 		return;
 	}
 
@@ -1179,7 +1182,7 @@
 	 * @param	integer
 	 * @return	string
 	 */
-	function _prep_quoted_printable($str, $charlim = '')
+	private function _prep_quoted_printable($str, $charlim = '')
 	{
 		// Set the character limit
 		// Don't allow over 76, as that will make servers and MUAs barf
@@ -1272,7 +1275,7 @@
 	 * @param	bool	// set to TRUE for processing From: headers
 	 * @return	str
 	 */
-	function _prep_q_encoding($str, $from = FALSE)
+	private function _prep_q_encoding($str, $from = FALSE)
 	{
 		$str = str_replace(array("\r", "\n"), array('', ''), $str);
 
@@ -1339,7 +1342,7 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function send()
+	public function send()
 	{
 		if ($this->_replyto_flag == FALSE)
 		{
@@ -1382,7 +1385,7 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function batch_bcc_send()
+	public function batch_bcc_send()
 	{
 		$float = $this->bcc_batch_size -1;
 
@@ -1440,7 +1443,7 @@
 	 * @access	private
 	 * @return	void
 	 */
-	function _unwrap_specials()
+	private function _unwrap_specials()
 	{
 		$this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);
 	}
@@ -1453,7 +1456,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _remove_nl_callback($matches)
+	private function _remove_nl_callback($matches)
 	{
 		if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE)
 		{
@@ -1471,7 +1474,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _spool_email()
+	private function _spool_email()
 	{
 		$this->_unwrap_specials();
 
@@ -1516,7 +1519,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _send_with_mail()
+	private function _send_with_mail()
 	{
 		if ($this->_safe_mode == TRUE)
 		{
@@ -1533,7 +1536,7 @@
 		{
 			// most documentation of sendmail using the "-f" flag lacks a space after it, however
 			// we've encountered servers that seem to require it to be in place.
-						
+
 			if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From'])))
 			{
 				return FALSE;
@@ -1553,7 +1556,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _send_with_sendmail()
+	private function _send_with_sendmail()
 	{
 		$fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');
 
@@ -1567,7 +1570,7 @@
 		fputs($fp, $this->_finalbody);
 
 		$status = pclose($fp);
-	
+
 		if (version_compare(PHP_VERSION, '4.2.3') == -1)
 		{
 			$status = $status >> 8 & 0xFF;
@@ -1591,7 +1594,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _send_with_smtp()
+	private function _send_with_smtp()
 	{
 		if ($this->smtp_host == '')
 		{
@@ -1604,14 +1607,14 @@
 
 		$this->_send_command('from', $this->clean_email($this->_headers['From']));
 
-		foreach($this->_recipients as $val)
+		foreach ($this->_recipients as $val)
 		{
 			$this->_send_command('to', $val);
 		}
 
 		if (count($this->_cc_array) > 0)
 		{
-			foreach($this->_cc_array as $val)
+			foreach ($this->_cc_array as $val)
 			{
 				if ($val != "")
 				{
@@ -1622,7 +1625,7 @@
 
 		if (count($this->_bcc_array) > 0)
 		{
-			foreach($this->_bcc_array as $val)
+			foreach ($this->_bcc_array as $val)
 			{
 				if ($val != "")
 				{
@@ -1661,7 +1664,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function _smtp_connect()
+	private function _smtp_connect()
 	{
 		$this->_smtp_connect = fsockopen($this->smtp_host,
 										$this->smtp_port,
@@ -1669,7 +1672,7 @@
 										$errstr,
 										$this->smtp_timeout);
 
-		if( ! is_resource($this->_smtp_connect))
+		if ( ! is_resource($this->_smtp_connect))
 		{
 			$this->_set_error_message('email_smtp_error', $errno." ".$errstr);
 			return FALSE;
@@ -1689,7 +1692,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function _send_command($cmd, $data = '')
+	private function _send_command($cmd, $data = '')
 	{
 		switch ($cmd)
 		{
@@ -1754,7 +1757,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _smtp_authenticate()
+	private function _smtp_authenticate()
 	{
 		if ( ! $this->_smtp_auth)
 		{
@@ -1808,7 +1811,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _send_data($data)
+	private function _send_data($data)
 	{
 		if ( ! fwrite($this->_smtp_connect, $data . $this->newline))
 		{
@@ -1829,7 +1832,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _get_smtp_data()
+	private function _get_smtp_data()
 	{
 		$data = "";
 
@@ -1854,7 +1857,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _get_hostname()
+	private function _get_hostname()
 	{
 		return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
 	}
@@ -1867,7 +1870,7 @@
 	 * @access	private
 	 * @return	string
 	 */
-	function _get_ip()
+	private function _get_ip()
 	{
 		if ($this->_IP !== FALSE)
 		{
@@ -1909,7 +1912,7 @@
 	 * @access	public
 	 * @return	string
 	 */
-	function print_debugger()
+	public function print_debugger()
 	{
 		$msg = '';
 
@@ -1934,7 +1937,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function _set_error_message($msg, $val = '')
+	private function _set_error_message($msg, $val = '')
 	{
 		$CI =& get_instance();
 		$CI->lang->load('email');
@@ -1958,7 +1961,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function _mime_types($ext = "")
+	private function _mime_types($ext = "")
 	{
 		$mimes = array(	'hqx'	=>	'application/mac-binhex40',
 						'cpt'	=>	'application/mac-compactpro',
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index cbefca1..adfd17d 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -138,14 +138,14 @@
 
 		// Build our master array
 		$this->_field_data[$field] = array(
-											'field'				=> $field,
-											'label'				=> $label,
-											'rules'				=> $rules,
-											'is_array'			=> $is_array,
-											'keys'				=> $indexes,
-											'postdata'			=> NULL,
-											'error'				=> ''
-											);
+			'field'				=> $field,
+			'label'				=> $label,
+			'rules'				=> $rules,
+			'is_array'			=> $is_array,
+			'keys'				=> $indexes,
+			'postdata'			=> NULL,
+			'error'				=> ''
+		);
 
 		return $this;
 	}
@@ -171,7 +171,7 @@
 		}
 
 		$this->_error_messages = array_merge($this->_error_messages, $lang);
-		
+
 		return $this;
 	}
 
@@ -191,7 +191,7 @@
 	{
 		$this->_error_prefix = $prefix;
 		$this->_error_suffix = $suffix;
-		
+
 		return $this;
 	}
 
@@ -576,7 +576,7 @@
 			// Strip the parameter (if exists) from the rule
 			// Rules can contain a parameter: max_length[5]
 			$param = FALSE;
-			if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match))
+			if (preg_match("/(.*?)\[(.*)\]/", $rule, $match))
 			{
 				$rule	= $match[1];
 				$param	= $match[2];
@@ -730,6 +730,13 @@
 			return $default;
 		}
 
+		// If the data is an array output them one at a time.
+		//     E.g: form_input('name[]', set_value('name[]');
+		if (is_array($this->_field_data[$field]['postdata']))
+		{
+			return array_shift($this->_field_data[$field]['postdata']);
+		}
+
 		return $this->_field_data[$field]['postdata'];
 	}
 
@@ -889,6 +896,26 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Performs a Regular Expression match test.
+	 *
+	 * @access	public
+	 * @param	string
+	 * @param	regex
+	 * @return	bool
+	 */
+	function regex_match($str, $regex)
+	{
+		if ( ! preg_match($regex, $str))
+		{
+			return FALSE;
+		}
+
+		return  TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Match one field to another
 	 *
 	 * @access	public
@@ -1013,7 +1040,7 @@
 			return $this->valid_email(trim($str));
 		}
 
-		foreach(explode(',', $str) as $email)
+		foreach (explode(',', $str) as $email)
 		{
 			if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
 			{
@@ -1120,7 +1147,57 @@
 	 */
 	function integer($str)
 	{
-		return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str);
+		return (bool) preg_match('/^[\-+]?[0-9]+$/', $str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Decimal number
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function decimal($str)
+	{
+		return (bool) preg_match('/^[\-+]?[0-9]+\.[0-9]+$/', $str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Greather than
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function greater_than($str, $min)
+	{
+		if ( ! is_numeric($str))
+		{
+			return FALSE;
+		}
+		return $str > $min;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Less than
+	 *
+	 * @access	public
+	 * @param	string
+	 * @return	bool
+	 */
+	function less_than($str, $max)
+	{
+		if ( ! is_numeric($str))
+		{
+			return FALSE;
+		}
+		return $str < $max;
 	}
 
 	// --------------------------------------------------------------------
@@ -1134,7 +1211,7 @@
 	 */
 	function is_natural($str)
 	{
-		return (bool)preg_match( '/^[0-9]+$/', $str);
+		return (bool) preg_match( '/^[0-9]+$/', $str);
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 41f9ad3..8902f52 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -749,7 +749,7 @@
 
 		@chmod($this->full_dst_path, FILE_WRITE_MODE);
 
-		return true;
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 6587eae..8a1f18c 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -415,7 +415,7 @@
 
 		$output .= "\n\n<table style='width:100%'>\n";
 
-		foreach(array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR') as $header)
+		foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR') as $header)
 		{
 			$val = (isset($_SERVER[$header])) ? $_SERVER[$header] : '';
 			$output .= "<tr><td style='vertical-align: top;width:50%;padding:5px;color:#900;background-color:#ddd;'>".$header."&nbsp;&nbsp;</td><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>".$val."</td></tr>\n";
@@ -446,7 +446,7 @@
 
 		$output .= "\n\n<table style='width:100%'>\n";
 
-		foreach($this->CI->config->config as $config=>$val)
+		foreach ($this->CI->config->config as $config=>$val)
 		{
 			if (is_array($val))
 			{
diff --git a/system/libraries/Security.php b/system/libraries/Security.php
index a73b8e1..58db4e7 100644
--- a/system/libraries/Security.php
+++ b/system/libraries/Security.php
@@ -25,14 +25,15 @@
  * @link		http://codeigniter.com/user_guide/libraries/sessions.html
  */
 class CI_Security {
-	var $xss_hash			= '';
-	var $csrf_hash			= '';
-	var $csrf_expire		= 7200;  // Two hours (in seconds)
-	var $csrf_token_name	= 'ci_csrf_token';
-	var $csrf_cookie_name	= 'ci_csrf_token';
+
+	public $xss_hash			= '';
+	public $csrf_hash			= '';
+	public $csrf_expire			= 7200;  // Two hours (in seconds)
+	public $csrf_token_name		= 'ci_csrf_token';
+	public $csrf_cookie_name	= 'ci_csrf_token';
 
 	/* never allowed, string replacement */
-	var $never_allowed_str = array(
+	public $never_allowed_str = array(
 									'document.cookie'	=> '[removed]',
 									'document.write'	=> '[removed]',
 									'.parentNode'		=> '[removed]',
@@ -44,7 +45,7 @@
 									'<![CDATA['			=> '&lt;![CDATA['
 									);
 	/* never allowed, regex replacement */
-	var $never_allowed_regex = array(
+	public $never_allowed_regex = array(
 										"javascript\s*:"			=> '[removed]',
 										"expression\s*(\(|&\#40;)"	=> '[removed]', // CSS and IE
 										"vbscript\s*:"				=> '[removed]', // IE, surprise!
@@ -53,6 +54,10 @@
 
 	public function __construct()
 	{
+		$this->csrf_token_name = (config_item('csrf_token_name')) ? config_item('csrf_token_name') : 'csrf_token_name';
+		$this->csrf_cookie_name = (config_item('csrf_cookie_name')) ? config_item('csrf_cookie_name') : 'csrf_cookie_name';
+		$this->csrf_expire = (config_item('csrf_expire')) ? config_item('csrf_expire') : 7200;
+
 		// Append application specific cookie prefix to token name
 		$this->csrf_cookie_name = (config_item('cookie_prefix')) ? config_item('cookie_prefix').$this->csrf_token_name : $this->csrf_token_name;
 
@@ -70,7 +75,7 @@
 	 * @access	public
 	 * @return	null
 	 */
-	function csrf_verify()
+	public function csrf_verify()
 	{
 		// If no POST data exists we will set the CSRF cookie
 		if (count($_POST) == 0)
@@ -109,7 +114,7 @@
 	 * @access	public
 	 * @return	null
 	 */
-	function csrf_set_cookie()
+	public function csrf_set_cookie()
 	{
 		$expire = time() + $this->csrf_expire;
 		$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
@@ -124,10 +129,10 @@
 	/**
 	 * Set Cross Site Request Forgery Protection Cookie
 	 *
-	 * @access	public
+	 * @access	private
 	 * @return	null
 	 */
-	function _csrf_set_hash()
+	private function _csrf_set_hash()
 	{
 		if ($this->csrf_hash == '')
 		{
@@ -154,7 +159,7 @@
 	 * @access	public
 	 * @return	null
 	 */
-	function csrf_show_error()
+	public function csrf_show_error()
 	{
 		show_error('The action you have requested is not allowed.');
 	}
@@ -187,7 +192,7 @@
 	 * @param	mixed	string or array
 	 * @return	string
 	 */
-	function xss_clean($str, $is_image = FALSE)
+	public function xss_clean($str, $is_image = FALSE)
 	{
 		/*
 		 * Is the string an array?
@@ -211,9 +216,9 @@
 		/*
 		 * Protect GET variables in URLs
 		 */
-		
+
 		 // 901119URL5918AMP18930PROTECT8198
-		
+
 		$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash()."\\1=\\2", $str);
 
 		/*
@@ -260,7 +265,7 @@
 		 */
 
 		$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
-	
+
 		$str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_decode_entity'), $str);
 
 		/*
@@ -369,7 +374,7 @@
 				$str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);
 			}
 		}
-		while($original != $str);
+		while ($original != $str);
 
 		unset($original);
 
@@ -471,7 +476,7 @@
 	 * @access	public
 	 * @return	string
 	 */
-	function xss_hash()
+	public function xss_hash()
 	{
 		if ($this->xss_hash == '')
 		{
@@ -494,11 +499,11 @@
 	 * Callback function for xss_clean() to remove whitespace from
 	 * things like j a v a s c r i p t
 	 *
-	 * @access	public
+	 * @access	private
 	 * @param	type
 	 * @return	type
 	 */
-	function _compact_exploded_words($matches)
+	private function _compact_exploded_words($matches)
 	{
 		return preg_replace('/\s+/s', '', $matches[1]).$matches[2];
 	}
@@ -514,7 +519,7 @@
 	 * @param	array
 	 * @return	string
 	 */
-	function _sanitize_naughty_html($matches)
+	private function _sanitize_naughty_html($matches)
 	{
 		// encode opening brace
 		$str = '&lt;'.$matches[1].$matches[2].$matches[3];
@@ -539,7 +544,7 @@
 	 * @param	array
 	 * @return	string
 	 */
-	function _js_link_removal($match)
+	private function _js_link_removal($match)
 	{
 		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
 		return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);
@@ -557,7 +562,7 @@
 	 * @param	array
 	 * @return	string
 	 */
-	function _js_img_removal($match)
+	private function _js_img_removal($match)
 	{
 		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
 		return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);
@@ -570,11 +575,11 @@
 	 *
 	 * Used as a callback for XSS Clean
 	 *
-	 * @access	public
+	 * @access	private
 	 * @param	array
 	 * @return	string
 	 */
-	function _convert_attribute($match)
+	private function _convert_attribute($match)
 	{
 		return str_replace(array('>', '<', '\\'), array('&gt;', '&lt;', '\\\\'), $match[0]);
 	}
@@ -586,11 +591,11 @@
 	 *
 	 * Filters tag attributes for consistency and safety
 	 *
-	 * @access	public
+	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	function _filter_attributes($str)
+	private function _filter_attributes($str)
 	{
 		$out = '';
 
@@ -612,11 +617,11 @@
 	 *
 	 * Used as a callback for XSS Clean
 	 *
-	 * @access	public
+	 * @access	private
 	 * @param	array
 	 * @return	string
 	 */
-	function _decode_entity($match)
+	private function _decode_entity($match)
 	{
 		return $this->entity_decode($match[0], strtoupper(config_item('charset')));
 	}
@@ -642,7 +647,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function entity_decode($str, $charset='UTF-8')
+	public function entity_decode($str, $charset='UTF-8')
 	{
 		if (stristr($str, '&') === FALSE) return $str;
 
@@ -681,7 +686,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function sanitize_filename($str, $relative_path = FALSE)
+	public function sanitize_filename($str, $relative_path = FALSE)
 	{
 		$bad = array(
 						"../",
@@ -716,7 +721,7 @@
 						"%3b",		// ;
 						"%3d"		// =
 					);
-		
+
 		if ( ! $relative_path)
 		{
 			$bad[] = './';
diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 0b94340..1822940 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -37,6 +37,7 @@
 	var $cookie_prefix				= '';
 	var $cookie_path				= '';
 	var $cookie_domain				= '';
+	var $cookie_secure				= FALSE;
 	var $sess_time_to_update		= 300;
 	var $encryption_key				= '';
 	var $flashdata_key				= 'flash';
@@ -61,7 +62,7 @@
 
 		// Set all the session preferences, which can either be set
 		// manually via the $params array above or via the config file
-		foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)
+		foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'cookie_secure', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key)
 		{
 			$this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);
 		}
@@ -658,8 +659,6 @@
 		}
 
 		$expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();
-		
-		$secure_cookie = (config_item('cookie_secure') === TRUE) ? 1 : 0;
 
 		// Set the cookie
 		setcookie(
@@ -668,7 +667,7 @@
 					$expire,
 					$this->cookie_path,
 					$this->cookie_domain,
-					$secure_cookie
+					$this->cookie_secure
 				);
 	}
 
diff --git a/system/libraries/Sha1.php b/system/libraries/Sha1.php
index ad747a0..1a65757 100644
--- a/system/libraries/Sha1.php
+++ b/system/libraries/Sha1.php
@@ -42,7 +42,7 @@
  * @author		ExpressionEngine Dev Team
  * @link		http://codeigniter.com/user_guide/general/encryption.html
  */
-class CI_SHA {
+class CI_SHA1 {
 
 	public function __construct()
 	{
@@ -88,7 +88,7 @@
 			$oldd = $d;
 			$olde = $e;
 
-			for($j = 0; $j < 80; $j++)
+			for ($j = 0; $j < 80; $j++)
 			{
 				if ($j < 16)
 				{
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index cb2535e..def6967 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -108,7 +108,7 @@
 		}
 
 		$new = array();
-		while(count($array) > 0)
+		while (count($array) > 0)
 		{
 			$temp = array_splice($array, 0, $col_limit);
 
@@ -280,7 +280,7 @@
 			$out .= $this->template['heading_row_start'];
 			$out .= $this->newline;
 
-			foreach($this->heading as $heading)
+			foreach ($this->heading as $heading)
 			{
 				$temp = $this->template['heading_cell_start'];
 
@@ -310,7 +310,7 @@
 			$out .= $this->newline;
 
 			$i = 1;
-			foreach($this->rows as $row)
+			foreach ($this->rows as $row)
 			{
 				if ( ! is_array($row))
 				{
@@ -323,7 +323,7 @@
 				$out .= $this->template['row_'.$name.'start'];
 				$out .= $this->newline;
 
-				foreach($row as $cell)
+				foreach ($row as $cell)
 				{
 					$temp = $this->template['cell_'.$name.'start'];
 
@@ -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/Trackback.php b/system/libraries/Trackback.php
index e29b35c..b0a7678 100644
--- a/system/libraries/Trackback.php
+++ b/system/libraries/Trackback.php
@@ -94,7 +94,7 @@
 				{
 					$$item = $this->convert_ascii($$item);
 				}
-				elseif($item == 'blog_name')
+				elseif ($item == 'blog_name')
 				{
 					$$item = $this->convert_ascii($$item);
 				}
@@ -261,7 +261,7 @@
 		// Was it successful?
 		$this->response = "";
 
-		while( ! feof($fp))
+		while ( ! feof($fp))
 		{
 			$this->response .= fgets($fp, 128);
 		}
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 97343a1..e15ea1b 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -213,7 +213,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/system/libraries/User_agent.php b/system/libraries/User_agent.php
index 863faba..3774fc2 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -82,7 +82,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _load_agent_file()
+	private function _load_agent_file()
 	{
 		if ( ! @include(APPPATH.'config/user_agents'.EXT))
 		{
@@ -130,7 +130,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _compile_data()
+	private function _compile_data()
 	{
 		$this->_set_platform();
 
@@ -151,7 +151,7 @@
 	 * @access	private
 	 * @return	mixed
 	 */
-	function _set_platform()
+	private function _set_platform()
 	{
 		if (is_array($this->platforms) AND count($this->platforms) > 0)
 		{
@@ -175,7 +175,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _set_browser()
+	private function _set_browser()
 	{
 		if (is_array($this->browsers) AND count($this->browsers) > 0)
 		{
@@ -202,7 +202,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _set_robot()
+	private function _set_robot()
 	{
 		if (is_array($this->robots) AND count($this->robots) > 0)
 		{
@@ -227,7 +227,7 @@
 	 * @access	private
 	 * @return	bool
 	 */
-	function _set_mobile()
+	private function _set_mobile()
 	{
 		if (is_array($this->mobiles) AND count($this->mobiles) > 0)
 		{
@@ -252,7 +252,7 @@
 	 * @access	private
 	 * @return	void
 	 */
-	function _set_languages()
+	private function _set_languages()
 	{
 		if ((count($this->languages) == 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '')
 		{
@@ -275,7 +275,7 @@
 	 * @access	private
 	 * @return	void
 	 */
-	function _set_charsets()
+	private function _set_charsets()
 	{
 		if ((count($this->charsets) == 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '')
 		{
@@ -298,9 +298,21 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function is_browser()
+	public function is_browser($key = NULL)
 	{
-		return $this->is_browser;
+		if ( ! $this->is_browser)
+		{
+			return FALSE;
+		}
+
+		// No need to be specific, it's a browser
+		if ($key === NULL)
+		{
+			return TRUE;
+		}
+
+		// Check for a specific browser
+		return array_key_exists($key, $this->browsers) AND $this->browser === $this->browsers[$key];
 	}
 
 	// --------------------------------------------------------------------
@@ -311,9 +323,21 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function is_robot()
+	public function is_robot($key = NULL)
 	{
-		return $this->is_robot;
+		if ( ! $this->is_robot)
+		{
+			return FALSE;
+		}
+
+		// No need to be specific, it's a robot
+		if ($key === NULL)
+		{
+			return TRUE;
+		}
+
+		// Check for a specific robot
+		return array_key_exists($key, $this->robots) AND $this->robot === $this->robots[$key];
 	}
 
 	// --------------------------------------------------------------------
@@ -324,9 +348,21 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function is_mobile()
+	public function is_mobile($key = NULL)
 	{
-		return $this->is_mobile;
+		if ( ! $this->is_mobile)
+		{
+			return FALSE;
+		}
+
+		// No need to be specific, it's a mobile
+		if ($key === NULL)
+		{
+			return TRUE;
+		}
+
+		// Check for a specific robot
+		return array_key_exists($key, $this->mobiles) AND $this->mobile === $this->mobiles[$key];
 	}
 
 	// --------------------------------------------------------------------
@@ -337,9 +373,13 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function is_referral()
+	public function is_referral()
 	{
-		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE;
+		if ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '')
+		{
+			return FALSE;
+		}
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -350,7 +390,7 @@
 	 * @access	public
 	 * @return	string
 	 */
-	function agent_string()
+	public function agent_string()
 	{
 		return $this->agent;
 	}
@@ -363,7 +403,7 @@
 	 * @access	public
 	 * @return	string
 	 */
-	function platform()
+	public function platform()
 	{
 		return $this->platform;
 	}
@@ -376,7 +416,7 @@
 	 * @access	public
 	 * @return	string
 	 */
-	function browser()
+	public function browser()
 	{
 		return $this->browser;
 	}
@@ -389,7 +429,7 @@
 	 * @access	public
 	 * @return	string
 	 */
-	function version()
+	public function version()
 	{
 		return $this->version;
 	}
@@ -402,7 +442,7 @@
 	 * @access	public
 	 * @return	string
 	 */
-	function robot()
+	public function robot()
 	{
 		return $this->robot;
 	}
@@ -414,7 +454,7 @@
 	 * @access	public
 	 * @return	string
 	 */
-	function mobile()
+	public function mobile()
 	{
 		return $this->mobile;
 	}
@@ -427,7 +467,7 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function referrer()
+	public function referrer()
 	{
 		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']);
 	}
@@ -440,7 +480,7 @@
 	 * @access	public
 	 * @return	array
 	 */
-	function languages()
+	public function languages()
 	{
 		if (count($this->languages) == 0)
 		{
@@ -458,7 +498,7 @@
 	 * @access	public
 	 * @return	array
 	 */
-	function charsets()
+	public function charsets()
 	{
 		if (count($this->charsets) == 0)
 		{
@@ -476,9 +516,9 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function accept_lang($lang = 'en')
+	public function accept_lang($lang = 'en')
 	{
-		return (in_array(strtolower($lang), $this->languages(), TRUE)) ? TRUE : FALSE;
+		return (in_array(strtolower($lang), $this->languages(), TRUE));
 	}
 
 	// --------------------------------------------------------------------
@@ -489,12 +529,11 @@
 	 * @access	public
 	 * @return	bool
 	 */
-	function accept_charset($charset = 'utf-8')
+	public function accept_charset($charset = 'utf-8')
 	{
-		return (in_array(strtolower($charset), $this->charsets(), TRUE)) ? TRUE : FALSE;
+		return (in_array(strtolower($charset), $this->charsets(), TRUE));
 	}
 
-
 }
 
 
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 9cf307c..a24bca9 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -207,7 +207,7 @@
 
 		$this->data = array();
 
-		foreach($incoming as $key => $value)
+		foreach ($incoming as $key => $value)
 		{
 			$this->data[$key] = $this->values_parsing($value);
 		}
@@ -232,7 +232,7 @@
 	{
 		if (is_array($value) && array_key_exists(0, $value))
 		{
-			if ( ! isset($value['1']) OR (! isset($this->xmlrpcTypes[$value['1']])))
+			if ( ! isset($value['1']) OR ( ! isset($this->xmlrpcTypes[$value['1']])))
 			{
 				if (is_array($value[0]))
 				{
@@ -243,7 +243,7 @@
 					$temp = new XML_RPC_Values($value['0'], 'string');
 				}
 			}
-			elseif(is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))
+			elseif (is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))
 			{
 				while (list($k) = each($value['0']))
 				{
@@ -281,7 +281,7 @@
 			$this->error = $this->result->errstr;
 			return FALSE;
 		}
-		elseif( ! is_object($this->result->val))
+		elseif ( ! is_object($this->result->val))
 		{
 			$this->error = $this->result->errstr;
 			return FALSE;
@@ -358,7 +358,7 @@
 	var $errno			= '';
 	var $errstring		= '';
 	var $timeout		= 5;
-	var $no_multicall	= false;
+	var $no_multicall	= FALSE;
 
 	public function __construct($path, $server, $port=80)
 	{
@@ -392,7 +392,7 @@
 			return $r;
 		}
 
-		if(empty($msg->payload))
+		if (empty($msg->payload))
 		{
 			// $msg = XML_RPC_Messages
 			$msg->createPayload();
@@ -553,11 +553,11 @@
 	{
 		$kind = $xmlrpc_val->kindOf();
 
-		if($kind == 'scalar')
+		if ($kind == 'scalar')
 		{
 			return $xmlrpc_val->scalarval();
 		}
-		elseif($kind == 'array')
+		elseif ($kind == 'array')
 		{
 			reset($xmlrpc_val->me);
 			list($a,$b) = each($xmlrpc_val->me);
@@ -565,18 +565,18 @@
 
 			$arr = array();
 
-			for($i = 0; $i < $size; $i++)
+			for ($i = 0; $i < $size; $i++)
 			{
 				$arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);
 			}
 			return $arr;
 		}
-		elseif($kind == 'struct')
+		elseif ($kind == 'struct')
 		{
 			reset($xmlrpc_val->me['struct']);
 			$arr = array();
 
-			while(list($key,$value) = each($xmlrpc_val->me['struct']))
+			while (list($key,$value) = each($xmlrpc_val->me['struct']))
 			{
 				$arr[$key] = $this->xmlrpc_decoder($value);
 			}
@@ -595,10 +595,8 @@
 		$t = 0;
 		if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})/', $time, $regs))
 		{
-			if ($utc == 1)
-				$t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
-			else
-				$t = mktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
+			$fnc = ($utc == 1) ? 'gmmktime' : 'mktime';
+			$t = $fnc($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
 		}
 		return $t;
 	}
@@ -628,7 +626,7 @@
 		$this->method_name = $method;
 		if (is_array($pars) && count($pars) > 0)
 		{
-			for($i=0; $i<count($pars); $i++)
+			for ($i=0; $i<count($pars); $i++)
 			{
 				// $pars[$i] = XML_RPC_Values
 				$this->params[] = $pars[$i];
@@ -646,7 +644,7 @@
 		$this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";
 		$this->payload .= "<params>\r\n";
 
-		for($i=0; $i<count($this->params); $i++)
+		for ($i=0; $i<count($this->params); $i++)
 		{
 			// $p = XML_RPC_Values
 			$p = $this->params[$i];
@@ -664,7 +662,7 @@
 	{
 		$data = '';
 
-		while($datum = fread($fp, 4096))
+		while ($datum = fread($fp, 4096))
 		{
 			$data .= $datum;
 		}
@@ -684,7 +682,7 @@
 		//  Check for data
 		//-------------------------------------
 
-		if($data == "")
+		if ($data == "")
 		{
 			error_log($this->xmlrpcstr['no_data']);
 			$r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
@@ -896,7 +894,7 @@
 				$this->xh[$the_parser]['isf'] = 1;
 			break;
 			case 'PARAM':
-				$this->xh[$the_parser]['value'] = null;
+				$this->xh[$the_parser]['value'] = NULL;
 			break;
 			case 'VALUE':
 				$this->xh[$the_parser]['vt'] = 'value';
@@ -925,7 +923,7 @@
 				$this->xh[$the_parser]['valuestack'][0]['name'] = '';
 
 				// Set NULL value to check to see if value passed for this param/member
-				$this->xh[$the_parser]['value'] = null;
+				$this->xh[$the_parser]['value'] = NULL;
 			break;
 			case 'DATA':
 			case 'METHODCALL':
@@ -1108,7 +1106,7 @@
 				$this->xh[$the_parser]['lv'] = 2; // Found a value
 			}
 
-			if( ! @isset($this->xh[$the_parser]['ac']))
+			if ( ! @isset($this->xh[$the_parser]['ac']))
 			{
 				$this->xh[$the_parser]['ac'] = '';
 			}
@@ -1174,11 +1172,11 @@
 	{
 		$kind = $param->kindOf();
 
-		if($kind == 'scalar')
+		if ($kind == 'scalar')
 		{
 			return $param->scalarval();
 		}
-		elseif($kind == 'array')
+		elseif ($kind == 'array')
 		{
 			reset($param->me);
 			list($a,$b) = each($param->me);
@@ -1192,13 +1190,13 @@
 
 			return $arr;
 		}
-		elseif($kind == 'struct')
+		elseif ($kind == 'struct')
 		{
 			reset($param->me['struct']);
 
 			$arr = array();
 
-			while(list($key,$value) = each($param->me['struct']))
+			while (list($key,$value) = each($param->me['struct']))
 			{
 				$arr[$key] = $this->decode_message($value);
 			}
@@ -1343,7 +1341,7 @@
 				// struct
 				$rs .= "<struct>\n";
 				reset($val);
-				while(list($key2, $val2) = each($val))
+				while (list($key2, $val2) = each($val))
 				{
 					$rs .= "<member>\n<name>{$key2}</name>\n";
 					$rs .= $this->serializeval($val2);
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index 6bedfe3..9cd3321 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -59,10 +59,15 @@
 		log_message('debug', "XML-RPC Server Class Initialized");
 	}
 
-	//-------------------------------------
-	//  Initialize Prefs and Serve
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Initialize Prefs and Serve
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	void
+	 */
 	function initialize($config=array())
 	{
 		if (isset($config['functions']) && is_array($config['functions']))
@@ -86,11 +91,15 @@
 		}
 	}
 
-	//-------------------------------------
-	//  Setting of System Methods
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
-	function set_system_methods ()
+	/**
+	 * Setting of System Methods
+	 *
+	 * @access	public
+	 * @return	void
+	 */
+	function set_system_methods()
 	{
 		$this->methods = array(
 					'system.listMethods'	 => array(
@@ -112,11 +121,14 @@
 					);
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Main Server Function
-	//-------------------------------------
-
+	/**
+	 * Main Server Function
+	 *
+	 * @access	public
+	 * @return	void
+	 */
 	function serve()
 	{
 		$r = $this->parseRequest();
@@ -129,11 +141,19 @@
 		exit($payload);
 	}
 
-	//-------------------------------------
-	//  Add Method to Class
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
-	function add_to_map($methodname,$function,$sig,$doc)
+	/**
+	 * Add Method to Class
+	 *
+	 * @access	public
+	 * @param	string	method name
+	 * @param	string	function
+	 * @param	string	signature
+	 * @param	string	docstring
+	 * @return	void
+	 */
+	function add_to_map($methodname, $function, $sig, $doc)
 	{
 		$this->methods[$methodname] = array(
 			'function'  => $function,
@@ -142,11 +162,15 @@
 		);
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Parse Server Request
-	//-------------------------------------
-
+	/**
+	 * Parse Server Request
+	 *
+	 * @access	public
+	 * @param	string	data
+	 * @return	object	xmlrpc response
+	 */
 	function parseRequest($data='')
 	{
 		global $HTTP_RAW_POST_DATA;
@@ -196,7 +220,7 @@
 				xml_get_current_line_number($parser)));
 			xml_parser_free($parser);
 		}
-		elseif($parser_object->xh[$parser]['isf'])
+		elseif ($parser_object->xh[$parser]['isf'])
 		{
 			return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
 		}
@@ -207,7 +231,7 @@
 			$m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
 			$plist='';
 
-			for($i=0; $i < count($parser_object->xh[$parser]['params']); $i++)
+			for ($i=0; $i < count($parser_object->xh[$parser]['params']); $i++)
 			{
 				if ($this->debug === TRUE)
 				{
@@ -239,10 +263,15 @@
 		return $r;
 	}
 
-	//-------------------------------------
-	//  Executes the Method
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Executes the Method
+	 *
+	 * @access	protected
+	 * @param	object
+	 * @return	mixed
+	 */
 	function _execute($m)
 	{
 		$methName = $m->method_name;
@@ -297,13 +326,13 @@
 		if (isset($this->methods[$methName]['signature']))
 		{
 			$sig = $this->methods[$methName]['signature'];
-			for($i=0; $i<count($sig); $i++)
+			for ($i=0; $i<count($sig); $i++)
 			{
 				$current_sig = $sig[$i];
 
 				if (count($current_sig) == count($m->params)+1)
 				{
-					for($n=0; $n < count($m->params); $n++)
+					for ($n=0; $n < count($m->params); $n++)
 					{
 						$p = $m->params[$n];
 						$pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
@@ -352,23 +381,27 @@
 			return call_user_func($this->methods[$methName]['function'], $m);
 		}
 	}
+	
+	// --------------------------------------------------------------------
 
-
-	//-------------------------------------
-	//  Server Function:  List Methods
-	//-------------------------------------
-
+	/**
+	 * Server Function:  List Methods
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	object
+	 */
 	function listMethods($m)
 	{
 		$v = new XML_RPC_Values();
 		$output = array();
 
-		foreach($this->methods as $key => $value)
+		foreach ($this->methods as $key => $value)
 		{
 			$output[] = new XML_RPC_Values($key, 'string');
 		}
 
-		foreach($this->system_methods as $key => $value)
+		foreach ($this->system_methods as $key => $value)
 		{
 			$output[]= new XML_RPC_Values($key, 'string');
 		}
@@ -376,11 +409,16 @@
 		$v->addArray($output);
 		return new XML_RPC_Response($v);
 	}
+	
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Server Function:  Return Signature for Method
-	//-------------------------------------
-
+	/**
+	 * Server Function:  Return Signature for Method
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	object
+	 */
 	function methodSignature($m)
 	{
 		$parameters = $m->output_parameters();
@@ -393,11 +431,11 @@
 				$sigs = array();
 				$signature = $this->methods[$method_name]['signature'];
 
-				for($i=0; $i < count($signature); $i++)
+				for ($i=0; $i < count($signature); $i++)
 				{
 					$cursig = array();
 					$inSig = $signature[$i];
-					for($j=0; $j<count($inSig); $j++)
+					for ($j=0; $j<count($inSig); $j++)
 					{
 						$cursig[]= new XML_RPC_Values($inSig[$j], 'string');
 					}
@@ -417,10 +455,15 @@
 		return $r;
 	}
 
-	//-------------------------------------
-	//  Server Function:  Doc String for Method
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Server Function:  Doc String for Method
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	object
+	 */
 	function methodHelp($m)
 	{
 		$parameters = $m->output_parameters();
@@ -437,11 +480,16 @@
 			return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
 		}
 	}
+	
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Server Function:  Multi-call
-	//-------------------------------------
-
+	/**
+	 * Server Function:  Multi-call
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	object
+	 */
 	function multicall($m)
 	{
 		// Disabled
@@ -459,7 +507,7 @@
 			$m = new XML_RPC_Message($value[0]);
 			$plist='';
 
-			for($i=0; $i < count($value[1]); $i++)
+			for ($i=0; $i < count($value[1]); $i++)
 			{
 				$m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
 			}
@@ -477,11 +525,15 @@
 		return new XML_RPC_Response(new XML_RPC_Values($result, 'array'));
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Multi-call Function:  Error Handling
-	//-------------------------------------
-
+	/**
+	 *  Multi-call Function:  Error Handling
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	object
+	 */
 	function multicall_error($err)
 	{
 		$str  = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
@@ -493,29 +545,45 @@
 		return new XML_RPC_Values($struct, 'struct');
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Multi-call Function:  Processes method
-	//-------------------------------------
-
+	/**
+	 *  Multi-call Function:  Processes method
+	 *
+	 * @access	public
+	 * @param	mixed
+	 * @return	object
+	 */
 	function do_multicall($call)
 	{
 		if ($call->kindOf() != 'struct')
+		{
 			return $this->multicall_error('notstruct');
+		}
 		elseif ( ! $methName = $call->me['struct']['methodName'])
+		{
 			return $this->multicall_error('nomethod');
+		}
 
 		list($scalar_type,$scalar_value)=each($methName->me);
 		$scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
 
 		if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')
+		{
 			return $this->multicall_error('notstring');
+		}
 		elseif ($scalar_value == 'system.multicall')
+		{
 			return $this->multicall_error('recursion');
+		}
 		elseif ( ! $params = $call->me['struct']['params'])
+		{
 			return $this->multicall_error('noparams');
+		}
 		elseif ($params->kindOf() != 'array')
+		{
 			return $this->multicall_error('notarray');
+		}
 
 		list($a,$b)=each($params->me);
 		$numParams = count($b);
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index 80633c7..666327d 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -289,7 +289,7 @@
 
 		while (FALSE !== ($file = readdir($fp)))
 		{
-			if(substr($file, 0, 1) == '.')
+			if (substr($file, 0, 1) == '.')
 			{
 				continue;
 			}