Merge remote-tracking branch 'upstream/develop' into new_date
diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php
index f6b634d..2fabdf4 100755
--- a/system/core/Benchmark.php
+++ b/system/core/Benchmark.php
@@ -25,13 +25,11 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Benchmark Class
  *
  * This class enables you to mark points and calculate the time difference
- * between them.  Memory consumption can also be displayed.
+ * between them. Memory consumption can also be displayed.
  *
  * @package		CodeIgniter
  * @subpackage	Libraries
@@ -46,7 +44,7 @@
 	 *
 	 * @var array
 	 */
-	public $marker = array();
+	public $marker =	array();
 
 	// --------------------------------------------------------------------
 
@@ -61,7 +59,7 @@
 	 */
 	public function mark($name)
 	{
-		$this->marker[$name] = microtime();
+		$this->marker[$name] = microtime(TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -81,7 +79,7 @@
 	 */
 	public function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
 	{
-		if ($point1 == '')
+		if ($point1 === '')
 		{
 			return '{elapsed_time}';
 		}
@@ -93,13 +91,10 @@
 
 		if ( ! isset($this->marker[$point2]))
 		{
-			$this->marker[$point2] = microtime();
+			$this->marker[$point2] = microtime(TRUE);
 		}
 
-		list($sm, $ss) = explode(' ', $this->marker[$point1]);
-		list($em, $es) = explode(' ', $this->marker[$point2]);
-
-		return number_format(($em + $es) - ($sm + $ss), $decimals);
+		return number_format($this->marker[$point2] - $this->marker[$point1], $decimals);
 	}
 
 	// --------------------------------------------------------------------
@@ -122,4 +117,4 @@
 }
 
 /* End of file Benchmark.php */
-/* Location: ./system/core/Benchmark.php */
+/* Location: ./system/core/Benchmark.php */
\ No newline at end of file
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 4885f31..8159b19 100755
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -25,15 +25,13 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * System Initialization File
  *
  * Loads the base classes and executes the request.
  *
  * @package		CodeIgniter
- * @subpackage	codeigniter
+ * @subpackage	CodeIgniter
  * @category	Front-controller
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/
@@ -42,7 +40,7 @@
 /**
  * CodeIgniter Version
  *
- * @var string
+ * @var	string
  *
  */
 	define('CI_VERSION', '3.0-dev');
@@ -75,9 +73,9 @@
  */
 	set_error_handler('_exception_handler');
 
-	if ( ! is_php('5.3'))
+	if ( ! is_php('5.4'))
 	{
-		@set_magic_quotes_runtime(0); // Kill magic quotes
+		@ini_set('magic_quotes_runtime', 0); // Kill magic quotes
 	}
 
 /*
@@ -96,24 +94,13 @@
  * Note: Since the config file data is cached it doesn't
  * hurt to load it here.
  */
-	if (isset($assign_to_config['subclass_prefix']) && $assign_to_config['subclass_prefix'] != '')
+	if ( ! empty($assign_to_config['subclass_prefix']))
 	{
 		get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
 	}
 
 /*
  * ------------------------------------------------------
- *  Set a liberal script execution time limit
- * ------------------------------------------------------
- */
-	if (function_exists('set_time_limit') && @ini_get('safe_mode') == 0
-		&& php_sapi_name() !== 'cli') // Do not override the Time Limit value if running from Command Line
-	{
-		@set_time_limit(300);
-	}
-
-/*
- * ------------------------------------------------------
  *  Start the timer... tick tock tick tock...
  * ------------------------------------------------------
  */
@@ -155,7 +142,7 @@
  *
  * Note: Order here is rather important as the UTF-8
  * class needs to be used very early on, but it cannot
- * properly determine if UTf-8 can be supported until
+ * properly determine if UTF-8 can be supported until
  * after the Config class is instantiated.
  *
  */
@@ -195,7 +182,7 @@
  * ------------------------------------------------------
  */
 	if ($EXT->call_hook('cache_override') === FALSE
-		&& $OUT->_display_cache($CFG, $URI) == TRUE)
+		&& $OUT->_display_cache($CFG, $URI) === TRUE)
 	{
 		exit;
 	}
@@ -230,6 +217,13 @@
 	// Load the base controller class
 	require BASEPATH.'core/Controller.php';
 
+	/**
+	 * Reference to the CI_Controller method.
+	 *
+	 * Returns current CI instance object
+	 *
+	 * @return object
+	 */
 	function &get_instance()
 	{
 		return CI_Controller::get_instance();
@@ -275,12 +269,12 @@
 		{
 			$x = explode('/', $RTR->routes['404_override'], 2);
 			$class = $x[0];
-			$method = (isset($x[1]) ? $x[1] : 'index');
+			$method = isset($x[1]) ? $x[1] : 'index';
 			if ( ! class_exists($class))
 			{
 				if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
 				{
-					show_404("{$class}/{$method}");
+					show_404($class.'/'.$method);
 				}
 
 				include_once(APPPATH.'controllers/'.$class.'.php');
@@ -288,7 +282,7 @@
 		}
 		else
 		{
-			show_404("{$class}/{$method}");
+			show_404($class.'/'.$method);
 		}
 	}
 
@@ -337,12 +331,12 @@
 			{
 				$x = explode('/', $RTR->routes['404_override'], 2);
 				$class = $x[0];
-				$method = (isset($x[1]) ? $x[1] : 'index');
+				$method = isset($x[1]) ? $x[1] : 'index';
 				if ( ! class_exists($class))
 				{
 					if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
 					{
-						show_404("{$class}/{$method}");
+						show_404($class.'/'.$method);
 					}
 
 					include_once(APPPATH.'controllers/'.$class.'.php');
@@ -352,7 +346,7 @@
 			}
 			else
 			{
-				show_404("{$class}/{$method}");
+				show_404($class.'/'.$method);
 			}
 		}
 
@@ -388,15 +382,5 @@
  */
 	$EXT->call_hook('post_system');
 
-/*
- * ------------------------------------------------------
- *  Close the DB connection if one exists
- * ------------------------------------------------------
- */
-	if (class_exists('CI_DB') && isset($CI->db))
-	{
-		$CI->db->close();
-	}
-
 /* End of file CodeIgniter.php */
-/* Location: ./system/core/CodeIgniter.php */
+/* Location: ./system/core/CodeIgniter.php */
\ No newline at end of file
diff --git a/system/core/Common.php b/system/core/Common.php
index aeb784b..c08755c 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -31,7 +31,7 @@
  * Loads the base classes and executes the request.
  *
  * @package		CodeIgniter
- * @subpackage	codeigniter
+ * @subpackage	CodeIgniter
  * @category	Common Functions
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/
@@ -39,25 +39,25 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Determines if the current version of PHP is greater then the supplied value
- *
- * Since there are a few places where we conditionally test for PHP > 5
- * we'll set a static variable.
- *
- * @param	string
- * @return	bool	TRUE if the current version is $version or higher
- */
 if ( ! function_exists('is_php'))
 {
-	function is_php($version = '5.0.0')
+	/**
+	 * Determines if the current version of PHP is greater then the supplied value
+	 *
+	 * Since there are a few places where we conditionally test for PHP > 5.3
+	 * we'll set a static variable.
+	 *
+	 * @param	string
+	 * @return	bool	TRUE if the current version is $version or higher
+	 */
+	function is_php($version = '5.3.0')
 	{
 		static $_is_php;
 		$version = (string) $version;
 
 		if ( ! isset($_is_php[$version]))
 		{
-			$_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0) ? FALSE : TRUE;
+			$_is_php[$version] = (version_compare(PHP_VERSION, $version) >= 0);
 		}
 
 		return $_is_php[$version];
@@ -66,18 +66,18 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Tests for file writability
- *
- * is_writable() returns TRUE on Windows servers when you really can't write to
- * the file, based on the read-only attribute. is_writable() is also unreliable
- * on Unix servers if safe_mode is on.
- *
- * @param	string
- * @return	void
- */
 if ( ! function_exists('is_really_writable'))
 {
+	/**
+	 * Tests for file writability
+	 *
+	 * is_writable() returns TRUE on Windows servers when you really can't write to
+	 * the file, based on the read-only attribute. is_writable() is also unreliable
+	 * on Unix servers if safe_mode is on.
+	 *
+	 * @param	string
+	 * @return	void
+	 */
 	function is_really_writable($file)
 	{
 		// If we're on a Unix server with safe_mode off we call is_writable
@@ -114,20 +114,20 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Class registry
- *
- * This function acts as a singleton. If the requested class does not
- * exist it is instantiated and set to a static variable. If it has
- * previously been instantiated the variable is returned.
- *
- * @param	string	the class name being requested
- * @param	string	the directory where the class should be found
- * @param	string	the class name prefix
- * @return	object
- */
 if ( ! function_exists('load_class'))
 {
+	/**
+	 * Class registry
+	 *
+	 * This function acts as a singleton. If the requested class does not
+	 * exist it is instantiated and set to a static variable. If it has
+	 * previously been instantiated the variable is returned.
+	 *
+	 * @param	string	the class name being requested
+	 * @param	string	the directory where the class should be found
+	 * @param	string	the class name prefix
+	 * @return	object
+	 */
 	function &load_class($class, $directory = 'libraries', $prefix = 'CI_')
 	{
 		static $_classes = array();
@@ -187,20 +187,20 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Keeps track of which libraries have been loaded. This function is
- * called by the load_class() function above
- *
- * @param	string
- * @return	array
- */
 if ( ! function_exists('is_loaded'))
 {
+	/**
+	 * Keeps track of which libraries have been loaded. This function is
+	 * called by the load_class() function above
+	 *
+	 * @param	string
+	 * @return	array
+	 */
 	function &is_loaded($class = '')
 	{
 		static $_is_loaded = array();
 
-		if ($class != '')
+		if ($class !== '')
 		{
 			$_is_loaded[strtolower($class)] = $class;
 		}
@@ -211,17 +211,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Loads the main config.php file
- *
- * This function lets us grab the config file even if the Config class
- * hasn't been instantiated yet
- *
- * @param	array
- * @return	array
- */
 if ( ! function_exists('get_config'))
 {
+	/**
+	 * Loads the main config.php file
+	 *
+	 * This function lets us grab the config file even if the Config class
+	 * hasn't been instantiated yet
+	 *
+	 * @param	array
+	 * @return	array
+	 */
 	function &get_config($replace = array())
 	{
 		static $_config;
@@ -231,21 +231,25 @@
 			return $_config[0];
 		}
 
-		// Is the config file in the environment folder?
-		if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
+		$file_path = APPPATH.'config/config.php';
+		$found = FALSE;
+		if (file_exists($file_path))
 		{
-			$file_path = APPPATH.'config/config.php';
+			$found = TRUE;
+			require($file_path);
 		}
 
-		// Fetch the config file
-		if ( ! file_exists($file_path))
+		// Is the config file in the environment folder?
+		if (defined(ENVIRONMENT) && file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
+		{
+			require($file_path);
+		}
+		elseif ( ! $found)
 		{
 			set_status_header(503);
 			exit('The configuration file does not exist.');
 		}
 
-		require($file_path);
-
 		// Does the $config array exist in the file?
 		if ( ! isset($config) OR ! is_array($config))
 		{
@@ -271,14 +275,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Returns the specified config item
- *
- * @param	string
- * @return	mixed
- */
 if ( ! function_exists('config_item'))
 {
+	/**
+	 * Returns the specified config item
+	 *
+	 * @param	string
+	 * @return	mixed
+	 */
 	function config_item($item)
 	{
 		static $_config_item = array();
@@ -300,22 +304,48 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Error Handler
- *
- * This function lets us invoke the exception class and
- * display errors using the standard error template located
- * in application/errors/errors.php
- * This function will send the error page directly to the
- * browser and exit.
- *
- * @param	string
- * @param	int
- * @param	string
- * @return	void
- */
+if ( ! function_exists('get_mimes'))
+{
+	/**
+	 * Returns the MIME types array from config/mimes.php
+	 *
+	 * @return	array
+	 */
+	function &get_mimes()
+	{
+		static $_mimes = array();
+
+		if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
+		{
+			$_mimes = include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
+		}
+		elseif (is_file(APPPATH.'config/mimes.php'))
+		{
+			$_mimes = include(APPPATH.'config/mimes.php');
+		}
+
+		return $_mimes;
+	}
+}
+
+// ------------------------------------------------------------------------
+
 if ( ! function_exists('show_error'))
 {
+	/**
+	 * Error Handler
+	 *
+	 * This function lets us invoke the exception class and
+	 * display errors using the standard error template located
+	 * in application/errors/errors.php
+	 * This function will send the error page directly to the
+	 * browser and exit.
+	 *
+	 * @param	string
+	 * @param	int
+	 * @param	string
+	 * @return	void
+	 */
 	function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
 	{
 		$_error =& load_class('Exceptions', 'core');
@@ -326,19 +356,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * 404 Page Handler
- *
- * This function is similar to the show_error() function above
- * However, instead of the standard error template it displays
- * 404 errors.
- *
- * @param	string
- * @param	bool
- * @return	void
- */
 if ( ! function_exists('show_404'))
 {
+	/**
+	 * 404 Page Handler
+	 *
+	 * This function is similar to the show_error() function above
+	 * However, instead of the standard error template it displays
+	 * 404 errors.
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	void
+	 */
 	function show_404($page = '', $log_error = TRUE)
 	{
 		$_error =& load_class('Exceptions', 'core');
@@ -349,24 +379,24 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Error Logging Interface
- *
- * We use this as a simple mechanism to access the logging
- * class and send messages to be logged.
- *
- * @param	string
- * @param	string
- * @param	bool
- * @return	void
- */
 if ( ! function_exists('log_message'))
 {
+	/**
+	 * Error Logging Interface
+	 *
+	 * We use this as a simple mechanism to access the logging
+	 * class and send messages to be logged.
+	 *
+	 * @param	string
+	 * @param	string
+	 * @param	bool
+	 * @return	void
+	 */
 	function log_message($level = 'error', $message, $php_error = FALSE)
 	{
 		static $_log;
 
-		if (config_item('log_threshold') == 0)
+		if (config_item('log_threshold') === 0)
 		{
 			return;
 		}
@@ -378,71 +408,70 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Set HTTP Status Header
- *
- * @param	int	the status code
- * @param	string
- * @return	void
- */
 if ( ! function_exists('set_status_header'))
 {
+	/**
+	 * Set HTTP Status Header
+	 *
+	 * @param	int	the status code
+	 * @param	string
+	 * @return	void
+	 */
 	function set_status_header($code = 200, $text = '')
 	{
 		$stati = array(
-					200	=> 'OK',
-					201	=> 'Created',
-					202	=> 'Accepted',
-					203	=> 'Non-Authoritative Information',
-					204	=> 'No Content',
-					205	=> 'Reset Content',
-					206	=> 'Partial Content',
+			200	=> 'OK',
+			201	=> 'Created',
+			202	=> 'Accepted',
+			203	=> 'Non-Authoritative Information',
+			204	=> 'No Content',
+			205	=> 'Reset Content',
+			206	=> 'Partial Content',
 
-					300	=> 'Multiple Choices',
-					301	=> 'Moved Permanently',
-					302	=> 'Found',
-					304	=> 'Not Modified',
-					305	=> 'Use Proxy',
-					307	=> 'Temporary Redirect',
+			300	=> 'Multiple Choices',
+			301	=> 'Moved Permanently',
+			302	=> 'Found',
+			304	=> 'Not Modified',
+			305	=> 'Use Proxy',
+			307	=> 'Temporary Redirect',
 
-					400	=> 'Bad Request',
-					401	=> 'Unauthorized',
-					403	=> 'Forbidden',
-					404	=> 'Not Found',
-					405	=> 'Method Not Allowed',
-					406	=> 'Not Acceptable',
-					407	=> 'Proxy Authentication Required',
-					408	=> 'Request Timeout',
-					409	=> 'Conflict',
-					410	=> 'Gone',
-					411	=> 'Length Required',
-					412	=> 'Precondition Failed',
-					413	=> 'Request Entity Too Large',
-					414	=> 'Request-URI Too Long',
-					415	=> 'Unsupported Media Type',
-					416	=> 'Requested Range Not Satisfiable',
-					417	=> 'Expectation Failed',
-					422	=> 'Unprocessable Entity',
+			400	=> 'Bad Request',
+			401	=> 'Unauthorized',
+			403	=> 'Forbidden',
+			404	=> 'Not Found',
+			405	=> 'Method Not Allowed',
+			406	=> 'Not Acceptable',
+			407	=> 'Proxy Authentication Required',
+			408	=> 'Request Timeout',
+			409	=> 'Conflict',
+			410	=> 'Gone',
+			411	=> 'Length Required',
+			412	=> 'Precondition Failed',
+			413	=> 'Request Entity Too Large',
+			414	=> 'Request-URI Too Long',
+			415	=> 'Unsupported Media Type',
+			416	=> 'Requested Range Not Satisfiable',
+			417	=> 'Expectation Failed',
+			422	=> 'Unprocessable Entity',
 
-					500	=> 'Internal Server Error',
-					501	=> 'Not Implemented',
-					502	=> 'Bad Gateway',
-					503	=> 'Service Unavailable',
-					504	=> 'Gateway Timeout',
-					505	=> 'HTTP Version Not Supported'
-			);
+			500	=> 'Internal Server Error',
+			501	=> 'Not Implemented',
+			502	=> 'Bad Gateway',
+			503	=> 'Service Unavailable',
+			504	=> 'Gateway Timeout',
+			505	=> 'HTTP Version Not Supported'
+		);
 
 		if ($code == '' OR ! is_numeric($code))
 		{
 			show_error('Status codes must be numeric', 500);
 		}
-
-		if (isset($stati[$code]) && $text == '')
+		elseif (isset($stati[$code]) && $text === '')
 		{
 			$text = $stati[$code];
 		}
 
-		if ($text == '')
+		if ($text === '')
 		{
 			show_error('No status text available. Please check your status code number or supply your own message text.', 500);
 		}
@@ -466,48 +495,38 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Exception Handler
- *
- * This is the custom exception handler that is declaired at the top
- * of Codeigniter.php. The main reason we use this is to permit
- * PHP errors to be logged in our own log files since the user may
- * not have access to server logs. Since this function
- * effectively intercepts PHP errors, however, we also need
- * to display errors based on the current error_reporting level.
- * We do that with the use of a PHP error template.
- *
- * @param	int
- * @param	string
- * @param	string
- * @param	int
- * @return	void
- */
 if ( ! function_exists('_exception_handler'))
 {
+	/**
+	 * Exception Handler
+	 *
+	 * This is the custom exception handler that is declaired at the top
+	 * of Codeigniter.php. The main reason we use this is to permit
+	 * PHP errors to be logged in our own log files since the user may
+	 * not have access to server logs. Since this function
+	 * effectively intercepts PHP errors, however, we also need
+	 * to display errors based on the current error_reporting level.
+	 * We do that with the use of a PHP error template.
+	 *
+	 * @param	int
+	 * @param	string
+	 * @param	string
+	 * @param	int
+	 * @return	void
+	 */
 	function _exception_handler($severity, $message, $filepath, $line)
 	{
-		 // We don't bother with "strict" notices since they tend to fill up
-		 // the log file with excess information that isn't normally very helpful.
-		 // For example, if you are running PHP 5 and you use version 4 style
-		 // class functions (without prefixes like "public", "private", etc.)
-		 // you'll get notices telling you that these have been deprecated.
-		if ($severity == E_STRICT)
-		{
-			return;
-		}
-
 		$_error =& load_class('Exceptions', 'core');
 
 		// Should we display the error? We'll get the current error_reporting
 		// level and add its bits with the severity bits to find out.
-		if (($severity & error_reporting()) == $severity)
+		if (($severity & error_reporting()) === $severity)
 		{
 			$_error->show_php_error($severity, $message, $filepath, $line);
 		}
 
-		// Should we log the error?  No?  We're done...
-		if (config_item('log_threshold') == 0)
+		// Should we log the error? No? We're done...
+		if (config_item('log_threshold') === 0)
 		{
 			return;
 		}
@@ -518,18 +537,18 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Remove Invisible Characters
- *
- * This prevents sandwiching null characters
- * between ascii characters, like Java\0script.
- *
- * @param	string
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('remove_invisible_characters'))
 {
+	/**
+	 * Remove Invisible Characters
+	 *
+	 * This prevents sandwiching null characters
+	 * between ascii characters, like Java\0script.
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	function remove_invisible_characters($str, $url_encoded = TRUE)
 	{
 		$non_displayables = array();
@@ -556,14 +575,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Returns HTML escaped variable
- *
- * @param	mixed
- * @return	mixed
- */
 if ( ! function_exists('html_escape'))
 {
+	/**
+	 * Returns HTML escaped variable
+	 *
+	 * @param	mixed
+	 * @return	mixed
+	 */
 	function html_escape($var)
 	{
 		return is_array($var)
diff --git a/system/core/Config.php b/system/core/Config.php
index 91826bd..3de1bcb 100755
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Config Class
  *
@@ -45,30 +43,27 @@
 	 *
 	 * @var array
 	 */
-	public $config = array();
+	public $config =	array();
+
 	/**
 	 * List of all loaded config files
 	 *
 	 * @var array
 	 */
-	public $is_loaded = array();
+	public $is_loaded =	array();
+
 	/**
 	 * List of paths to search when trying to load a config file.
 	 * This must be public as it's used by the Loader class.
 	 *
 	 * @var array
 	 */
-	public $_config_paths = array(APPPATH);
+	public $_config_paths =	array(APPPATH);
 
 	/**
 	 * Constructor
 	 *
 	 * Sets the $config data from the primary config.php file as a class variable
-	 *
-	 * @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 successfully loaded or not
 	 */
 	public function __construct()
 	{
@@ -80,9 +75,9 @@
 		{
 			if (isset($_SERVER['HTTP_HOST']))
 			{
-				$base_url = ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
-				$base_url .= '://'. $_SERVER['HTTP_HOST']
-					. str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
+				$base_url = ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off') ? 'https' : 'http';
+				$base_url .= '://'.$_SERVER['HTTP_HOST']
+					.str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
 			}
 			else
 			{
@@ -99,13 +94,13 @@
 	 * Load Config File
 	 *
 	 * @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
+	 * @param	bool	if configuration values should be loaded into their own section
+	 * @param	bool	true if errors should just return false, false if an error message should be displayed
+	 * @return	bool	if the file was loaded correctly
 	 */
 	public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
 	{
-		$file = ($file == '') ? 'config' : str_replace('.php', '', $file);
+		$file = ($file === '') ? 'config' : str_replace('.php', '', $file);
 		$found = $loaded = FALSE;
 
 		foreach ($this->_config_paths as $path)
@@ -188,10 +183,8 @@
 	/**
 	 * Fetch a config file item
 	 *
-	 *
 	 * @param	string	the config item name
 	 * @param	string	the index name
-	 * @param	bool
 	 * @return	string
 	 */
 	public function item($item, $index = '')
@@ -210,7 +203,6 @@
 	 * Fetch a config file item - adds slash after item (if item is not empty)
 	 *
 	 * @param	string	the config item name
-	 * @param	bool
 	 * @return	string
 	 */
 	public function slash_item($item)
@@ -219,7 +211,7 @@
 		{
 			return FALSE;
 		}
-		elseif (trim($this->config[$item]) == '')
+		elseif (trim($this->config[$item]) === '')
 		{
 			return '';
 		}
@@ -238,14 +230,14 @@
 	 */
 	public function site_url($uri = '')
 	{
-		if ($uri == '')
+		if ($uri === '')
 		{
 			return $this->slash_item('base_url').$this->item('index_page');
 		}
 
-		if ($this->item('enable_query_strings') == FALSE)
+		if ($this->item('enable_query_strings') === FALSE)
 		{
-			$suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
+			$suffix = ($this->item('url_suffix') === FALSE) ? '' : $this->item('url_suffix');
 			return $this->slash_item('base_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix;
 		}
 		else
@@ -260,8 +252,8 @@
 	 * Base URL
 	 * Returns base_url [. uri_string]
 	 *
-	 * @param string $uri
-	 * @return string
+	 * @param	string	$uri
+	 * @return	string
 	 */
 	public function base_url($uri = '')
 	{
@@ -273,12 +265,12 @@
 	/**
 	 * Build URI string for use in Config::site_url() and Config::base_url()
 	 *
-	 * @param  mixed $uri
-	 * @return string
+	 * @param	mixed	$uri
+	 * @return	string
 	 */
 	protected function _uri_string($uri)
 	{
-		if ($this->item('enable_query_strings') == FALSE)
+		if ($this->item('enable_query_strings') === FALSE)
 		{
 			if (is_array($uri))
 			{
@@ -351,7 +343,8 @@
 			}
 		}
 	}
+
 }
 
 /* End of file Config.php */
-/* Location: ./system/core/Config.php */
+/* Location: ./system/core/Config.php */
\ No newline at end of file
diff --git a/system/core/Controller.php b/system/core/Controller.php
index 05e1bf5..4914148 100644
--- a/system/core/Controller.php
+++ b/system/core/Controller.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Application Controller Class
  *
@@ -41,8 +39,18 @@
  */
 class CI_Controller {
 
+	/**
+	 * Reference to the global CI instance
+	 *
+	 * @var	object
+	 */
 	private static $instance;
 
+	/**
+	 * Set up controller properties and methods
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
 		self::$instance =& $this;
@@ -60,11 +68,17 @@
 		log_message('debug', 'Controller Class Initialized');
 	}
 
+	/**
+	 * Return the CI object
+	 *
+	 * @return	object
+	 */
 	public static function &get_instance()
 	{
 		return self::$instance;
 	}
+
 }
 
 /* End of file Controller.php */
-/* Location: ./system/core/Controller.php */
+/* Location: ./system/core/Controller.php */
\ No newline at end of file
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index f36b315..8c32085 100755
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -36,39 +36,38 @@
  */
 class CI_Exceptions {
 
-	public $action;
-	public $severity;
-	public $message;
-	public $filename;
-	public $line;
-
 	/**
 	 * Nesting level of the output buffering mechanism
 	 *
-	 * @var int
+	 * @var	int
 	 */
 	public $ob_level;
 
 	/**
 	 * List if available error levels
 	 *
-	 * @var array
+	 * @var	array
 	 */
 	public $levels = array(
-				E_ERROR			=>	'Error',
-				E_WARNING		=>	'Warning',
-				E_PARSE			=>	'Parsing Error',
-				E_NOTICE		=>	'Notice',
-				E_CORE_ERROR		=>	'Core Error',
-				E_CORE_WARNING		=>	'Core Warning',
-				E_COMPILE_ERROR		=>	'Compile Error',
-				E_COMPILE_WARNING	=>	'Compile Warning',
-				E_USER_ERROR		=>	'User Error',
-				E_USER_WARNING		=>	'User Warning',
-				E_USER_NOTICE		=>	'User Notice',
-				E_STRICT		=>	'Runtime Notice'
-			);
+		E_ERROR			=>	'Error',
+		E_WARNING		=>	'Warning',
+		E_PARSE			=>	'Parsing Error',
+		E_NOTICE		=>	'Notice',
+		E_CORE_ERROR		=>	'Core Error',
+		E_CORE_WARNING		=>	'Core Warning',
+		E_COMPILE_ERROR		=>	'Compile Error',
+		E_COMPILE_WARNING	=>	'Compile Warning',
+		E_USER_ERROR		=>	'User Error',
+		E_USER_WARNING		=>	'User Warning',
+		E_USER_NOTICE		=>	'User Notice',
+		E_STRICT		=>	'Runtime Notice'
+	);
 
+	/**
+	 * Initialize execption class
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
 		$this->ob_level = ob_get_level();
@@ -90,7 +89,7 @@
 	 */
 	public function log_exception($severity, $message, $filepath, $line)
 	{
-		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
+		$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
 		log_message('error', 'Severity: '.$severity.'  --> '.$message. ' '.$filepath.' '.$line, TRUE);
 	}
 
@@ -130,21 +129,21 @@
 	 * @param	string	the heading
 	 * @param	string	the message
 	 * @param	string	the template name
-	 * @param 	int		the status code
+	 * @param 	int	the status code
 	 * @return	string
 	 */
 	public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
 	{
 		set_status_header($status_code);
 
-		$message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>';
+		$message = '<p>'.implode('</p><p>', is_array($message) ? $message : array($message)).'</p>';
 
 		if (ob_get_level() > $this->ob_level + 1)
 		{
 			ob_end_flush();
 		}
 		ob_start();
-		include(APPPATH.'errors/'.$template.'.php');
+		include(APPPATH.'views/errors/'.$template.'.php');
 		$buffer = ob_get_contents();
 		ob_end_clean();
 		return $buffer;
@@ -163,7 +162,7 @@
 	 */
 	public function show_php_error($severity, $message, $filepath, $line)
 	{
-		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
+		$severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
 		$filepath = str_replace('\\', '/', $filepath);
 
 		// For safety reasons we do not show the full file path
@@ -178,7 +177,7 @@
 			ob_end_flush();
 		}
 		ob_start();
-		include(APPPATH.'errors/'.'error_php.php');
+		include(APPPATH.'views/errors/error_php.php');
 		$buffer = ob_get_contents();
 		ob_end_clean();
 		echo $buffer;
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index 68e30ef..29fd882 100755
--- a/system/core/Hooks.php
+++ b/system/core/Hooks.php
@@ -43,19 +43,21 @@
 	 *
 	 * @var bool
 	 */
-	public $enabled		= FALSE;
+	public $enabled =	FALSE;
+
 	/**
 	 * List of all hooks set in config/hooks.php
 	 *
 	 * @var array
 	 */
-	public $hooks		= array();
+	public $hooks =	array();
+
 	/**
 	 * Determines wether hook is in progress, used to prevent infinte loops
 	 *
 	 * @var bool
 	 */
-	public $in_progress	= FALSE;
+	public $in_progress	=	FALSE;
 
 	/**
 	 * Initialize the Hooks Preferences
@@ -70,7 +72,7 @@
 
 		// If hooks are not enabled in the config file
 		// there is nothing else to do
-		if ($CFG->item('enable_hooks') == FALSE)
+		if ($CFG->item('enable_hooks') === FALSE)
 		{
 			return;
 		}
@@ -150,7 +152,7 @@
 
 		// If the script being called happens to have the same
 		// hook call within it a loop can happen
-		if ($this->in_progress == TRUE)
+		if ($this->in_progress === TRUE)
 		{
 			return;
 		}
diff --git a/system/core/Input.php b/system/core/Input.php
index 6e68859..b986c49 100755
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -43,51 +43,59 @@
 	 *
 	 * @var string
 	 */
-	public $ip_address				= FALSE;
+	public $ip_address =	FALSE;
+
 	/**
 	 * user agent (web browser) being used by the current user
 	 *
 	 * @var string
 	 */
-	public $user_agent				= FALSE;
+	public $user_agent =	FALSE;
+
 	/**
 	 * If FALSE, then $_GET will be set to an empty array
 	 *
 	 * @var bool
 	 */
-	protected $_allow_get_array		= TRUE;
+	protected $_allow_get_array =	TRUE;
+
 	/**
 	 * If TRUE, then newlines are standardized
 	 *
 	 * @var bool
 	 */
-	protected $_standardize_newlines	= TRUE;
+	protected $_standardize_newlines =	TRUE;
+
 	/**
 	 * Determines whether the XSS filter is always active when GET, POST or COOKIE data is encountered
 	 * Set automatically based on config setting
 	 *
 	 * @var bool
 	 */
-	protected $_enable_xss			= FALSE;
+	protected $_enable_xss =	FALSE;
+
 	/**
 	 * Enables a CSRF cookie token to be set.
 	 * Set automatically based on config setting
 	 *
 	 * @var bool
 	 */
-	protected $_enable_csrf			= FALSE;
+	protected $_enable_csrf =	FALSE;
+
 	/**
 	 * List of all HTTP request headers
 	 *
 	 * @var array
 	 */
-	protected $headers			= array();
+	protected $headers =	array();
 
 	/**
 	 * Constructor
 	 *
 	 * Sets whether to globally enable the XSS processing
 	 * and whether to allow the $_GET array
+	 *
+	 * @return	void
 	 */
 	public function __construct()
 	{
@@ -127,7 +135,7 @@
 	{
 		if ( ! isset($array[$index]))
 		{
-			return FALSE;
+			return NULL;
 		}
 
 		if ($xss_clean === TRUE)
@@ -141,12 +149,12 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Fetch an item from the GET array
-	*
-	* @param	string
-	* @param	bool
-	* @return	string
-	*/
+	 * Fetch an item from the GET array
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	public function get($index = NULL, $xss_clean = FALSE)
 	{
 		// Check if a field has been provided
@@ -168,12 +176,12 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Fetch an item from the POST array
-	*
-	* @param	string
-	* @param	bool
-	* @return	string
-	*/
+	 * Fetch an item from the POST array
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	public function post($index = NULL, $xss_clean = FALSE)
 	{
 		// Check if a field has been provided
@@ -196,12 +204,12 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Fetch an item from either the GET array or the POST
-	*
-	* @param	string	The index key
-	* @param	bool	XSS cleaning
-	* @return	string
-	*/
+	 * Fetch an item from either the GET array or the POST
+	 *
+	 * @param	string	The index key
+	 * @param	bool	XSS cleaning
+	 * @return	string
+	 */
 	public function get_post($index = '', $xss_clean = FALSE)
 	{
 		return isset($_POST[$index])
@@ -212,12 +220,12 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Fetch an item from the COOKIE array
-	*
-	* @param	string
-	* @param	bool
-	* @return	string
-	*/
+	 * Fetch an item from the COOKIE array
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	public function cookie($index = '', $xss_clean = FALSE)
 	{
 		return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
@@ -226,21 +234,21 @@
 	// ------------------------------------------------------------------------
 
 	/**
-	* Set cookie
-	*
-	* Accepts seven parameters, or you can submit an associative
-	* array in the first parameter containing all the values.
-	*
-	* @param	mixed
-	* @param	string	the value of the cookie
-	* @param	string	the number of seconds until expiration
-	* @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
-	* @param	bool	true makes the cookie accessible via http(s) only (no javascript)
-	* @return	void
-	*/
+	 * Set cookie
+	 *
+	 * Accepts seven parameters, or you can submit an associative
+	 * array in the first parameter containing all the values.
+	 *
+	 * @param	mixed
+	 * @param	string	the value of the cookie
+	 * @param	string	the number of seconds until expiration
+	 * @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
+	 * @param	bool	true makes the cookie accessible via http(s) only (no javascript)
+	 * @return	void
+	 */
 	public function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
 	{
 		if (is_array($name))
@@ -255,23 +263,27 @@
 			}
 		}
 
-		if ($prefix == '' && config_item('cookie_prefix') != '')
+		if ($prefix === '' && config_item('cookie_prefix') !== '')
 		{
 			$prefix = config_item('cookie_prefix');
 		}
+
 		if ($domain == '' && config_item('cookie_domain') != '')
 		{
 			$domain = config_item('cookie_domain');
 		}
-		if ($path == '/' && config_item('cookie_path') !== '/')
+
+		if ($path === '/' && config_item('cookie_path') !== '/')
 		{
 			$path = config_item('cookie_path');
 		}
-		if ($secure == FALSE && config_item('cookie_secure') != FALSE)
+
+		if ($secure === FALSE && config_item('cookie_secure') !== FALSE)
 		{
 			$secure = config_item('cookie_secure');
 		}
-		if ($httponly == FALSE && config_item('cookie_httponly') != FALSE)
+
+		if ($httponly === FALSE && config_item('cookie_httponly') !== FALSE)
 		{
 			$httponly = config_item('cookie_httponly');
 		}
@@ -291,12 +303,12 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Fetch an item from the SERVER array
-	*
-	* @param	string
-	* @param	bool
-	* @return	string
-	*/
+	 * Fetch an item from the SERVER array
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	public function server($index = '', $xss_clean = FALSE)
 	{
 		return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
@@ -305,10 +317,10 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Fetch the IP Address
-	*
-	* @return	string
-	*/
+	 * Fetch the IP Address
+	 *
+	 * @return	string
+	 */
 	public function ip_address()
 	{
 		if ($this->ip_address !== FALSE)
@@ -362,25 +374,25 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Validate IP Address
-	*
-	* Updated version suggested by Geert De Deckere
-	*
-	* @param	string
-	* @return	bool
-	*/
+	 * Validate IP Address
+	 *
+	 * Updated version suggested by Geert De Deckere
+	 *
+	 * @param	string
+	 * @return	bool
+	 */
 	public function valid_ip($ip)
 	{
-		return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
+		return (bool) filter_var($ip, FILTER_VALIDATE_IP);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	* User Agent
-	*
-	* @return	string
-	*/
+	 * User Agent
+	 *
+	 * @return	string
+	 */
 	public function user_agent()
 	{
 		if ($this->user_agent !== FALSE)
@@ -394,38 +406,45 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Sanitize Globals
-	*
-	* This function does the following:
-	*
-	* - Unsets $_GET data (if query strings are not enabled)
-	* - Unsets all globals if register_globals is enabled
-	* - Standardizes newline characters to \n
-	*
-	* @return	void
-	*/
+	 * Sanitize Globals
+	 *
+	 * This function does the following:
+	 *
+	 * - Unsets $_GET data (if query strings are not enabled)
+	 * - Unsets all globals if register_globals is enabled
+	 * - Standardizes newline characters to \n
+	 *
+	 * @return	void
+	 */
 	protected function _sanitize_globals()
 	{
 		// It would be "wrong" to unset any of these GLOBALS.
-		$protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST',
-					'_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',
-					'system_folder', 'application_folder', 'BM', 'EXT',
-					'CFG', 'URI', 'RTR', 'OUT', 'IN'
-				);
+		$protected = array(
+			'_SERVER',
+			'_GET',
+			'_POST',
+			'_FILES',
+			'_REQUEST',
+			'_SESSION',
+			'_ENV',
+			'GLOBALS',
+			'HTTP_RAW_POST_DATA',
+			'system_folder',
+			'application_folder',
+			'BM',
+			'EXT',
+			'CFG',
+			'URI',
+			'RTR',
+			'OUT',
+			'IN'
+		);
 
 		// Unset globals for securiy.
 		// This is effectively the same as register_globals = off
 		foreach (array($_GET, $_POST, $_COOKIE) as $global)
 		{
-			if ( ! is_array($global))
-			{
-				if ( ! in_array($global, $protected))
-				{
-					global $$global;
-					$$global = NULL;
-				}
-			}
-			else
+			if (is_array($global))
 			{
 				foreach ($global as $key => $val)
 				{
@@ -436,10 +455,15 @@
 					}
 				}
 			}
+			elseif ( ! in_array($global, $protected))
+			{
+				global $$global;
+				$$global = NULL;
+			}
 		}
 
 		// Is $_GET data allowed? If not we'll set the $_GET to an empty array
-		if ($this->_allow_get_array == FALSE)
+		if ($this->_allow_get_array === FALSE)
 		{
 			$_GET = array();
 		}
@@ -482,7 +506,7 @@
 		$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
 
 		// CSRF Protection check
-		if ($this->_enable_csrf == TRUE)
+		if ($this->_enable_csrf === TRUE)
 		{
 			$this->security->csrf_verify();
 		}
@@ -493,14 +517,14 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Clean Input Data
-	*
-	* This is a helper function. It escapes data and
-	* standardizes newline characters to \n
-	*
-	* @param	string
-	* @return	string
-	*/
+	 * Clean Input Data
+	 *
+	 * This is a helper function. It escapes data and
+	 * standardizes newline characters to \n
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	protected function _clean_input_data($str)
 	{
 		if (is_array($str))
@@ -539,7 +563,7 @@
 		}
 
 		// Standardize newlines if needed
-		if ($this->_standardize_newlines == TRUE && strpos($str, "\r") !== FALSE)
+		if ($this->_standardize_newlines === TRUE && strpos($str, "\r") !== FALSE)
 		{
 			return str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);
 		}
@@ -550,15 +574,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Clean Keys
-	*
-	* This is a helper function. To prevent malicious users
-	* from trying to exploit keys we make sure that keys are
-	* only named with alpha-numeric text and a few other items.
-	*
-	* @param	string
-	* @return	string
-	*/
+	 * Clean Keys
+	 *
+	 * This is a helper function. To prevent malicious users
+	 * from trying to exploit keys we make sure that keys are
+	 * only named with alpha-numeric text and a few other items.
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	protected function _clean_input_keys($str)
 	{
 		if ( ! preg_match('/^[a-z0-9:_\/-]+$/i', $str))
@@ -584,7 +608,7 @@
 	 * In Apache, you can simply call apache_request_headers(), however for
 	 * people running other webservers the function is undefined.
 	 *
-	 * @param	bool XSS cleaning
+	 * @param	bool	XSS cleaning
 	 * @return	array
 	 */
 	public function request_headers($xss_clean = FALSE)
@@ -639,7 +663,7 @@
 
 		if ( ! isset($this->headers[$index]))
 		{
-			return FALSE;
+			return NULL;
 		}
 
 		return ($xss_clean === TRUE)
@@ -695,4 +719,4 @@
 }
 
 /* End of file Input.php */
-/* Location: ./system/core/Input.php */
+/* Location: ./system/core/Input.php */
\ No newline at end of file
diff --git a/system/core/Lang.php b/system/core/Lang.php
index 9ef76f4..3001f1b 100755
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Language Class
  *
@@ -43,14 +41,20 @@
 	 *
 	 * @var array
 	 */
-	public $language	= array();
+	public $language =	array();
+
 	/**
 	 * List of loaded language files
 	 *
 	 * @var array
 	 */
-	public $is_loaded	= array();
+	public $is_loaded =	array();
 
+	/**
+	 * Initialize language class
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
 		log_message('debug', 'Language Class Initialized');
@@ -61,39 +65,37 @@
 	/**
 	 * Load a language file
 	 *
-	 * @param	mixed	the name of the language file to be loaded. Can be an array
+	 * @param	mixed	the name of the language file to be loaded
 	 * @param	string	the language (english, etc.)
 	 * @param	bool	return loaded array of translations
 	 * @param 	bool	add suffix to $langfile
 	 * @param 	string	alternative path to look for language file
 	 * @return	mixed
 	 */
-	public function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
+	public function load($langfile, $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
 	{
 		$langfile = str_replace('.php', '', $langfile);
 
-		if ($add_suffix == TRUE)
+		if ($add_suffix === TRUE)
 		{
-			$langfile = str_replace('_lang.', '', $langfile).'_lang';
+			$langfile = str_replace('_lang', '', $langfile).'_lang';
 		}
 
 		$langfile .= '.php';
 
-		if (in_array($langfile, $this->is_loaded, TRUE))
+		if ($idiom === '')
+		{
+			$config =& get_config();
+			$idiom = ( ! empty($config['language'])) ? $config['language'] : 'english';
+		}
+
+		if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom)
 		{
 			return;
 		}
 
-		$config =& get_config();
-
-		if ($idiom == '')
-		{
-			$deft_lang = ( ! isset($config['language'])) ? 'english' : $config['language'];
-			$idiom = ($deft_lang == '') ? 'english' : $deft_lang;
-		}
-
 		// Determine where the language file is and load it
-		if ($alt_path != '' && file_exists($alt_path.'language/'.$idiom.'/'.$langfile))
+		if ($alt_path !== '' && file_exists($alt_path.'language/'.$idiom.'/'.$langfile))
 		{
 			include($alt_path.'language/'.$idiom.'/'.$langfile);
 		}
@@ -121,17 +123,21 @@
 		if ( ! isset($lang) OR ! is_array($lang))
 		{
 			log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
+
+			if ($return === TRUE)
+			{
+				return array();
+			}
 			return;
 		}
 
-		if ($return == TRUE)
+		if ($return === TRUE)
 		{
 			return $lang;
 		}
 
-		$this->is_loaded[] = $langfile;
+		$this->is_loaded[$langfile] = $idiom;
 		$this->language = array_merge($this->language, $lang);
-		unset($lang);
 
 		log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);
 		return TRUE;
@@ -147,7 +153,7 @@
 	 */
 	public function line($line = '')
 	{
-		$value = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
+		$value = ($line === '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
 
 		// Because killer robots like unicorns!
 		if ($value === FALSE)
@@ -161,4 +167,4 @@
 }
 
 /* End of file Lang.php */
-/* Location: ./system/core/Lang.php */
+/* Location: ./system/core/Lang.php */
\ No newline at end of file
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 976a5a5..09e9487 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -32,8 +32,8 @@
  *
  * @package		CodeIgniter
  * @subpackage	Libraries
- * @author		EllisLab Dev Team
  * @category	Loader
+ * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/libraries/loader.html
  */
 class CI_Loader {
@@ -45,80 +45,93 @@
 	 * @var int
 	 */
 	protected $_ci_ob_level;
+
 	/**
 	 * List of paths to load views from
 	 *
 	 * @var array
 	 */
-	protected $_ci_view_paths		= array();
+	protected $_ci_view_paths =	array();
+
 	/**
 	 * List of paths to load libraries from
 	 *
 	 * @var array
 	 */
-	protected $_ci_library_paths	= array();
+	protected $_ci_library_paths =	array();
+
 	/**
 	 * List of paths to load models from
 	 *
 	 * @var array
 	 */
-	protected $_ci_model_paths		= array();
+	protected $_ci_model_paths =	array();
+
 	/**
 	 * List of paths to load helpers from
 	 *
 	 * @var array
 	 */
-	protected $_ci_helper_paths		= array();
+	protected $_ci_helper_paths =	array();
+
 	/**
 	 * List of loaded base classes
 	 *
 	 * @var array
 	 */
-	protected $_base_classes		= array(); // Set by the controller class
+	protected $_base_classes =	array(); // Set by the controller class
+
 	/**
 	 * List of cached variables
 	 *
 	 * @var array
 	 */
-	protected $_ci_cached_vars		= array();
+	protected $_ci_cached_vars =	array();
+
 	/**
 	 * List of loaded classes
 	 *
 	 * @var array
 	 */
-	protected $_ci_classes			= array();
+	protected $_ci_classes =	array();
+
 	/**
 	 * List of loaded files
 	 *
 	 * @var array
 	 */
-	protected $_ci_loaded_files		= array();
+	protected $_ci_loaded_files =	array();
+
 	/**
 	 * List of loaded models
 	 *
 	 * @var array
 	 */
-	protected $_ci_models			= array();
+	protected $_ci_models =	array();
+
 	/**
 	 * List of loaded helpers
 	 *
 	 * @var array
 	 */
-	protected $_ci_helpers			= array();
+	protected $_ci_helpers =	array();
+
 	/**
 	 * List of class name mappings
 	 *
 	 * @var array
 	 */
-	protected $_ci_varmap			= array(
-							'unit_test' => 'unit',
-							'user_agent' => 'agent'
-							);
+	protected $_ci_varmap =	array(
+		'unit_test' => 'unit',
+		'user_agent' => 'agent'
+	);
 
 	/**
 	 * Constructor
 	 *
 	 * Sets the path to the view files and gets the initial output buffering level
+	 *
+	 * @return	void
 	 */
 	public function __construct()
 	{
@@ -138,7 +151,6 @@
 	 *
 	 * This method is called once in CI_Controller.
 	 *
-	 * @param 	array
 	 * @return 	object
 	 */
 	public function initialize()
@@ -168,12 +180,7 @@
 	 */
 	public function is_loaded($class)
 	{
-		if (isset($this->_ci_classes[$class]))
-		{
-			return $this->_ci_classes[$class];
-		}
-
-		return FALSE;
+		return isset($this->_ci_classes[$class]) ? $this->_ci_classes[$class] : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -201,7 +208,7 @@
 			return;
 		}
 
-		if ($library == '' OR isset($this->_base_classes[$library]))
+		if ($library === '' OR isset($this->_base_classes[$library]))
 		{
 			return FALSE;
 		}
@@ -237,7 +244,7 @@
 			return;
 		}
 
-		if ($model == '')
+		if ($model === '')
 		{
 			return;
 		}
@@ -254,7 +261,7 @@
 			$model = substr($model, $last_slash);
 		}
 
-		if ($name == '')
+		if (empty($name))
 		{
 			$name = $model;
 		}
@@ -313,16 +320,16 @@
 	 *
 	 * @param	string	the DB credentials
 	 * @param	bool	whether to return the DB object
-	 * @param	bool	whether to enable active record (this allows us to override the config setting)
+	 * @param	bool	whether to enable query builder (this allows us to override the config setting)
 	 * @return	object
 	 */
-	public function database($params = '', $return = FALSE, $active_record = NULL)
+	public function database($params = '', $return = FALSE, $query_builder = NULL)
 	{
 		// Grab the super object
 		$CI =& get_instance();
 
 		// Do we even need to load the database class?
-		if (class_exists('CI_DB') && $return == FALSE && $active_record == NULL && isset($CI->db) && is_object($CI->db))
+		if (class_exists('CI_DB') && $return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db))
 		{
 			return FALSE;
 		}
@@ -331,7 +338,7 @@
 
 		if ($return === TRUE)
 		{
-			return DB($params, $active_record);
+			return DB($params, $query_builder);
 		}
 
 		// Initialize the db variable. Needed to prevent
@@ -339,7 +346,7 @@
 		$CI->db = '';
 
 		// Load the DB class
-		$CI->db =& DB($params, $active_record);
+		$CI->db =& DB($params, $query_builder);
 	}
 
 	// --------------------------------------------------------------------
@@ -445,7 +452,7 @@
 	 */
 	public function vars($vars = array(), $val = '')
 	{
-		if ($val != '' && is_string($vars))
+		if ($val !== '' && is_string($vars))
 		{
 			$vars = array($vars => $val);
 		}
@@ -635,7 +642,7 @@
 			require BASEPATH.'libraries/Driver.php';
 		}
 
-		if ($library == '')
+		if ($library === '')
 		{
 			return FALSE;
 		}
@@ -673,7 +680,7 @@
 
 		// Add config file path
 		$config =& $this->_ci_get_component('config');
-		array_unshift($config->_config_paths, $path);
+		array_push($config->_config_paths, $path);
 	}
 
 	// --------------------------------------------------------------------
@@ -707,13 +714,13 @@
 	{
 		$config =& $this->_ci_get_component('config');
 
-		if ($path == '')
+		if ($path === '')
 		{
 			array_shift($this->_ci_library_paths);
 			array_shift($this->_ci_model_paths);
 			array_shift($this->_ci_helper_paths);
 			array_shift($this->_ci_view_paths);
-			array_shift($config->_config_paths);
+			array_pop($config->_config_paths);
 		}
 		else
 		{
@@ -768,7 +775,7 @@
 		$file_exists = FALSE;
 
 		// Set the path to the requested file
-		if ($_ci_path != '')
+		if (is_string($_ci_path) && $_ci_path !== '')
 		{
 			$_ci_x = explode('/', $_ci_path);
 			$_ci_file = end($_ci_x);
@@ -776,7 +783,7 @@
 		else
 		{
 			$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
-			$_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view;
+			$_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view;
 
 			foreach ($this->_ci_view_paths as $view_file => $cascade)
 			{
@@ -840,7 +847,7 @@
 		// If the PHP installation does not support short tags we'll
 		// do a little string replacement, changing the short tags
 		// to standard PHP echo statements.
-		if ( ! is_php('5.4') && (bool) @ini_get('short_open_tag') === FALSE && config_item('rewrite_short_tags') == TRUE)
+		if ( ! is_php('5.4') && (bool) @ini_get('short_open_tag') === FALSE && config_item('rewrite_short_tags') === TRUE)
 		{
 			echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
 		}
@@ -993,7 +1000,7 @@
 		} // END FOREACH
 
 		// One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
-		if ($subdir == '')
+		if ($subdir === '')
 		{
 			$path = strtolower($class).'/'.$class;
 			return $this->_ci_load_class($path, $params);
@@ -1001,7 +1008,7 @@
 
 		// If we got this far we were unable to find the requested class.
 		// We do not issue errors if the load call failed due to a duplicate request
-		if ($is_duplicate == FALSE)
+		if ($is_duplicate === FALSE)
 		{
 			log_message('error', 'Unable to load the requested class: '.$class);
 			show_error('Unable to load the requested class: '.$class);
@@ -1060,7 +1067,7 @@
 			}
 		}
 
-		if ($prefix == '')
+		if ($prefix === '')
 		{
 			if (class_exists('CI_'.$class))
 			{
@@ -1111,7 +1118,7 @@
 		}
 		else
 		{
-			$CI->$classvar = new $name;
+			$CI->$classvar = new $name();
 		}
 	}
 
@@ -1123,7 +1130,6 @@
 	 * The config/autoload.php file contains an array that permits sub-systems,
 	 * libraries, and helpers to be loaded automatically.
 	 *
-	 * @param	array
 	 * @return	void
 	 */
 	protected function _ci_autoloader()
diff --git a/system/core/Model.php b/system/core/Model.php
index 49b8d34..9bc9f87 100755
--- a/system/core/Model.php
+++ b/system/core/Model.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Model Class
  *
@@ -38,6 +36,11 @@
  */
 class CI_Model {
 
+	/**
+	 * Initialize CI_Model Class
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
 		log_message('debug', 'Model Class Initialized');
@@ -56,7 +59,8 @@
 		$CI =& get_instance();
 		return $CI->$key;
 	}
+
 }
 
 /* End of file Model.php */
-/* Location: ./system/core/Model.php */
+/* Location: ./system/core/Model.php */
\ No newline at end of file
diff --git a/system/core/Output.php b/system/core/Output.php
index 9bf818e..5588ffe 100755
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -43,66 +43,69 @@
 	 *
 	 * @var string
 	 */
-	protected $final_output;
+	public $final_output;
+
 	/**
 	 * Cache expiration time
 	 *
 	 * @var int
 	 */
-	protected $cache_expiration	= 0;
+	public $cache_expiration =	0;
+
 	/**
 	 * List of server headers
 	 *
 	 * @var array
 	 */
-	protected $headers			= array();
+	public $headers =	array();
+
 	/**
 	 * List of mime types
 	 *
 	 * @var array
 	 */
-	protected $mime_types		= array();
+	public $mimes =		array();
+
 	/**
 	 * Determines wether profiler is enabled
 	 *
 	 * @var book
 	 */
-	protected $enable_profiler	= FALSE;
+	public $enable_profiler =	FALSE;
+
 	/**
 	 * Determines if output compression is enabled
 	 *
 	 * @var bool
 	 */
-	protected $_zlib_oc			= FALSE;
+	protected $_zlib_oc =	FALSE;
+
 	/**
 	 * List of profiler sections
 	 *
 	 * @var array
 	 */
-	protected $_profiler_sections = array();
+	protected $_profiler_sections =	array();
+
 	/**
 	 * Whether or not to parse variables like {elapsed_time} and {memory_usage}
 	 *
 	 * @var bool
 	 */
-	protected $parse_exec_vars	= TRUE;
+	public $parse_exec_vars =	TRUE;
 
+	/**
+	 * Set up Output class
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
-		$this->_zlib_oc = @ini_get('zlib.output_compression');
+		$this->_zlib_oc = (bool) @ini_get('zlib.output_compression');
 
 		// Get mime types for later
-		if (defined('ENVIRONMENT') && file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
-		{
-			include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';
-		}
-		else
-		{
-			include APPPATH.'config/mimes.php';
-		}
+		$this->mimes =& get_mimes();
 
-
-		$this->mime_types = $mimes;
 		log_message('debug', 'Output Class Initialized');
 	}
 
@@ -167,7 +170,7 @@
 	 *
 	 * Lets you set a server header which will be outputted with the final display.
 	 *
-	 * Note:  If a file is cached, headers will not be sent.  We need to figure out
+	 * Note: If a file is cached, headers will not be sent. We need to figure out
 	 * how to permit header data to be saved with the cache data...
 	 *
 	 * @param	string
@@ -180,7 +183,7 @@
 		// but it will not modify the content-length header to compensate for
 		// the reduction, causing the browser to hang waiting for more data.
 		// We'll just skip content-length in those cases.
-		if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) == 0)
+		if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) === 0)
 		{
 			return;
 		}
@@ -197,16 +200,16 @@
 	 * @param	string	extension of the file we're outputting
 	 * @return	void
 	 */
-	public function set_content_type($mime_type)
+	public function set_content_type($mime_type, $charset = NULL)
 	{
 		if (strpos($mime_type, '/') === FALSE)
 		{
 			$extension = ltrim($mime_type, '.');
 
 			// Is this extension supported?
-			if (isset($this->mime_types[$extension]))
+			if (isset($this->mimes[$extension]))
 			{
-				$mime_type =& $this->mime_types[$extension];
+				$mime_type =& $this->mimes[$extension];
 
 				if (is_array($mime_type))
 				{
@@ -215,7 +218,13 @@
 			}
 		}
 
-		$header = 'Content-Type: '.$mime_type;
+		if (empty($charset))
+		{
+			$charset = config_item('charset');
+		}
+
+		$header = 'Content-Type: '.$mime_type
+			.(empty($charset) ? NULL : '; charset='.strtolower($charset));
 
 		$this->headers[] = array($header, TRUE);
 		return $this;
@@ -224,6 +233,26 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Get Current Content Type Header
+	 *
+	 * @return	string	'text/html', if not already set
+	 */
+	public function get_content_type()
+	{
+		for ($i = 0, $c = count($this->headers); $i < $c; $i++)
+		{
+			if (preg_match('/^Content-Type:\s(.+)$/', $this->headers[$i][0], $matches))
+			{
+				return $matches[1];
+			}
+		}
+
+		return 'text/html';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Set HTTP Status Header
 	 * moved to Common procedural functions in 1.7.2
 	 *
@@ -317,7 +346,7 @@
 		// --------------------------------------------------------------------
 
 		// Set the output data
-		if ($output == '')
+		if ($output === '')
 		{
 			$output =& $this->final_output;
 		}
@@ -341,7 +370,7 @@
 
 		if ($this->parse_exec_vars === TRUE)
 		{
-			$memory	= function_exists('memory_get_usage') ? round(memory_get_usage()/1024/1024, 2).'MB' : '0';
+			$memory	= round(memory_get_usage() / 1024 / 1024, 2).'MB';
 
 			$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
 		}
@@ -349,7 +378,7 @@
 		// --------------------------------------------------------------------
 
 		// Is compression requested?
-		if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE
+		if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc === FALSE
 			&& extension_loaded('zlib')
 			&& isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
 		{
@@ -384,7 +413,7 @@
 
 		// Do we need to generate profile data?
 		// If so, load the Profile class and run it.
-		if ($this->enable_profiler == TRUE)
+		if ($this->enable_profiler === TRUE)
 		{
 			$CI->load->library('profiler');
 			if ( ! empty($this->_profiler_sections))
@@ -428,7 +457,7 @@
 	{
 		$CI =& get_instance();
 		$path = $CI->config->item('cache_path');
-		$cache_path = ($path == '') ? APPPATH.'cache/' : $path;
+		$cache_path = ($path === '') ? APPPATH.'cache/' : $path;
 
 		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
 		{
@@ -473,11 +502,11 @@
 	 *
 	 * @param 	object	config class
 	 * @param 	object	uri class
-	 * @return	void
+	 * @return	bool
 	 */
 	public function _display_cache(&$CFG, &$URI)
 	{
-		$cache_path = ($CFG->item('cache_path') == '') ? APPPATH.'cache/' : $CFG->item('cache_path');
+		$cache_path = ($CFG->item('cache_path') === '') ? APPPATH.'cache/' : $CFG->item('cache_path');
 
 		// Build the file path. The file name is an MD5 hash of the full URI
 		$uri =	$CFG->item('base_url').$CFG->item('index_page').$URI->uri_string;
diff --git a/system/core/Router.php b/system/core/Router.php
index 5477fed..5bc0530 100755
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -32,8 +32,8 @@
  *
  * @package		CodeIgniter
  * @subpackage	Libraries
- * @author		EllisLab Dev Team
  * @category	Libraries
+ * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/general/routing.html
  */
 class CI_Router {
@@ -44,36 +44,42 @@
 	 * @var object
 	 */
 	public $config;
+
 	/**
 	 * List of routes
 	 *
 	 * @var array
 	 */
-	public $routes			= array();
+	public $routes =	array();
+
 	/**
 	 * List of error routes
 	 *
 	 * @var array
 	 */
-	public $error_routes	= array();
+	public $error_routes =	array();
+
 	/**
 	 * Current class name
 	 *
 	 * @var string
 	 */
-	public $class			= '';
+	public $class =		'';
+
 	/**
 	 * Current method name
 	 *
 	 * @var string
 	 */
-	public $method			= 'index';
+	public $method =	'index';
+
 	/**
 	 * Sub-directory that contains the requested controller class
 	 *
 	 * @var string
 	 */
-	public $directory		= '';
+	public $directory =	'';
+
 	/**
 	 * Default controller (and method if specific)
 	 *
@@ -85,6 +91,8 @@
 	 * Constructor
 	 *
 	 * Runs the route mapping function.
+	 *
+	 * @return	void
 	 */
 	public function __construct()
 	{
@@ -211,7 +219,6 @@
 	 * input, and sets the current class/method
 	 *
 	 * @param	array
-	 * @param	bool
 	 * @return	void
 	 */
 	protected function _set_request($segments = array())
@@ -428,12 +435,7 @@
 	 */
 	public function fetch_method()
 	{
-		if ($this->method == $this->fetch_class())
-		{
-			return 'index';
-		}
-
-		return $this->method;
+		return ($this->method === $this->fetch_class()) ? 'index' : $this->method;
 	}
 
 	// --------------------------------------------------------------------
@@ -481,7 +483,7 @@
 			$this->set_directory($routing['directory']);
 		}
 
-		if (isset($routing['controller']) && $routing['controller'] != '')
+		if ( ! empty($routing['controller']))
 		{
 			$this->set_class($routing['controller']);
 		}
diff --git a/system/core/Security.php b/system/core/Security.php
index ac39ce9..4593a10 100755
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -41,14 +41,14 @@
 	 *
 	 * @var string
 	 */
-	protected $_xss_hash			= '';
+	protected $_xss_hash =	'';
 
 	/**
 	 * Random Hash for Cross Site Request Forgery Protection Cookie
 	 *
 	 * @var string
 	 */
-	protected $_csrf_hash			= '';
+	protected $_csrf_hash =	'';
 
 	/**
 	 * Expiration time for Cross Site Request Forgery Protection Cookie
@@ -56,39 +56,39 @@
 	 *
 	 * @var int
 	 */
-	protected $_csrf_expire			= 7200;
+	protected $_csrf_expire =	7200;
 
 	/**
 	 * Token name for Cross Site Request Forgery Protection Cookie
 	 *
 	 * @var string
 	 */
-	protected $_csrf_token_name		= 'ci_csrf_token';
+	protected $_csrf_token_name =	'ci_csrf_token';
 
 	/**
 	 * Cookie name for Cross Site Request Forgery Protection Cookie
 	 *
 	 * @var string
 	 */
-	protected $_csrf_cookie_name		= 'ci_csrf_token';
+	protected $_csrf_cookie_name =	'ci_csrf_token';
 
 	/**
 	 * List of never allowed strings
 	 *
 	 * @var array
 	 */
-	protected $_never_allowed_str = array(
-						'document.cookie'	=> '[removed]',
-						'document.write'	=> '[removed]',
-						'.parentNode'		=> '[removed]',
-						'.innerHTML'		=> '[removed]',
-						'window.location'	=> '[removed]',
-						'-moz-binding'		=> '[removed]',
-						'<!--'				=> '&lt;!--',
-						'-->'				=> '--&gt;',
-						'<![CDATA['			=> '&lt;![CDATA[',
-						'<comment>'			=> '&lt;comment&gt;'
-					);
+	protected $_never_allowed_str =	array(
+		'document.cookie'	=> '[removed]',
+		'document.write'	=> '[removed]',
+		'.parentNode'		=> '[removed]',
+		'.innerHTML'		=> '[removed]',
+		'window.location'	=> '[removed]',
+		'-moz-binding'		=> '[removed]',
+		'<!--'				=> '&lt;!--',
+		'-->'				=> '--&gt;',
+		'<![CDATA['			=> '&lt;![CDATA[',
+		'<comment>'			=> '&lt;comment&gt;'
+	);
 
 	/**
 	 * List of never allowed regex replacement
@@ -96,12 +96,18 @@
 	 * @var array
 	 */
 	protected $_never_allowed_regex = array(
-						'javascript\s*:',
-						'expression\s*(\(|&\#40;)', // CSS and IE
-						'vbscript\s*:', // IE, surprise!
-						'Redirect\s+302'
-					);
+		'javascript\s*:',
+		'expression\s*(\(|&\#40;)', // CSS and IE
+		'vbscript\s*:', // IE, surprise!
+		'Redirect\s+302',
+		"([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?"
+	);
 
+	/**
+	 * Initialize security class
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
 		// Is CSRF protection enabled?
@@ -156,7 +162,7 @@
 
 		// Do the tokens exist in both the _POST and _COOKIE arrays?
 		if ( ! isset($_POST[$this->_csrf_token_name]) OR ! isset($_COOKIE[$this->_csrf_cookie_name])
-			OR $_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match?
+			OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match?
 		{
 			$this->csrf_show_error();
 		}
@@ -185,6 +191,7 @@
 	 * Set Cross Site Request Forgery Protection Cookie
 	 *
 	 * @return	object
+	 * @codeCoverageIgnore
 	 */
 	public function csrf_set_cookie()
 	{
@@ -197,11 +204,11 @@
 		}
 
 		setcookie(
-			$this->_csrf_cookie_name, 
-			$this->_csrf_hash, 
-			$expire, 
-			config_item('cookie_path'), 
-			config_item('cookie_domain'), 
+			$this->_csrf_cookie_name,
+			$this->_csrf_hash,
+			$expire,
+			config_item('cookie_path'),
+			config_item('cookie_domain'),
 			$secure_cookie,
 			config_item('cookie_httponly')
 		);
@@ -362,9 +369,10 @@
 		 * These words are compacted back to their correct state.
 		 */
 		$words = array(
-				'javascript', 'expression', 'vbscript', 'script',
-				'applet', 'alert', 'document', 'write', 'cookie', 'window'
-			);
+			'javascript', 'expression', 'vbscript', 'script', 'base64',
+			'applet', 'alert', 'document', 'write', 'cookie', 'window'
+		);
+
 
 		foreach ($words as $word)
 		{
@@ -400,7 +408,7 @@
 				$str = preg_replace('#<(/*)(script|xss)(.*?)\>#si', '[removed]', $str);
 			}
 		}
-		while($original != $str);
+		while($original !== $str);
 
 		unset($original);
 
@@ -467,7 +475,7 @@
 	 */
 	public function xss_hash()
 	{
-		if ($this->_xss_hash == '')
+		if ($this->_xss_hash === '')
 		{
 			mt_srand();
 			$this->_xss_hash = md5(time() + mt_rand(0, 1999999999));
@@ -522,23 +530,23 @@
 	public function sanitize_filename($str, $relative_path = FALSE)
 	{
 		$bad = array(
-				'../', '<!--', '-->', '<', '>',
-				"'", '"', '&', '$', '#',
-				'{', '}', '[', ']', '=',
-				';', '?', '%20', '%22',
-				'%3c',		// <
-				'%253c',	// <
-				'%3e',		// >
-				'%0e',		// >
-				'%28',		// (
-				'%29',		// )
-				'%2528',	// (
-				'%26',		// &
-				'%24',		// $
-				'%3f',		// ?
-				'%3b',		// ;
-				'%3d'		// =
-			);
+			'../', '<!--', '-->', '<', '>',
+			"'", '"', '&', '$', '#',
+			'{', '}', '[', ']', '=',
+			';', '?', '%20', '%22',
+			'%3c',		// <
+			'%253c',	// <
+			'%3e',		// >
+			'%0e',		// >
+			'%28',		// (
+			'%29',		// )
+			'%2528',	// (
+			'%26',		// &
+			'%24',		// $
+			'%3f',		// ?
+			'%3b',		// ;
+			'%3d'		// =
+		);
 
 		if ( ! $relative_path)
 		{
@@ -558,8 +566,8 @@
 	 * Callback function for xss_clean() to remove whitespace from
 	 * things like j a v a s c r i p t
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	string
 	 */
 	protected function _compact_exploded_words($matches)
 	{
@@ -568,8 +576,8 @@
 
 	// --------------------------------------------------------------------
 
-	/*
-	 * Remove Evil HTML Attributes (like evenhandlers and style)
+	/**
+	 * Remove Evil HTML Attributes (like event handlers and style)
 	 *
 	 * It removes the evil attribute and either:
 	 * 	- Everything up until a space
@@ -602,10 +610,11 @@
 			$attribs = array();
 
 			// find occurrences of illegal attribute strings without quotes
-			preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s]*)/is', $str, $matches, PREG_SET_ORDER);
+			preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*([^\s>]*)/is', $str, $matches, PREG_SET_ORDER);
 
 			foreach ($matches as $attr)
 			{
+
 				$attribs[] = preg_quote($attr[0], '/');
 			}
 
@@ -620,7 +629,7 @@
 			// replace illegal attribute strings that are inside an html tag
 			if (count($attribs) > 0)
 			{
-				$str = preg_replace('/<(\/?[^><]+?)([^A-Za-z\-])('.implode('|', $attribs).')([\s><])([><]*)/i', '<$1$2$4$5', $str, -1, $count);
+				$str = preg_replace('/<(\/?[^><]+?)([^A-Za-z<>\-])(.*?)('.implode('|', $attribs).')(.*?)([\s><])([><]*)/i', '<$1 $3$5$6$7', $str, -1, $count);
 			}
 
 		} while ($count);
@@ -661,7 +670,7 @@
 	protected function _js_link_removal($match)
 	{
 		return str_replace($match[1],
-					preg_replace('#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
+					preg_replace('#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|data\s*:)#si',
 							'',
 							$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
 					),
@@ -801,7 +810,7 @@
 
 		foreach ($this->_never_allowed_regex as $regex)
 		{
-			$str = preg_replace('#'.$regex.'#i', '[removed]', $str);
+			$str = preg_replace('#'.$regex.'#is', '[removed]', $str);
 		}
 
 		return $str;
@@ -816,14 +825,14 @@
 	 */
 	protected function _csrf_set_hash()
 	{
-		if ($this->_csrf_hash == '')
+		if ($this->_csrf_hash === '')
 		{
 			// If the cookie exists we will use it's value.
 			// We don't necessarily want to regenerate it with
 			// each page load since a page could contain embedded
 			// sub-pages causing this feature to fail
 			if (isset($_COOKIE[$this->_csrf_cookie_name]) &&
-				$_COOKIE[$this->_csrf_cookie_name] != '')
+				preg_match('#^[0-9a-f]{32}$#iS', $_COOKIE[$this->_csrf_cookie_name]) === 1)
 			{
 				return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name];
 			}
@@ -838,4 +847,4 @@
 }
 
 /* End of file Security.php */
-/* Location: ./system/core/Security.php */
+/* Location: ./system/core/Security.php */
\ No newline at end of file
diff --git a/system/core/URI.php b/system/core/URI.php
index 48bb7ae..a575bc3 100755
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -22,10 +22,9 @@
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
+ * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * URI Class
  *
@@ -44,26 +43,29 @@
 	 *
 	 * @var array
 	 */
-	public $keyval		= array();
+	public $keyval =	array();
+
 	/**
 	 * Current uri string
 	 *
 	 * @var string
 	 */
 	public $uri_string;
+
 	/**
 	 * List of uri segments
 	 *
 	 * @var array
 	 */
-	public $segments	= array();
+	public $segments =	array();
+
 	/**
 	 * Re-indexed list of uri segments
 	 * Starts at 1 instead of 0
 	 *
 	 * @var array
 	 */
-	public $rsegments	= array();
+	public $rsegments =	array();
 
 	/**
 	 * Constructor
@@ -71,6 +73,8 @@
 	 * Simply globalizes the $RTR object. The front
 	 * loads the Router class early on so it's not available
 	 * normally as other classes are.
+	 *
+	 * @return	void
 	 */
 	public function __construct()
 	{
@@ -107,8 +111,8 @@
 
 			// Is there a PATH_INFO variable?
 			// Note: some servers seem to have trouble with getenv() so we'll test it two ways
-			$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
-			if (trim($path, '/') != '' && $path !== '/'.SELF)
+			$path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
+			if (trim($path, '/') !== '' && $path !== '/'.SELF)
 			{
 				$this->_set_uri_string($path);
 				return;
@@ -116,14 +120,14 @@
 
 			// No PATH_INFO?... What about QUERY_STRING?
 			$path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
-			if (trim($path, '/') != '')
+			if (trim($path, '/') !== '')
 			{
 				$this->_set_uri_string($path);
 				return;
 			}
 
 			// As a last ditch effort lets try using the $_GET array
-			if (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') != '')
+			if (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') !== '')
 			{
 				$this->_set_uri_string(key($_GET));
 				return;
@@ -147,7 +151,7 @@
 			return;
 		}
 
-		$path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
+		$path = isset($_SERVER[$uri]) ? $_SERVER[$uri] : @getenv($uri);
 		$this->_set_uri_string($path);
 	}
 
@@ -180,7 +184,7 @@
 	 */
 	protected function _detect_uri()
 	{
-		if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
+		if ( ! isset($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']))
 		{
 			return '';
 		}
@@ -214,7 +218,7 @@
 			$_GET = array();
 		}
 
-		if ($uri == '/' OR empty($uri))
+		if ($uri === '/' OR empty($uri))
 		{
 			return '/';
 		}
@@ -226,20 +230,19 @@
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Is cli Request?
 	 *
 	 * Duplicate of function from the Input class to test to see if a request was made from the command line
 	 *
-	 * @return 	boolean
+	 * @return 	bool
 	 */
 	protected function _is_cli_request()
 	{
-		return (php_sapi_name() == 'cli') OR defined('STDIN');
+		return (php_sapi_name() === 'cli') OR defined('STDIN');
 	}
 
-	
 	// --------------------------------------------------------------------
 
 	/**
@@ -252,7 +255,7 @@
 	protected function _parse_cli_args()
 	{
 		$args = array_slice($_SERVER['argv'], 1);
-		return $args ? '/' . implode('/', $args) : '';
+		return $args ? '/'.implode('/', $args) : '';
 	}
 
 	// --------------------------------------------------------------------
@@ -267,7 +270,7 @@
 	 */
 	public function _filter_uri($str)
 	{
-		if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
+		if ($str !== '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') === FALSE)
 		{
 			// preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
 			// compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
@@ -295,7 +298,7 @@
 	 */
 	public function _remove_url_suffix()
 	{
-		if  ($this->config->item('url_suffix') != '')
+		if  ($this->config->item('url_suffix') !== '')
 		{
 			$this->uri_string = preg_replace('|'.preg_quote($this->config->item('url_suffix')).'$|', '', $this->uri_string);
 		}
@@ -318,7 +321,7 @@
 			// Filter segments for security
 			$val = trim($this->_filter_uri($val));
 
-			if ($val != '')
+			if ($val !== '')
 			{
 				$this->segments[] = $val;
 			}
@@ -326,6 +329,7 @@
 	}
 
 	// --------------------------------------------------------------------
+
 	/**
 	 * Re-index Segments
 	 *
@@ -353,13 +357,13 @@
 	 *
 	 * This function returns the URI segment based on the number provided.
 	 *
-	 * @param	integer
-	 * @param	bool
+	 * @param	int
+	 * @param	mixed
 	 * @return	string
 	 */
-	public function segment($n, $no_result = FALSE)
+	public function segment($n, $no_result = NULL)
 	{
-		return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
+		return isset($this->segments[$n]) ? $this->segments[$n] : $no_result;
 	}
 
 	// --------------------------------------------------------------------
@@ -368,16 +372,16 @@
 	 * Fetch a URI "routed" Segment
 	 *
 	 * This function returns the re-routed URI segment (assuming routing rules are used)
-	 * based on the number provided.  If there is no routing this function returns the
+	 * based on the number provided. If there is no routing this function returns the
 	 * same result as $this->segment()
 	 *
-	 * @param	integer
-	 * @param	bool
+	 * @param	int
+	 * @param	mixed
 	 * @return	string
 	 */
-	public function rsegment($n, $no_result = FALSE)
+	public function rsegment($n, $no_result = NULL)
 	{
-		return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
+		return isset($this->rsegments[$n]) ? $this->rsegments[$n] : $no_result;
 	}
 
 	// --------------------------------------------------------------------
@@ -398,7 +402,7 @@
 	 *			gender => male
 	 *		 )
 	 *
-	 * @param	integer	the starting segment number
+	 * @param	int	the starting segment number
 	 * @param	array	an array of default values
 	 * @return	array
 	 */
@@ -406,10 +410,13 @@
 	{
 		return $this->_uri_to_assoc($n, $default, 'segment');
 	}
+
+	// --------------------------------------------------------------------
+
 	/**
 	 * Identical to above only it uses the re-routed segment array
 	 *
-	 * @param 	integer	the starting segment number
+	 * @param 	int	the starting segment number
 	 * @param 	array	an array of default values
 	 * @return 	array
 	 */
@@ -423,7 +430,7 @@
 	/**
 	 * Generate a key value pair from the URI string or Re-routed URI string
 	 *
-	 * @param	integer	the starting segment number
+	 * @param	int	the starting segment number
 	 * @param	array	an array of default values
 	 * @param	string	which array we should use
 	 * @return	array
@@ -453,12 +460,9 @@
 
 		if ($this->$total_segments() < $n)
 		{
-			if (count($default) === 0)
-			{
-				return array();
-			}
-
-			return array_fill_keys($default, FALSE);
+			return (count($default) === 0)
+				? array()
+				: array_fill_keys($default, NULL);
 		}
 
 		$segments = array_slice($this->$segment_array(), ($n - 1));
@@ -473,7 +477,7 @@
 			}
 			else
 			{
-				$retval[$seg] = FALSE;
+				$retval[$seg] = NULL;
 				$lastval = $seg;
 			}
 
@@ -486,7 +490,7 @@
 			{
 				if ( ! array_key_exists($val, $retval))
 				{
-					$retval[$val] = FALSE;
+					$retval[$val] = NULL;
 				}
 			}
 		}
@@ -501,14 +505,13 @@
 	/**
 	 * Generate a URI string from an associative array
 	 *
-	 *
 	 * @param	array	an associative array of key/values
 	 * @return	array
 	 */
 	public function assoc_to_uri($array)
 	{
 		$temp = array();
-		foreach ((array)$array as $key => $val)
+		foreach ((array) $array as $key => $val)
 		{
 			$temp[] = $key;
 			$temp[] = $val;
@@ -522,7 +525,7 @@
 	/**
 	 * Fetch a URI Segment and add a trailing slash
 	 *
-	 * @param	integer
+	 * @param	int
 	 * @param	string
 	 * @return	string
 	 */
@@ -536,7 +539,7 @@
 	/**
 	 * Fetch a URI Segment and add a trailing slash
 	 *
-	 * @param	integer
+	 * @param	int
 	 * @param	string
 	 * @return	string
 	 */
@@ -550,7 +553,7 @@
 	/**
 	 * Fetch a URI Segment and add a trailing slash - helper function
 	 *
-	 * @param	integer
+	 * @param	int
 	 * @param	string
 	 * @param	string
 	 * @return	string
@@ -600,7 +603,7 @@
 	/**
 	 * Total number of segments
 	 *
-	 * @return	integer
+	 * @return	int
 	 */
 	public function total_segments()
 	{
@@ -612,7 +615,7 @@
 	/**
 	 * Total number of routed segments
 	 *
-	 * @return	integer
+	 * @return	int
 	 */
 	public function total_rsegments()
 	{
@@ -641,10 +644,10 @@
 	 */
 	public function ruri_string()
 	{
-		return '/'.implode('/', $this->rsegment_array());
+		return implode('/', $this->rsegment_array());
 	}
 
 }
 
 /* End of file URI.php */
-/* Location: ./system/core/URI.php */
+/* Location: ./system/core/URI.php */
\ No newline at end of file
diff --git a/system/core/Utf8.php b/system/core/Utf8.php
index ba35674..0a7ec50 100644
--- a/system/core/Utf8.php
+++ b/system/core/Utf8.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Utf8 Class
  *
@@ -44,6 +42,8 @@
 	 * Constructor
 	 *
 	 * Determines if UTF-8 support is to be enabled
+	 *
+	 * @return	void
 	 */
 	public function __construct()
 	{
@@ -54,7 +54,7 @@
 		if (
 			@preg_match('/./u', 'é') === 1		// PCRE must support UTF-8
 			&& function_exists('iconv')			// iconv must be installed
-			&& @ini_get('mbstring.func_overload') != 1	// Multibyte string function overloading cannot be enabled
+			&& (bool) @ini_get('mbstring.func_overload') !== TRUE	// Multibyte string function overloading cannot be enabled
 			&& $CFG->item('charset') === 'UTF-8'		// Application charset must be UTF-8
 			)
 		{
@@ -126,7 +126,7 @@
 	 * Attempts to convert a string to UTF-8
 	 *
 	 * @param	string
-	 * @param	string	- input encoding
+	 * @param	string	input encoding
 	 * @return	string
 	 */
 	public function convert_to_utf8($str, $encoding)
@@ -161,4 +161,4 @@
 }
 
 /* End of file Utf8.php */
-/* Location: ./system/core/Utf8.php */
+/* Location: ./system/core/Utf8.php */
\ No newline at end of file
diff --git a/system/database/DB.php b/system/database/DB.php
index 96e4955..00d14b4 100755
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -32,9 +32,9 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/database/
  * @param 	string
- * @param 	bool	Determines if active record should be used or not
+ * @param 	bool	Determines if query builder should be used or not
  */
-function &DB($params = '', $active_record_override = NULL)
+function &DB($params = '', $query_builder_override = NULL)
 {
 	// Load the DB config file if a DSN string wasn't passed
 	if (is_string($params) && strpos($params, '://') === FALSE)
@@ -53,7 +53,7 @@
 			show_error('No database connection settings were found in the database config file.');
 		}
 
-		if ($params != '')
+		if ($params !== '')
 		{
 			$active_group = $params;
 		}
@@ -92,16 +92,12 @@
 		if (isset($dsn['query']))
 		{
 			parse_str($dsn['query'], $extra);
+
 			foreach ($extra as $key => $val)
 			{
-				// booleans please
-				if (strtoupper($val) === 'TRUE')
+				if (is_string($val) && in_array(strtoupper($val), array('TRUE', 'FALSE', 'NULL')))
 				{
-					$val = TRUE;
-				}
-				elseif (strtoupper($val) === 'FALSE')
-				{
-					$val = FALSE;
+					$val = var_export($val);
 				}
 
 				$params[$key] = $val;
@@ -110,27 +106,34 @@
 	}
 
 	// No DB specified yet? Beat them senseless...
-	if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
+	if (empty($params['dbdriver']))
 	{
 		show_error('You have not selected a database type to connect to.');
 	}
 
-	// Load the DB classes. Note: Since the active record class is optional
+	// Load the DB classes. Note: Since the query builder class is optional
 	// we need to dynamically create a class that extends proper parent class
-	// based on whether we're using the active record class or not.
-	if ($active_record_override !== NULL)
+	// based on whether we're using the query builder class or not.
+	if ($query_builder_override !== NULL)
 	{
-		$active_record = $active_record_override;
+		$query_builder = $query_builder_override;
+	}
+	// Backwards compatibility work-around for keeping the
+	// $active_record config variable working. Should be
+	// removed in v3.1
+	elseif ( ! isset($query_builder) && isset($active_record))
+	{
+		$query_builder = $active_record;
 	}
 
 	require_once(BASEPATH.'database/DB_driver.php');
 
-	if ( ! isset($active_record) OR $active_record == TRUE)
+	if ( ! isset($query_builder) OR $query_builder === TRUE)
 	{
-		require_once(BASEPATH.'database/DB_active_rec.php');
+		require_once(BASEPATH.'database/DB_query_builder.php');
 		if ( ! class_exists('CI_DB'))
 		{
-			class CI_DB extends CI_DB_active_record { }
+			class CI_DB extends CI_DB_query_builder { }
 		}
 	}
 	elseif ( ! class_exists('CI_DB'))
@@ -138,18 +141,23 @@
 		class CI_DB extends CI_DB_driver { }
 	}
 
-	require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php');
+	// Load the DB driver
+	$driver_file = BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php';
+
+	if ( ! file_exists($driver_file)) show_error('Invalid DB driver');
+
+	require_once($driver_file);
 
 	// Instantiate the DB adapter
 	$driver = 'CI_DB_'.$params['dbdriver'].'_driver';
 	$DB = new $driver($params);
 
-	if ($DB->autoinit == TRUE)
+	if ($DB->autoinit === TRUE)
 	{
 		$DB->initialize();
 	}
 
-	if (isset($params['stricton']) && $params['stricton'] == TRUE)
+	if ( ! empty($params['stricton']))
 	{
 		$DB->query('SET SESSION sql_mode="STRICT_ALL_TABLES"');
 	}
diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php
index 58e6968..ba91103 100644
--- a/system/database/DB_cache.php
+++ b/system/database/DB_cache.php
@@ -55,9 +55,9 @@
 	 */
 	public function check_path($path = '')
 	{
-		if ($path == '')
+		if ($path === '')
 		{
-			if ($this->db->cachedir == '')
+			if ($this->db->cachedir === '')
 			{
 				return $this->db->cache_off();
 			}
@@ -99,7 +99,7 @@
 		$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
 		$filepath = $this->db->cachedir.$segment_one.'+'.$segment_two.'/'.md5($sql);
 
-		if (FALSE === ($cachedata = read_file($filepath)))
+		if (FALSE === ($cachedata = file_get_contents($filepath)))
 		{
 			return FALSE;
 		}
@@ -154,12 +154,12 @@
 	 */
 	public function delete($segment_one = '', $segment_two = '')
 	{
-		if ($segment_one == '')
+		if ($segment_one === '')
 		{
 			$segment_one  = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
 		}
 
-		if ($segment_two == '')
+		if ($segment_two === '')
 		{
 			$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
 		}
@@ -177,7 +177,7 @@
 	 */
 	public function delete_all()
 	{
-		delete_files($this->db->cachedir, TRUE);
+		delete_files($this->db->cachedir, TRUE, 0, TRUE);
 	}
 
 }
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 9f1a0b8..65f1f18 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -99,9 +99,13 @@
 	 */
 	public function initialize()
 	{
-		// If an existing connection resource is available
-		// there is no need to connect and select the database
-		if (is_resource($this->conn_id) OR is_object($this->conn_id))
+		/* If an established connection is available, then there's
+		 * no need to connect and select the database.
+		 *
+		 * Depending on the database driver, conn_id can be either
+		 * boolean TRUE, a resource or an object.
+		 */
+		if ($this->conn_id)
 		{
 			return TRUE;
 		}
@@ -109,7 +113,7 @@
 		// ----------------------------------------------------------------
 
 		// Connect to the database and set the connection ID
-		$this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();
+		$this->conn_id = ($this->pconnect === FALSE) ? $this->db_connect() : $this->db_pconnect();
 
 		// No connection resource? Check if there is a failover else throw an error
 		if ( ! $this->conn_id)
@@ -127,7 +131,7 @@
 					}
 
 					// Try to connect
-					$this->conn_id = ($this->pconnect == FALSE) ? $this->db_connect() : $this->db_pconnect();
+					$this->conn_id = ($this->pconnect === FALSE) ? $this->db_connect() : $this->db_pconnect();
 
 					// If a connection is made break the foreach loop
 					if ($this->conn_id)
@@ -188,10 +192,24 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Select database
+	 *
+	 * This is just a dummy method to allow drivers without such
+	 * functionality to not declare it, while others will override it.
+	 *
+	 * @return      bool
+	 */
+	public function db_select()
+	{
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Set client character set
 	 *
 	 * @param	string
-	 * @param	string
 	 * @return	bool
 	 */
 	public function db_set_charset($charset)
@@ -279,21 +297,17 @@
 	 */
 	public function query($sql, $binds = FALSE, $return_object = TRUE)
 	{
-		if ($sql == '')
+		if ($sql === '')
 		{
 			log_message('error', 'Invalid query: '.$sql);
 
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_invalid_query');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_invalid_query') : FALSE;
 		}
 
 		// Verify table prefix and replace if necessary
-		if ( ($this->dbprefix != '' AND $this->swap_pre != '') AND ($this->dbprefix != $this->swap_pre) )
+		if ($this->dbprefix !== '' && $this->swap_pre !== '' && $this->dbprefix !== $this->swap_pre)
 		{
-			$sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);
+			$sql = preg_replace('/(\W)'.$this->swap_pre.'(\S+?)/', '\\1'.$this->dbprefix.'\\2', $sql);
 		}
 
 		// Compile binds if needed
@@ -305,31 +319,28 @@
 		// Is query caching enabled? If the query is a "read type"
 		// we will load the caching class and return the previously
 		// cached query if it exists
-		if ($this->cache_on == TRUE AND stristr($sql, 'SELECT'))
+		if ($this->cache_on === TRUE && stripos($sql, 'SELECT') !== FALSE && $this->_cache_init())
 		{
-			if ($this->_cache_init())
+			$this->load_rdriver();
+			if (FALSE !== ($cache = $this->CACHE->read($sql)))
 			{
-				$this->load_rdriver();
-				if (FALSE !== ($cache = $this->CACHE->read($sql)))
-				{
-					return $cache;
-				}
+				return $cache;
 			}
 		}
 
 		// Save the  query for debugging
-		if ($this->save_queries == TRUE)
+		if ($this->save_queries === TRUE)
 		{
 			$this->queries[] = $sql;
 		}
 
 		// Start the Query Timer
-		$time_start = list($sm, $ss) = explode(' ', microtime());
+		$time_start = microtime(TRUE);
 
 		// Run the Query
 		if (FALSE === ($this->result_id = $this->simple_query($sql)))
 		{
-			if ($this->save_queries == TRUE)
+			if ($this->save_queries === TRUE)
 			{
 				$this->query_times[] = 0;
 			}
@@ -352,25 +363,19 @@
 				$this->trans_complete();
 
 				// Display errors
-				return $this->display_error(
-								array(
-									'Error Number: '.$error['code'],
-									$error['message'],
-									$sql
-								)
-							);
+				return $this->display_error(array('Error Number: '.$error['code'], $error['message'], $sql));
 			}
 
 			return FALSE;
 		}
 
 		// Stop and aggregate the query time results
-		$time_end = list($em, $es) = explode(' ', microtime());
-		$this->benchmark += ($em + $es) - ($sm + $ss);
+		$time_end = microtime(TRUE);
+		$this->benchmark += $time_end - $time_start;
 
-		if ($this->save_queries == TRUE)
+		if ($this->save_queries === TRUE)
 		{
-			$this->query_times[] = ($em + $es) - ($sm + $ss);
+			$this->query_times[] = $time_end - $time_start;
 		}
 
 		// Increment the query counter
@@ -382,7 +387,7 @@
 		{
 			// If caching is enabled we'll auto-cleanup any
 			// existing files related to this particular URI
-			if ($this->cache_on == TRUE AND $this->cache_autodel == TRUE AND $this->_cache_init())
+			if ($this->cache_on === TRUE && $this->cache_autodel === TRUE && $this->_cache_init())
 			{
 				$this->CACHE->delete();
 			}
@@ -402,11 +407,9 @@
 		$driver		= $this->load_rdriver();
 		$RES		= new $driver($this);
 
-		$RES->num_rows	= $RES->num_rows();
-
-		// Is query caching enabled?  If so, we'll serialize the
+		// Is query caching enabled? If so, we'll serialize the
 		// result object and save it to a cache file.
-		if ($this->cache_on == TRUE AND $this->_cache_init())
+		if ($this->cache_on === TRUE && $this->_cache_init())
 		{
 			// We'll create a new instance of the result object
 			// only without the platform specific driver since
@@ -415,9 +418,9 @@
 			// result object, so we'll have to compile the data
 			// and save it)
 			$CR = new CI_DB_result();
-			$CR->num_rows		= $RES->num_rows();
 			$CR->result_object	= $RES->result_object();
 			$CR->result_array	= $RES->result_array();
+			$CR->num_rows		= $RES->num_rows();
 
 			// Reset these since cached objects can not utilize resource IDs.
 			$CR->conn_id		= NULL;
@@ -608,7 +611,8 @@
 
 		// The count of bind should be 1 less then the count of segments
 		// If there are more bind arguments trim it down
-		if (count($binds) >= count($segments)) {
+		if (count($binds) >= count($segments))
+		{
 			$binds = array_slice($binds, 0, count($segments)-1);
 		}
 
@@ -617,8 +621,7 @@
 		$i = 0;
 		foreach ($binds as $bind)
 		{
-			$result .= $this->escape($bind);
-			$result .= $segments[++$i];
+			$result .= $this->escape($bind).$segments[++$i];
 		}
 
 		return $result;
@@ -634,7 +637,7 @@
 	 */
 	public function is_write_type($sql)
 	{
-		return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|OPTIMIZE|REINDEX)\s+/i', $sql);
+		return (bool) preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s+/i', $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -689,15 +692,15 @@
 	{
 		if (is_string($str) OR method_exists($str, '__toString'))
 		{
-			$str = "'".$this->escape_str($str)."'";
+			return "'".$this->escape_str($str)."'";
 		}
 		elseif (is_bool($str))
 		{
-			$str = ($str === FALSE) ? 0 : 1;
+			return ($str === FALSE) ? 0 : 1;
 		}
 		elseif (is_null($str))
 		{
-			$str = 'NULL';
+			return 'NULL';
 		}
 
 		return $str;
@@ -733,13 +736,36 @@
 	public function primary($table = '')
 	{
 		$fields = $this->list_fields($table);
+		return is_array($fields) ? current($fields) : FALSE;
+	}
 
-		if ( ! is_array($fields))
+	// --------------------------------------------------------------------
+
+	/**
+	 * "Count All" query
+	 *
+	 * Generates a platform-specific query string that counts all records in
+	 * the specified database
+	 *
+	 * @param	string
+	 * @return	int
+	 */
+	public function count_all($table = '')
+	{
+		if ($table === '')
 		{
-			return FALSE;
+			return 0;
 		}
 
-		return current($fields);
+		$query = $this->query($this->_count_string.$this->escape_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
+		if ($query->num_rows() === 0)
+		{
+			return 0;
+		}
+
+		$query = $query->row();
+		$this->_reset_select();
+		return (int) $query->numrows;
 	}
 
 	// --------------------------------------------------------------------
@@ -759,35 +785,40 @@
 
 		if (FALSE === ($sql = $this->_list_tables($constrain_by_prefix)))
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_unsupported_function');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE;
 		}
 
-		$retval = array();
+		$this->data_cache['table_names'] = array();
 		$query = $this->query($sql);
 
-		if ($query->num_rows() > 0)
+		foreach ($query->result_array() as $row)
 		{
-			$table = FALSE;
-			$rows = $query->result_array();
-			$key = (($row = current($rows)) && in_array('table_name', array_map('strtolower', array_keys($row))));
-
-			if ($key)
+			// Do we know from which column to get the table name?
+			if ( ! isset($key))
 			{
-				$table = array_key_exists('TABLE_NAME', $row) ? 'TABLE_NAME' : 'table_name';
+				if (isset($row['table_name']))
+				{
+					$key = 'table_name';
+				}
+				elseif (isset($row['TABLE_NAME']))
+				{
+					$key = 'TABLE_NAME';
+				}
+				else
+				{
+					/* We have no other choice but to just get the first element's key.
+					 * Due to array_shift() accepting it's argument by reference, if
+					 * E_STRICT is on, this would trigger a warning. So we'll have to
+					 * assign it first.
+					 */
+					$key = array_keys($row);
+					$key = array_shift($key);
+				}
 			}
 
-			foreach ($rows as $row)
-			{
-				$retval[] = ( ! $table) ? current($row) : $row[$table];
-			}
+			$this->data_cache['table_names'][] = $row[$key];
 		}
 
-		$this->data_cache['table_names'] = $retval;
-
 		return $this->data_cache['table_names'];
 	}
 
@@ -819,40 +850,47 @@
 			return $this->data_cache['field_names'][$table];
 		}
 
-		if ($table == '')
+		if ($table === '')
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_field_param_missing');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
 		}
 
 		if (FALSE === ($sql = $this->_list_columns($table)))
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_unsupported_function');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE;
 		}
 
 		$query = $this->query($sql);
+		$this->data_cache['field_names'][$table] = array();
 
-		$retval = array();
 		foreach ($query->result_array() as $row)
 		{
-			if (isset($row['COLUMN_NAME']))
+			// Do we know from where to get the column's name?
+			if ( ! isset($key))
 			{
-				$retval[] = $row['COLUMN_NAME'];
+				if (isset($row['column_name']))
+				{
+					$key = 'column_name';
+				}
+				elseif (isset($row['COLUMN_NAME']))
+				{
+					$key = 'COLUMN_NAME';
+				}
+				else
+				{
+					/* We have no other choice but to just get the first element's key.
+					 * Due to array_shift() accepting it's argument by reference, if
+					 * E_STRICT is on, this would trigger a warning. So we'll have to
+					 * assign it first.
+					 */
+					$key = array_keys($row);
+					$key = array_shift($key);
+				}
 			}
-			else
-			{
-				$retval[] = current($row);
-			}
+
+			$this->data_cache['field_names'][$table][] = $row[$key];
 		}
 
-		$this->data_cache['field_names'][$table] = $retval;
 		return $this->data_cache['field_names'][$table];
 	}
 
@@ -867,7 +905,7 @@
 	 */
 	public function field_exists($field_name, $table_name)
 	{
-		return ( ! in_array($field_name, $this->list_fields($table_name))) ? FALSE : TRUE;
+		return in_array($field_name, $this->list_fields($table_name));
 	}
 
 	// --------------------------------------------------------------------
@@ -880,23 +918,69 @@
 	 */
 	public function field_data($table = '')
 	{
-		if ($table == '')
+		if ($table === '')
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_field_param_missing');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
 		}
 
 		$query = $this->query($this->_field_data($this->protect_identifiers($table, TRUE, NULL, FALSE)));
-
 		return $query->field_data();
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
+	 * Escape the SQL Identifiers
+	 *
+	 * This function escapes column and table names
+	 *
+	 * @param	mixed
+	 * @return	mixed
+	 */
+	public function escape_identifiers($item)
+	{
+		if ($this->_escape_char === '')
+		{
+			return $item;
+		}
+		elseif (is_array($item))
+		{
+			foreach ($item as $key => $value)
+			{
+				$item[$key] = $this->escape_identifiers($value);
+			}
+
+			return $item;
+		}
+
+		static $preg_ec = array();
+
+		if (empty($preg_ec))
+		{
+			if (is_array($this->_escape_char))
+			{
+				$preg_ec = array(preg_quote($this->_escape_char[0]), preg_quote($this->_escape_char[1]));
+			}
+			else
+			{
+				$preg_ec[0] = $preg_ec[1] = preg_quote($this->_escape_char);
+			}
+		}
+
+		foreach ($this->_reserved_identifiers as $id)
+		{
+			if (strpos($item, '.'.$id) !== FALSE)
+			{
+				return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?\./i', $preg_ec[0].'$1'.$preg_ec[1].'.', $item);
+			}
+		}
+
+		return preg_replace('/'.$preg_ec[0].'?([^'.$preg_ec[1].'\.]+)'.$preg_ec[1].'?(\.)?/i', $preg_ec[0].'$1'.$preg_ec[1].'$2', $item);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Generate an insert string
 	 *
 	 * @param	string	the table upon which the query will be performed
@@ -905,12 +989,11 @@
 	 */
 	public function insert_string($table, $data)
 	{
-		$fields = array();
-		$values = array();
+		$fields = $values = array();
 
 		foreach ($data as $key => $val)
 		{
-			$fields[] = $this->_escape_identifiers($key);
+			$fields[] = $this->escape_identifiers($key);
 			$values[] = $this->escape($val);
 		}
 
@@ -929,7 +1012,7 @@
 	 */
 	public function update_string($table, $data, $where)
 	{
-		if ($where == '')
+		if ($where === '')
 		{
 			return FALSE;
 		}
@@ -949,7 +1032,7 @@
 			$dest = array();
 			foreach ($where as $key => $val)
 			{
-				$prefix = (count($dest) == 0) ? '' : ' AND ';
+				$prefix = (count($dest) === 0) ? '' : ' AND ';
 				$key = $this->protect_identifiers($key);
 
 				if ($val !== '')
@@ -979,13 +1062,7 @@
 	 */
 	protected function _has_operator($str)
 	{
-		$str = trim($str);
-		if ( ! preg_match("/(\s|<|>|!|=|is null|is not null)/i", $str))
-		{
-			return FALSE;
-		}
-
-		return TRUE;
+		return (bool) preg_match('/(\s|<|>|!|=|IS NULL|IS NOT NULL)/i', trim($str));
 	}
 
 	// --------------------------------------------------------------------
@@ -999,7 +1076,7 @@
 	 */
 	public function call_function($function)
 	{
-		$driver = ($this->dbdriver == 'postgre') ? 'pg_' : $this->dbdriver.'_';
+		$driver = ($this->dbdriver === 'postgre') ? 'pg_' : $this->dbdriver.'_';
 
 		if (FALSE === strpos($driver, $function))
 		{
@@ -1008,25 +1085,12 @@
 
 		if ( ! function_exists($function))
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_unsupported_function');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE;
 		}
-		else
-		{
-			$args = (func_num_args() > 1) ? array_splice(func_get_args(), 1) : null;
 
-			if (is_null($args))
-			{
-				return call_user_func($function);
-			}
-			else
-			{
-				return call_user_func_array($function, $args);
-			}
-		}
+		return (func_num_args() > 1)
+			? call_user_func_array($function, array_splice(func_get_args(), 1))
+			: call_user_func($function);
 	}
 
 	// --------------------------------------------------------------------
@@ -1051,8 +1115,7 @@
 	 */
 	public function cache_on()
 	{
-		$this->cache_on = TRUE;
-		return TRUE;
+		return $this->cache_on = TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1064,8 +1127,7 @@
 	 */
 	public function cache_off()
 	{
-		$this->cache_on = FALSE;
-		return FALSE;
+		return $this->cache_on = FALSE;
 	}
 
 
@@ -1078,11 +1140,9 @@
 	 */
 	public function cache_delete($segment_one = '', $segment_two = '')
 	{
-		if ( ! $this->_cache_init())
-		{
-			return FALSE;
-		}
-		return $this->CACHE->delete($segment_one, $segment_two);
+		return ($this->_cache_init())
+			? $this->CACHE->delete($segment_one, $segment_two)
+			: FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1094,12 +1154,9 @@
 	 */
 	public function cache_delete_all()
 	{
-		if ( ! $this->_cache_init())
-		{
-			return FALSE;
-		}
-
-		return $this->CACHE->delete_all();
+		return ($this->_cache_init())
+			? $this->CACHE->delete_all()
+			: FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1111,18 +1168,17 @@
 	 */
 	protected function _cache_init()
 	{
-		if (is_object($this->CACHE) AND class_exists('CI_DB_Cache'))
+		if (class_exists('CI_DB_Cache'))
 		{
-			return TRUE;
-		}
-
-		if ( ! class_exists('CI_DB_Cache'))
-		{
-			if ( ! @include(BASEPATH.'database/DB_cache.php'))
+			if (is_object($this->CACHE))
 			{
-				return $this->cache_off();
+				return TRUE;
 			}
 		}
+		elseif ( ! @include_once(BASEPATH.'database/DB_cache.php'))
+		{
+			return $this->cache_off();
+		}
 
 		$this->CACHE = new CI_DB_Cache($this); // pass db object to support multiple db connections and returned db objects
 		return TRUE;
@@ -1137,10 +1193,24 @@
 	 */
 	public function close()
 	{
-		if (is_resource($this->conn_id) OR is_object($this->conn_id))
+		if ($this->conn_id)
 		{
-			$this->_close($this->conn_id);
+			$this->_close();
+			$this->conn_id = FALSE;
 		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * This method would be overriden by most of the drivers.
+	 *
+	 * @return	void
+	 */
+	protected function _close()
+	{
 		$this->conn_id = FALSE;
 	}
 
@@ -1161,7 +1231,7 @@
 
 		$heading = $LANG->line('db_error_heading');
 
-		if ($native == TRUE)
+		if ($native === TRUE)
 		{
 			$message = (array) $error;
 		}
@@ -1173,9 +1243,7 @@
 		// Find the most likely culprit of the error by going through
 		// the backtrace until the source file is no longer in the
 		// database folder.
-
 		$trace = debug_backtrace();
-
 		foreach ($trace as $call)
 		{
 			if (isset($call['file']) && strpos($call['file'], BASEPATH.'database') === FALSE)
@@ -1183,7 +1251,6 @@
 				// Found it - use a relative path for safety
 				$message[] = 'Filename: '.str_replace(array(BASEPATH, APPPATH), '', $call['file']);
 				$message[] = 'Line Number: '.$call['line'];
-
 				break;
 			}
 		}
@@ -1198,10 +1265,10 @@
 	/**
 	 * Protect Identifiers
 	 *
-	 * This function is used extensively by the Active Record class, and by
+	 * This function is used extensively by the Query Builder class, and by
 	 * a couple functions in this class.
 	 * It takes a column or table name (optionally with an alias) and inserts
-	 * the table prefix onto it.  Some logic is necessary in order to deal with
+	 * the table prefix onto it. Some logic is necessary in order to deal with
 	 * column names that include the path. Consider a query like this:
 	 *
 	 * SELECT * FROM hostname.database.table.column AS c FROM hostname.database.table
@@ -1244,12 +1311,15 @@
 
 		// If the item has an alias declaration we remove it and set it aside.
 		// Basically we remove everything to the right of the first space
-		$alias = '';
 		if (strpos($item, ' ') !== FALSE)
 		{
-			$alias = strstr($item, " ");
+			$alias = strstr($item, ' ');
 			$item = substr($item, 0, - strlen($alias));
 		}
+		else
+		{
+			$alias = '';
+		}
 
 		// This is basically a bug fix for queries that use MAX, MIN, etc.
 		// If a parenthesis is found we know that we do not need to
@@ -1270,7 +1340,7 @@
 			// Does the first segment of the exploded item match
 			// one of the aliases previously identified? If so,
 			// we have nothing more to do other than escape the item
-			if (in_array($parts[0], $this->ar_aliased_tables))
+			if (in_array($parts[0], $this->qb_aliased_tables))
 			{
 				if ($protect_identifiers === TRUE)
 				{
@@ -1278,17 +1348,18 @@
 					{
 						if ( ! in_array($val, $this->_reserved_identifiers))
 						{
-							$parts[$key] = $this->_escape_identifiers($val);
+							$parts[$key] = $this->escape_identifiers($val);
 						}
 					}
 
 					$item = implode('.', $parts);
 				}
+
 				return $item.$alias;
 			}
 
 			// Is there a table prefix defined in the config file? If not, no need to do anything
-			if ($this->dbprefix != '')
+			if ($this->dbprefix !== '')
 			{
 				// We now add the table prefix based on some logic.
 				// Do we have 4 segments (hostname.database.table.column)?
@@ -1312,19 +1383,18 @@
 
 				// This flag is set when the supplied $item does not contain a field name.
 				// This can happen when this function is being called from a JOIN.
-				if ($field_exists == FALSE)
+				if ($field_exists === FALSE)
 				{
 					$i++;
 				}
 
 				// Verify table prefix and replace if necessary
-				if ($this->swap_pre != '' && strncmp($parts[$i], $this->swap_pre, strlen($this->swap_pre)) === 0)
+				if ($this->swap_pre !== '' && strpos($parts[$i], $this->swap_pre) === 0)
 				{
-					$parts[$i] = preg_replace("/^".$this->swap_pre."(\S+?)/", $this->dbprefix."\\1", $parts[$i]);
+					$parts[$i] = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $parts[$i]);
 				}
-
 				// We only add the table prefix if it does not already exist
-				if (substr($parts[$i], 0, strlen($this->dbprefix)) != $this->dbprefix)
+				elseif (strpos($parts[$i], $this->dbprefix) !== 0)
 				{
 					$parts[$i] = $this->dbprefix.$parts[$i];
 				}
@@ -1335,31 +1405,30 @@
 
 			if ($protect_identifiers === TRUE)
 			{
-				$item = $this->_escape_identifiers($item);
+				$item = $this->escape_identifiers($item);
 			}
 
 			return $item.$alias;
 		}
 
 		// Is there a table prefix? If not, no need to insert it
-		if ($this->dbprefix != '')
+		if ($this->dbprefix !== '')
 		{
 			// Verify table prefix and replace if necessary
-			if ($this->swap_pre != '' && strncmp($item, $this->swap_pre, strlen($this->swap_pre)) === 0)
+			if ($this->swap_pre !== '' && strpos($item, $this->swap_pre) === 0)
 			{
-				$item = preg_replace("/^".$this->swap_pre."(\S+?)/", $this->dbprefix."\\1", $item);
+				$item = preg_replace('/^'.$this->swap_pre.'(\S+?)/', $this->dbprefix.'\\1', $item);
 			}
-
 			// Do we prefix an item with no segments?
-			if ($prefix_single == TRUE AND substr($item, 0, strlen($this->dbprefix)) != $this->dbprefix)
+			elseif ($prefix_single === TRUE && strpos($item, $this->dbprefix) !== 0)
 			{
 				$item = $this->dbprefix.$item;
 			}
 		}
 
-		if ($protect_identifiers === TRUE AND ! in_array($item, $this->_reserved_identifiers))
+		if ($protect_identifiers === TRUE && ! in_array($item, $this->_reserved_identifiers))
 		{
-			$item = $this->_escape_identifiers($item);
+			$item = $this->escape_identifiers($item);
 		}
 
 		return $item.$alias;
@@ -1368,13 +1437,14 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Dummy method that allows Active Record class to be disabled
-	 *
-	 * This function is used extensively by every db driver.
+	 * Dummy method that allows Query Builder class to be disabled
+	 * and keep count_all() working.
 	 *
 	 * @return	void
 	 */
-	abstract protected function _reset_select();
+	protected function _reset_select()
+	{
+	}
 
 }
 
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index 34c502a..ff5eb3f 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -25,10 +25,8 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
- * Database Utility Class
+ * Database Forge Class
  *
  * @category	Database
  * @author		EllisLab Dev Team
@@ -41,6 +39,12 @@
 	public $primary_keys	= array();
 	public $db_char_set	=	'';
 
+	// Platform specific SQL strings
+	protected $_create_database	= 'CREATE DATABASE %s';
+	protected $_drop_database	= 'DROP DATABASE %s';
+	protected $_drop_table		= 'DROP TABLE IF EXISTS %s';
+	protected $_rename_table	= 'ALTER TABLE %s RENAME TO %s';
+
 	public function __construct()
 	{
 		// Assign the main database object to $this->db
@@ -59,8 +63,16 @@
 	 */
 	public function create_database($db_name)
 	{
-		$sql = $this->_create_database($db_name);
-		return is_bool($sql) ? $sql : $this->db->query($sql);
+		if ($this->_create_database === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
+		}
+		elseif ( ! $this->db->query(sprintf($this->_create_database, $db_name, $this->db->char_set, $this->db->dbcollat)))
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
+		}
+
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -73,8 +85,21 @@
 	 */
 	public function drop_database($db_name)
 	{
-		$sql = $this->_drop_database($db_name);
-		return is_bool($sql) ? $sql : $this->db->query($sql);
+		if ($db_name === '')
+		{
+			show_error('A table name is required for that operation.');
+			return FALSE;
+		}
+		elseif ($this->_drop_database === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
+		}
+		elseif ( ! $this->db->query(sprintf($this->_drop_database, $db_name)))
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
+		}
+
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -98,7 +123,7 @@
 			return;
 		}
 
-		if ($key == '')
+		if ($key === '')
 		{
 			show_error('Key information is required for that operation.');
 		}
@@ -125,7 +150,7 @@
 	 */
 	public function add_field($field = '')
 	{
-		if ($field == '')
+		if ($field === '')
 		{
 			show_error('Field information is required.');
 		}
@@ -172,7 +197,7 @@
 	 */
 	public function create_table($table = '', $if_not_exists = FALSE)
 	{
-		if ($table == '')
+		if ($table === '')
 		{
 			show_error('A table name is required for that operation.');
 		}
@@ -197,8 +222,16 @@
 	 */
 	public function drop_table($table_name)
 	{
-		$sql = $this->_drop_table($this->db->dbprefix.$table_name);
-		return is_bool($sql) ? $sql : $this->db->query($sql);
+		if ($table_name === '')
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_table_name_required') : FALSE;
+		}
+		elseif ($this->_drop_table === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
+		}
+
+		return $this->db->query(sprintf($this->_drop_table, $this->db->escape_identifiers($this->db->dbprefix.$table_name)));
 	}
 
 	// --------------------------------------------------------------------
@@ -212,12 +245,20 @@
 	 */
 	public function rename_table($table_name, $new_table_name)
 	{
-		if ($table_name == '' OR $new_table_name == '')
+		if ($table_name === '' OR $new_table_name === '')
 		{
 			show_error('A table name is required for that operation.');
+			return FALSE;
+		}
+		elseif ($this->_rename_table === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 		}
 
-		return $this->db->query($this->_rename_table($this->db->dbprefix.$table_name, $this->db->dbprefix.$new_table_name));
+		return $this->db->query(sprintf($this->_rename_table,
+						$this->db->escape_identifiers($this->db->dbprefix.$table_name),
+						$this->db->escape_identifiers($this->db->dbprefix.$new_table_name))
+					);
 	}
 
 	// --------------------------------------------------------------------
@@ -232,7 +273,7 @@
 	 */
 	public function add_column($table = '', $field = array(), $after_field = '')
 	{
-		if ($table == '')
+		if ($table === '')
 		{
 			show_error('A table name is required for that operation.');
 		}
@@ -243,7 +284,7 @@
 		{
 			$this->add_field(array($k => $field[$k]));
 
-			if (count($this->fields) == 0)
+			if (count($this->fields) === 0)
 			{
 				show_error('Field information is required.');
 			}
@@ -271,12 +312,12 @@
 	 */
 	public function drop_column($table = '', $column_name = '')
 	{
-		if ($table == '')
+		if ($table === '')
 		{
 			show_error('A table name is required for that operation.');
 		}
 
-		if ($column_name == '')
+		if ($column_name === '')
 		{
 			show_error('A column name is required for that operation.');
 		}
@@ -296,7 +337,7 @@
 	 */
 	public function modify_column($table = '', $field = array())
 	{
-		if ($table == '')
+		if ($table === '')
 		{
 			show_error('A table name is required for that operation.');
 		}
diff --git a/system/database/DB_active_rec.php b/system/database/DB_query_builder.php
similarity index 69%
rename from system/database/DB_active_rec.php
rename to system/database/DB_query_builder.php
index b324226..3ed5562 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_query_builder.php
@@ -26,9 +26,9 @@
  */
 
 /**
- * Active Record Class
+ * Query Builder Class
  *
- * This is the platform-independent base Active Record implementation class.
+ * This is the platform-independent base Query Builder implementation class.
  *
  * @package		CodeIgniter
  * @subpackage	Drivers
@@ -36,46 +36,47 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/database/
  */
-abstract class CI_DB_active_record extends CI_DB_driver {
+
+abstract class CI_DB_query_builder extends CI_DB_driver {
 
 	protected $return_delete_sql		= FALSE;
 	protected $reset_delete_data		= FALSE;
 
-	protected $ar_select			= array();
-	protected $ar_distinct			= FALSE;
-	protected $ar_from			= array();
-	protected $ar_join			= array();
-	protected $ar_where			= array();
-	protected $ar_like			= array();
-	protected $ar_groupby			= array();
-	protected $ar_having			= array();
-	protected $ar_keys			= array();
-	protected $ar_limit			= FALSE;
-	protected $ar_offset			= FALSE;
-	protected $ar_order			= FALSE;
-	protected $ar_orderby			= array();
-	protected $ar_set			= array();
-	protected $ar_wherein			= array();
-	protected $ar_aliased_tables		= array();
-	protected $ar_store_array		= array();
-	protected $ar_where_group_started	= FALSE;
-	protected $ar_where_group_count		= 0;
+	protected $qb_select			= array();
+	protected $qb_distinct			= FALSE;
+	protected $qb_from			= array();
+	protected $qb_join			= array();
+	protected $qb_where			= array();
+	protected $qb_like			= array();
+	protected $qb_groupby			= array();
+	protected $qb_having			= array();
+	protected $qb_keys			= array();
+	protected $qb_limit			= FALSE;
+	protected $qb_offset			= FALSE;
+	protected $qb_order			= FALSE;
+	protected $qb_orderby			= array();
+	protected $qb_set			= array();
+	protected $qb_wherein			= array();
+	protected $qb_aliased_tables		= array();
+	protected $qb_store_array		= array();
+	protected $qb_where_group_started	= FALSE;
+	protected $qb_where_group_count		= 0;
 
-	// Active Record Caching variables
-	protected $ar_caching				= FALSE;
-	protected $ar_cache_exists			= array();
-	protected $ar_cache_select			= array();
-	protected $ar_cache_from			= array();
-	protected $ar_cache_join			= array();
-	protected $ar_cache_where			= array();
-	protected $ar_cache_like			= array();
-	protected $ar_cache_groupby			= array();
-	protected $ar_cache_having			= array();
-	protected $ar_cache_orderby			= array();
-	protected $ar_cache_set				= array();
+	// Query Builder Caching variables
+	protected $qb_caching				= FALSE;
+	protected $qb_cache_exists			= array();
+	protected $qb_cache_select			= array();
+	protected $qb_cache_from			= array();
+	protected $qb_cache_join			= array();
+	protected $qb_cache_where			= array();
+	protected $qb_cache_like			= array();
+	protected $qb_cache_groupby			= array();
+	protected $qb_cache_having			= array();
+	protected $qb_cache_orderby			= array();
+	protected $qb_cache_set				= array();
 
-	protected $ar_no_escape 			= array();
-	protected $ar_cache_no_escape			= array();
+	protected $qb_no_escape 			= array();
+	protected $qb_cache_no_escape			= array();
 
 	/**
 	 * Select
@@ -96,16 +97,16 @@
 		{
 			$val = trim($val);
 
-			if ($val != '')
+			if ($val !== '')
 			{
-				$this->ar_select[] = $val;
-				$this->ar_no_escape[] = $escape;
+				$this->qb_select[] = $val;
+				$this->qb_no_escape[] = $escape;
 
-				if ($this->ar_caching === TRUE)
+				if ($this->qb_caching === TRUE)
 				{
-					$this->ar_cache_select[] = $val;
-					$this->ar_cache_exists[] = 'select';
-					$this->ar_cache_no_escape[] = $escape;
+					$this->qb_cache_select[] = $val;
+					$this->qb_cache_exists[] = 'select';
+					$this->qb_cache_no_escape[] = $escape;
 				}
 			}
 		}
@@ -193,7 +194,7 @@
 	 */
 	protected function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX')
 	{
-		if ( ! is_string($select) OR $select == '')
+		if ( ! is_string($select) OR $select === '')
 		{
 			$this->display_error('db_invalid_query');
 		}
@@ -205,19 +206,20 @@
 			show_error('Invalid function type: '.$type);
 		}
 
-		if ($alias == '')
+		if ($alias === '')
 		{
 			$alias = $this->_create_alias_from_table(trim($select));
 		}
 
-		$sql = $this->protect_identifiers($type.'('.trim($select).')').' AS '.$this->protect_identifiers(trim($alias));
-		$this->ar_select[] = $sql;
-		$this->ar_no_escape[] = NULL;
+		$sql = $this->protect_identifiers($type.'('.trim($select).')').' AS '.$this->escape_identifiers(trim($alias));
 
-		if ($this->ar_caching === TRUE)
+		$this->qb_select[] = $sql;
+		$this->qb_no_escape[] = NULL;
+
+		if ($this->qb_caching === TRUE)
 		{
-			$this->ar_cache_select[] = $sql;
-			$this->ar_cache_exists[] = 'select';
+			$this->qb_cache_select[] = $sql;
+			$this->qb_cache_exists[] = 'select';
 		}
 
 		return $this;
@@ -254,7 +256,7 @@
 	 */
 	public function distinct($val = TRUE)
 	{
-		$this->ar_distinct = (is_bool($val)) ? $val : TRUE;
+		$this->qb_distinct = is_bool($val) ? $val : TRUE;
 		return $this;
 	}
 
@@ -270,7 +272,7 @@
 	 */
 	public function from($from)
 	{
-		foreach ((array)$from as $val)
+		foreach ((array) $from as $val)
 		{
 			if (strpos($val, ',') !== FALSE)
 			{
@@ -278,12 +280,13 @@
 				{
 					$v = trim($v);
 					$this->_track_aliases($v);
-					$v = $this->ar_from[] = $this->protect_identifiers($v, TRUE, NULL, FALSE);
 
-					if ($this->ar_caching === TRUE)
+					$this->qb_from[] = $v = $this->protect_identifiers($v, TRUE, NULL, FALSE);
+
+					if ($this->qb_caching === TRUE)
 					{
-						$this->ar_cache_from[] = $v;
-						$this->ar_cache_exists[] = 'from';
+						$this->qb_cache_from[] = $v;
+						$this->qb_cache_exists[] = 'from';
 					}
 				}
 			}
@@ -292,14 +295,15 @@
 				$val = trim($val);
 
 				// Extract any aliases that might exist. We use this information
-				// in the _protect_identifiers to know whether to add a table prefix
+				// in the protect_identifiers to know whether to add a table prefix
 				$this->_track_aliases($val);
-				$this->ar_from[] = $val = $this->protect_identifiers($val, TRUE, NULL, FALSE);
 
-				if ($this->ar_caching === TRUE)
+				$this->qb_from[] = $val = $this->protect_identifiers($val, TRUE, NULL, FALSE);
+
+				if ($this->qb_caching === TRUE)
 				{
-					$this->ar_cache_from[] = $val;
-					$this->ar_cache_exists[] = 'from';
+					$this->qb_cache_from[] = $val;
+					$this->qb_cache_exists[] = 'from';
 				}
 			}
 		}
@@ -321,7 +325,7 @@
 	 */
 	public function join($table, $cond, $type = '')
 	{
-		if ($type != '')
+		if ($type !== '')
 		{
 			$type = strtoupper(trim($type));
 
@@ -336,7 +340,7 @@
 		}
 
 		// Extract any aliases that might exist. We use this information
-		// in the _protect_identifiers to know whether to add a table prefix
+		// in the protect_identifiers to know whether to add a table prefix
 		$this->_track_aliases($table);
 
 		// Strip apart the condition and protect the identifiers
@@ -346,12 +350,12 @@
 		}
 
 		// Assemble the JOIN statement
-		$this->ar_join[] = $join = $type.'JOIN '.$this->protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;
+		$this->qb_join[] = $join = $type.'JOIN '.$this->protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;
 
-		if ($this->ar_caching === TRUE)
+		if ($this->qb_caching === TRUE)
 		{
-			$this->ar_cache_join[] = $join;
-			$this->ar_cache_exists[] = 'join';
+			$this->qb_cache_join[] = $join;
+			$this->qb_cache_exists[] = 'join';
 		}
 
 		return $this;
@@ -420,7 +424,7 @@
 
 		foreach ($key as $k => $v)
 		{
-			$prefix = (count($this->ar_where) === 0 && count($this->ar_cache_where) === 0) ? '' : $type;
+			$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
 
 			if (is_null($v) && ! $this->_has_operator($k))
 			{
@@ -446,11 +450,11 @@
 				$k = $this->protect_identifiers($k, FALSE, $escape);
 			}
 
-			$this->ar_where[] = $prefix.$k.$v;
-			if ($this->ar_caching === TRUE)
+			$this->qb_where[] = $prefix.$k.$v;
+			if ($this->qb_caching === TRUE)
 			{
-				$this->ar_cache_where[] = $prefix.$k.$v;
-				$this->ar_cache_exists[] = 'where';
+				$this->qb_cache_where[] = $prefix.$k.$v;
+				$this->qb_cache_exists[] = 'where';
 			}
 
 		}
@@ -557,20 +561,20 @@
 
 		foreach ($values as $value)
 		{
-			$this->ar_wherein[] = $this->escape($value);
+			$this->qb_wherein[] = $this->escape($value);
 		}
 
-		$prefix = (count($this->ar_where) === 0) ? '' : $type;
-		$this->ar_where[] = $where_in = $prefix.$this->protect_identifiers($key).$not.' IN ('.implode(', ', $this->ar_wherein).') ';
+		$prefix = (count($this->qb_where) === 0) ? '' : $type;
+		$this->qb_where[] = $where_in = $prefix.$this->protect_identifiers($key).$not.' IN ('.implode(', ', $this->qb_wherein).') ';
 
-		if ($this->ar_caching === TRUE)
+		if ($this->qb_caching === TRUE)
 		{
-			$this->ar_cache_where[] = $where_in;
-			$this->ar_cache_exists[] = 'where';
+			$this->qb_cache_where[] = $where_in;
+			$this->qb_cache_exists[] = 'where';
 		}
 
 		// reset the array for multiple calls
-		$this->ar_wherein = array();
+		$this->qb_wherein = array();
 		return $this;
 	}
 
@@ -666,37 +670,37 @@
 		foreach ($field as $k => $v)
 		{
 			$k = $this->protect_identifiers($k);
-			$prefix = (count($this->ar_like) === 0) ? '' : $type;
+			$prefix = (count($this->qb_like) === 0) ? '' : $type;
 			$v = $this->escape_like_str($v);
 
 			if ($side === 'none')
 			{
-				$like_statement = $prefix." $k $not LIKE '{$v}'";
+				$like_statement = "{$prefix} $k $not LIKE '{$v}'";
 			}
 			elseif ($side === 'before')
 			{
-				$like_statement = $prefix." $k $not LIKE '%{$v}'";
+				$like_statement = "{$prefix} $k $not LIKE '%{$v}'";
 			}
 			elseif ($side === 'after')
 			{
-				$like_statement = $prefix." $k $not LIKE '{$v}%'";
+				$like_statement = "{$prefix} $k $not LIKE '{$v}%'";
 			}
 			else
 			{
-				$like_statement = $prefix." $k $not LIKE '%{$v}%'";
+				$like_statement = "{$prefix} $k $not LIKE '%{$v}%'";
 			}
 
 			// some platforms require an escape sequence definition for LIKE wildcards
-			if ($this->_like_escape_str != '')
+			if ($this->_like_escape_str !== '')
 			{
 				$like_statement = $like_statement.sprintf($this->_like_escape_str, $this->_like_escape_chr);
 			}
 
-			$this->ar_like[] = $like_statement;
-			if ($this->ar_caching === TRUE)
+			$this->qb_like[] = $like_statement;
+			if ($this->qb_caching === TRUE)
 			{
-				$this->ar_cache_like[] = $like_statement;
-				$this->ar_cache_exists[] = 'like';
+				$this->qb_cache_like[] = $like_statement;
+				$this->qb_cache_exists[] = 'like';
 			}
 
 		}
@@ -716,13 +720,14 @@
 	public function group_start($not = '', $type = 'AND ')
 	{
 		$type = $this->_group_get_type($type);
-		$this->ar_where_group_started = TRUE;
-		$prefix = (count($this->ar_where) === 0 && count($this->ar_cache_where) === 0) ? '' : $type;
-		$this->ar_where[] = $value = $prefix.$not.str_repeat(' ', ++$this->ar_where_group_count).' (';
 
-		if ($this->ar_caching)
+		$this->qb_where_group_started = TRUE;
+		$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
+		$this->qb_where[] = $value = $prefix.$not.str_repeat(' ', ++$this->qb_where_group_count).' (';
+
+		if ($this->qb_caching)
 		{
-			$this->ar_cache_where[] = $value;
+			$this->qb_cache_where[] = $value;
 		}
 
 		return $this;
@@ -773,12 +778,12 @@
 	 */
 	public function group_end()
 	{
-		$this->ar_where_group_started = FALSE;
-		$this->ar_where[] = $value = str_repeat(' ', $this->ar_where_group_count--) . ')';
+		$this->qb_where_group_started = FALSE;
+		$this->qb_where[] = $value = str_repeat(' ', $this->qb_where_group_count--) . ')';
 
-		if ($this->ar_caching)
+		if ($this->qb_caching)
 		{
-			$this->ar_cache_where[] = $value;
+			$this->qb_cache_where[] = $value;
 		}
 
 		return $this;
@@ -796,10 +801,10 @@
 	 */
 	protected function _group_get_type($type)
 	{
-		if ($this->ar_where_group_started)
+		if ($this->qb_where_group_started)
 		{
 			$type = '';
-			$this->ar_where_group_started = FALSE;
+			$this->qb_where_group_started = FALSE;
 		}
 
 		return $type;
@@ -824,14 +829,14 @@
 		{
 			$val = trim($val);
 
-			if ($val != '')
+			if ($val !== '')
 			{
-				$this->ar_groupby[] = $val = $this->protect_identifiers($val);
+				$this->qb_groupby[] = $val = $this->protect_identifiers($val);
 
-				if ($this->ar_caching === TRUE)
+				if ($this->qb_caching === TRUE)
 				{
-					$this->ar_cache_groupby[] = $val;
-					$this->ar_cache_exists[] = 'groupby';
+					$this->qb_cache_groupby[] = $val;
+					$this->qb_cache_exists[] = 'groupby';
 				}
 			}
 		}
@@ -891,7 +896,7 @@
 
 		foreach ($key as $k => $v)
 		{
-			$prefix = (count($this->ar_having) === 0) ? '' : $type;
+			$prefix = (count($this->qb_having) === 0) ? '' : $type;
 
 			if ($escape === TRUE)
 			{
@@ -903,16 +908,16 @@
 				$k .= ' = ';
 			}
 
-			if ($v != '')
+			if ($v !== '')
 			{
 				$v = ' '.$this->escape($v);
 			}
 
-			$this->ar_having[] = $prefix.$k.$v;
-			if ($this->ar_caching === TRUE)
+			$this->qb_having[] = $prefix.$k.$v;
+			if ($this->qb_caching === TRUE)
 			{
-				$this->ar_cache_having[] = $prefix.$k.$v;
-				$this->ar_cache_exists[] = 'having';
+				$this->qb_cache_having[] = $prefix.$k.$v;
+				$this->qb_cache_exists[] = 'having';
 			}
 		}
 
@@ -936,7 +941,7 @@
 			$orderby = ''; // Random results want or don't need a field name
 			$direction = $this->_random_keyword;
 		}
-		elseif (trim($direction) != '')
+		elseif (trim($direction) !== '')
 		{
 			$direction = (in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE)) ? ' '.$direction : ' ASC';
 		}
@@ -948,7 +953,7 @@
 			foreach (explode(',', $orderby) as $part)
 			{
 				$part = trim($part);
-				if ( ! in_array($part, $this->ar_aliased_tables))
+				if ( ! in_array($part, $this->qb_aliased_tables))
 				{
 					$part = $this->protect_identifiers(trim($part));
 				}
@@ -958,7 +963,7 @@
 
 			$orderby = implode(', ', $temp);
 		}
-		elseif ($direction != $this->_random_keyword)
+		elseif ($direction !== $this->_random_keyword)
 		{
 			if ($escape === TRUE)
 			{
@@ -966,12 +971,12 @@
 			}
 		}
 
-		$this->ar_orderby[] = $orderby_statement = $orderby.$direction;
+		$this->qb_orderby[] = $orderby_statement = $orderby.$direction;
 
-		if ($this->ar_caching === TRUE)
+		if ($this->qb_caching === TRUE)
 		{
-			$this->ar_cache_orderby[] = $orderby_statement;
-			$this->ar_cache_exists[] = 'orderby';
+			$this->qb_cache_orderby[] = $orderby_statement;
+			$this->qb_cache_exists[] = 'orderby';
 		}
 
 		return $this;
@@ -988,11 +993,11 @@
 	 */
 	public function limit($value, $offset = NULL)
 	{
-		$this->ar_limit = (int) $value;
+		$this->qb_limit = (int) $value;
 
 		if ( ! is_null($offset))
 		{
-			$this->ar_offset = (int) $offset;
+			$this->qb_offset = (int) $offset;
 		}
 
 		return $this;
@@ -1008,7 +1013,7 @@
 	 */
 	public function offset($offset)
 	{
-		$this->ar_offset = (int) $offset;
+		$this->qb_offset = (int) $offset;
 		return $this;
 	}
 
@@ -1035,11 +1040,11 @@
 		{
 			if ($escape === FALSE)
 			{
-				$this->ar_set[$this->protect_identifiers($k)] = $v;
+				$this->qb_set[$this->protect_identifiers($k)] = $v;
 			}
 			else
 			{
-				$this->ar_set[$this->protect_identifiers($k, FALSE, TRUE)] = $this->escape($v);
+				$this->qb_set[$this->protect_identifiers($k, FALSE, TRUE)] = $this->escape($v);
 			}
 		}
 
@@ -1054,12 +1059,12 @@
 	 * Compiles a SELECT query string and returns the sql.
 	 *
 	 * @param	string	the table name to select from (optional)
-	 * @param	bool	TRUE: resets AR values; FALSE: leave AR vaules alone
+	 * @param	bool	TRUE: resets QB values; FALSE: leave QB vaules alone
 	 * @return	string
 	 */
 	public function get_compiled_select($table = '', $reset = TRUE)
 	{
-		if ($table != '')
+		if ($table !== '')
 		{
 			$this->_track_aliases($table);
 			$this->from($table);
@@ -1090,7 +1095,7 @@
 	 */
 	public function get($table = '', $limit = null, $offset = null)
 	{
-		if ($table != '')
+		if ($table !== '')
 		{
 			$this->_track_aliases($table);
 			$this->from($table);
@@ -1106,18 +1111,20 @@
 		return $result;
 	}
 
+	// --------------------------------------------------------------------
+
 	/**
 	 * "Count All Results" query
 	 *
 	 * Generates a platform-specific query string that counts all records
-	 * returned by an Active Record query.
+	 * returned by an Query Builder query.
 	 *
 	 * @param	string
 	 * @return	string
 	 */
 	public function count_all_results($table = '')
 	{
-		if ($table != '')
+		if ($table !== '')
 		{
 			$this->_track_aliases($table);
 			$this->from($table);
@@ -1134,6 +1141,7 @@
 		$row = $result->row();
 		return (int) $row->numrows;
 	}
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1148,7 +1156,7 @@
 	 */
 	public function get_where($table = '', $where = null, $limit = null, $offset = null)
 	{
-		if ($table != '')
+		if ($table !== '')
 		{
 			$this->from($table);
 		}
@@ -1186,7 +1194,7 @@
 			$this->set_insert_batch($set);
 		}
 
-		if (count($this->ar_set) === 0)
+		if (count($this->qb_set) === 0)
 		{
 			if ($this->db_debug)
 			{
@@ -1196,20 +1204,20 @@
 			return FALSE;
 		}
 
-		if ($table == '')
+		if ($table === '')
 		{
-			if ( ! isset($this->ar_from[0]))
+			if ( ! isset($this->qb_from[0]))
 			{
 				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
-			$table = $this->ar_from[0];
+			$table = $this->qb_from[0];
 		}
 
 		// Batch this baby
-		for ($i = 0, $total = count($this->ar_set); $i < $total; $i += 100)
+		for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100)
 		{
-			$this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100)));
+			$this->query($this->_insert_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), $this->qb_keys, array_slice($this->qb_set, $i, 100)));
 		}
 
 		$this->_reset_write();
@@ -1219,6 +1227,23 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Insert_batch statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data.
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _insert_batch($table, $keys, $values)
+	{
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * The "set_insert_batch" function.  Allows key/value pairs to be set for batch inserts
 	 *
 	 * @param	mixed
@@ -1235,15 +1260,16 @@
 			$key = array($key => $value);
 		}
 
-		$keys = array_keys(current($key));
+		$keys = array_keys($this->_object_to_array(current($key)));
 		sort($keys);
 
 		foreach ($key as $row)
 		{
+			$row = $this->_object_to_array($row);
 			if (count(array_diff($keys, array_keys($row))) > 0 OR count(array_diff(array_keys($row), $keys)) > 0)
 			{
 				// batch function above returns an error on an empty array
-				$this->ar_set[] = array();
+				$this->qb_set[] = array();
 				return;
 			}
 
@@ -1251,7 +1277,7 @@
 
 			if ($escape === FALSE)
 			{
-				$this->ar_set[] =  '('.implode(',', $row).')';
+				$this->qb_set[] =  '('.implode(',', $row).')';
 			}
 			else
 			{
@@ -1261,13 +1287,13 @@
 					$clean[] = $this->escape($value);
 				}
 
-				$this->ar_set[] =  '('.implode(',', $clean).')';
+				$this->qb_set[] =  '('.implode(',', $clean).')';
 			}
 		}
 
 		foreach ($keys as $k)
 		{
-			$this->ar_keys[] = $this->protect_identifiers($k);
+			$this->qb_keys[] = $this->protect_identifiers($k);
 		}
 
 		return $this;
@@ -1281,7 +1307,7 @@
 	 * Compiles an insert query and returns the sql
 	 *
 	 * @param	string	the table to insert into
-	 * @param	bool	TRUE: reset AR values; FALSE: leave AR values alone
+	 * @param	bool	TRUE: reset QB values; FALSE: leave QB values alone
 	 * @return	string
 	 */
 	public function get_compiled_insert($table = '', $reset = TRUE)
@@ -1292,9 +1318,11 @@
 		}
 
 		$sql = $this->_insert(
-			$this->protect_identifiers($this->ar_from[0], TRUE, NULL, FALSE),
-			array_keys($this->ar_set),
-			array_values($this->ar_set)
+			$this->protect_identifiers(
+				$this->qb_from[0], TRUE, NULL, FALSE
+			),
+			array_keys($this->qb_set),
+			array_values($this->qb_set)
 		);
 
 		if ($reset === TRUE)
@@ -1329,9 +1357,11 @@
 		}
 
 		$sql = $this->_insert(
-			$this->protect_identifiers($this->ar_from[0], TRUE, NULL, FALSE),
-			array_keys($this->ar_set),
-			array_values($this->ar_set)
+			$this->protect_identifiers(
+				$this->qb_from[0], TRUE, NULL, FALSE
+			),
+			array_keys($this->qb_set),
+			array_values($this->qb_set)
 		);
 
 		$this->_reset_write();
@@ -1341,6 +1371,23 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Insert statement
+	 *
+	 * Generates a platform-specific insert string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _insert($table, $keys, $values)
+	{
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Validate Insert
 	 *
 	 * This method is used by both insert() and get_compiled_insert() to
@@ -1352,21 +1399,18 @@
 	 */
 	protected function _validate_insert($table = '')
 	{
-		if (count($this->ar_set) === 0)
+		if (count($this->qb_set) === 0)
 		{
 			return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
 		}
 
-		if ($table == '')
+		if ($table !== '')
 		{
-			if ( ! isset($this->ar_from[0]))
-			{
-				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
-			}
+			$this->qb_from[0] = $table;
 		}
-		else
+		elseif ( ! isset($this->qb_from[0]))
 		{
-			$this->ar_from[0] = $table;
+			return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 		}
 
 		return TRUE;
@@ -1390,22 +1434,23 @@
 			$this->set($set);
 		}
 
-		if (count($this->ar_set) === 0)
+		if (count($this->qb_set) === 0)
 		{
 			return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
 		}
 
-		if ($table == '')
+		if ($table === '')
 		{
-			if ( ! isset($this->ar_from[0]))
+			if ( ! isset($this->qb_from[0]))
 			{
 				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
-			$table = $this->ar_from[0];
+			$table = $this->qb_from[0];
 		}
 
-		$sql = $this->_replace($this->protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));
+		$sql = $this->_replace($this->protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->qb_set), array_values($this->qb_set));
+
 		$this->_reset_write();
 		return $this->query($sql);
 	}
@@ -1413,12 +1458,47 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Replace statement
+	 *
+	 * Generates a platform-specific replace string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _replace($table, $keys, $values)
+	{
+		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * From Tables
+	 *
+	 * This public function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @param       array
+	 * @return      string
+	 */
+	protected function _from_tables($tables)
+	{
+		is_array($tables) OR $tables = array($tables);
+
+		return (count($tables) === 1) ? $tables[0] : '('.implode(', ', $tables).')';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Get UPDATE query string
 	 *
 	 * Compiles an update query and returns the sql
 	 *
 	 * @param	string	the table to update
-	 * @param	bool	TRUE: reset AR values; FALSE: leave AR values alone
+	 * @param	bool	TRUE: reset QB values; FALSE: leave QB values alone
 	 * @return	string
 	 */
 	public function get_compiled_update($table = '', $reset = TRUE)
@@ -1431,7 +1511,7 @@
 			return FALSE;
 		}
 
-		$sql = $this->_update($this->protect_identifiers($this->ar_from[0], TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit);
+		$sql = $this->_update($this->protect_identifiers($this->qb_from[0], TRUE, NULL, FALSE), $this->qb_set, $this->qb_where, $this->qb_orderby, $this->qb_limit);
 
 		if ($reset === TRUE)
 		{
@@ -1468,7 +1548,7 @@
 			return FALSE;
 		}
 
-		if ($where != NULL)
+		if ($where !== NULL)
 		{
 			$this->where($where);
 		}
@@ -1478,7 +1558,8 @@
 			$this->limit($limit);
 		}
 
-		$sql = $this->_update($this->protect_identifiers($this->ar_from[0], TRUE, NULL, FALSE), $this->ar_set, $this->ar_where, $this->ar_orderby, $this->ar_limit, $this->ar_like);
+		$sql = $this->_update($this->protect_identifiers($this->qb_from[0], TRUE, NULL, FALSE), $this->qb_set, $this->qb_where, $this->qb_orderby, $this->qb_limit, $this->qb_like);
+
 		$this->_reset_write();
 		return $this->query($sql);
 	}
@@ -1486,6 +1567,41 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Update statement
+	 *
+	 * Generates a platform-specific update string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
+	 * @param	array	the orderby clause
+	 * @param	array	the limit clause
+	 * @param	array	the like clause
+	 * @return	string
+	 */
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
+	{
+		foreach ($values as $key => $val)
+		{
+			$valstr[] = $key.' = '.$val;
+		}
+
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
+
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
+
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
+			.$where
+			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
+			.($limit ? ' LIMIT '.$limit : '');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Validate Update
 	 *
 	 * This method is used by both update() and get_compiled_update() to
@@ -1497,21 +1613,18 @@
 	 */
 	protected function _validate_update($table = '')
 	{
-		if (count($this->ar_set) == 0)
+		if (count($this->qb_set) === 0)
 		{
 			return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
 		}
 
-		if ($table == '')
+		if ($table !== '')
 		{
-			if ( ! isset($this->ar_from[0]))
-			{
-				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
-			}
+			$this->qb_from[0] = $table;
 		}
-		else
+		elseif ( ! isset($this->qb_from[0]))
 		{
-			$this->ar_from[0] = $table;
+			return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 		}
 
 		return TRUE;
@@ -1544,25 +1657,25 @@
 			$this->set_update_batch($set, $index);
 		}
 
-		if (count($this->ar_set) === 0)
+		if (count($this->qb_set) === 0)
 		{
 			return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
 		}
 
-		if ($table == '')
+		if ($table === '')
 		{
-			if ( ! isset($this->ar_from[0]))
+			if ( ! isset($this->qb_from[0]))
 			{
 				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
-			$table = $this->ar_from[0];
+			$table = $this->qb_from[0];
 		}
 
 		// Batch this baby
-		for ($i = 0, $total = count($this->ar_set); $i < $total; $i += 100)
+		for ($i = 0, $total = count($this->qb_set); $i < $total; $i += 100)
 		{
-			$this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->ar_set, $i, 100), $this->protect_identifiers($index), $this->ar_where));
+			$this->query($this->_update_batch($this->protect_identifiers($table, TRUE, NULL, FALSE), array_slice($this->qb_set, $i, 100), $this->protect_identifiers($index), $this->qb_where));
 		}
 
 		$this->_reset_write();
@@ -1594,24 +1707,20 @@
 			$clean = array();
 			foreach ($v as $k2 => $v2)
 			{
-				if ($k2 == $index)
+				if ($k2 === $index)
 				{
 					$index_set = TRUE;
 				}
-				else
-				{
-					$not[] = $k.'-'.$v;
-				}
 
 				$clean[$this->protect_identifiers($k2)] = ($escape === FALSE) ? $v2 : $this->escape($v2);
 			}
 
-			if ($index_set == FALSE)
+			if ($index_set === FALSE)
 			{
 				return $this->display_error('db_batch_missing_index');
 			}
 
-			$this->ar_set[] = $clean;
+			$this->qb_set[] = $clean;
 		}
 
 		return $this;
@@ -1629,14 +1738,14 @@
 	 */
 	public function empty_table($table = '')
 	{
-		if ($table == '')
+		if ($table === '')
 		{
-			if ( ! isset($this->ar_from[0]))
+			if ( ! isset($this->qb_from[0]))
 			{
 				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
-			$table = $this->ar_from[0];
+			$table = $this->qb_from[0];
 		}
 		else
 		{
@@ -1662,14 +1771,14 @@
 	 */
 	public function truncate($table = '')
 	{
-		if ($table == '')
+		if ($table === '')
 		{
-			if ( ! isset($this->ar_from[0]))
+			if ( ! isset($this->qb_from[0]))
 			{
 				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
-			$table = $this->ar_from[0];
+			$table = $this->qb_from[0];
 		}
 		else
 		{
@@ -1684,12 +1793,30 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _truncate($table)
+	{
+		return 'TRUNCATE '.$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Get DELETE query string
 	 *
 	 * Compiles a delete query string and returns the sql
 	 *
 	 * @param	string	the table to delete from
-	 * @param	bool	TRUE: reset AR values; FALSE: leave AR values alone
+	 * @param	bool	TRUE: reset QB values; FALSE: leave QB values alone
 	 * @return	string
 	 */
 	public function get_compiled_delete($table = '', $reset = TRUE)
@@ -1718,14 +1845,14 @@
 		// Combine any cached components with the current statements
 		$this->_merge_cache();
 
-		if ($table == '')
+		if ($table === '')
 		{
-			if ( ! isset($this->ar_from[0]))
+			if ( ! isset($this->qb_from[0]))
 			{
 				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
-			$table = $this->ar_from[0];
+			$table = $this->qb_from[0];
 		}
 		elseif (is_array($table))
 		{
@@ -1742,7 +1869,7 @@
 			$table = $this->protect_identifiers($table, TRUE, NULL, FALSE);
 		}
 
-		if ($where != '')
+		if ($where !== '')
 		{
 			$this->where($where);
 		}
@@ -1752,12 +1879,12 @@
 			$this->limit($limit);
 		}
 
-		if (count($this->ar_where) === 0 && count($this->ar_wherein) === 0 && count($this->ar_like) === 0)
+		if (count($this->qb_where) === 0 && count($this->qb_wherein) === 0 && count($this->qb_like) === 0)
 		{
 			return ($this->db_debug) ? $this->display_error('db_del_must_use_where') : FALSE;
 		}
 
-		$sql = $this->_delete($table, $this->ar_where, $this->ar_like, $this->ar_limit);
+		$sql = $this->_delete($table, $this->qb_where, $this->qb_like, $this->qb_limit);
 		if ($reset_data)
 		{
 			$this->_reset_write();
@@ -1769,6 +1896,31 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Delete statement
+	 *
+	 * Generates a platform-specific delete string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the where clause
+	 * @param	array	the like clause
+	 * @param	string	the limit clause
+	 * @return	string
+	 */
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	{
+		$conditions = array();
+
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
+
+		return 'DELETE FROM '.$table
+			.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '')
+			.($limit ? ' LIMIT '.$limit : '');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * DB Prefix
 	 *
 	 * Prepends a database prefix if one exists in configuration
@@ -1778,7 +1930,7 @@
 	 */
 	public function dbprefix($table = '')
 	{
-		if ($table == '')
+		if ($table === '')
 		{
 			$this->display_error('db_table_name_required');
 		}
@@ -1839,9 +1991,9 @@
 			$table = trim(strrchr($table, ' '));
 
 			// Store the alias, if it doesn't already exist
-			if ( ! in_array($table, $this->ar_aliased_tables))
+			if ( ! in_array($table, $this->qb_aliased_tables))
 			{
-				$this->ar_aliased_tables[] = $table;
+				$this->qb_aliased_tables[] = $table;
 			}
 		}
 	}
@@ -1868,9 +2020,9 @@
 		}
 		else
 		{
-			$sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
+			$sql = ( ! $this->qb_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
 
-			if (count($this->ar_select) === 0)
+			if (count($this->qb_select) === 0)
 			{
 				$sql .= '*';
 			}
@@ -1879,73 +2031,73 @@
 				// Cycle through the "select" portion of the query and prep each column name.
 				// The reason we protect identifiers here rather then in the select() function
 				// is because until the user calls the from() function we don't know if there are aliases
-				foreach ($this->ar_select as $key => $val)
+				foreach ($this->qb_select as $key => $val)
 				{
-					$no_escape = isset($this->ar_no_escape[$key]) ? $this->ar_no_escape[$key] : NULL;
-					$this->ar_select[$key] = $this->protect_identifiers($val, FALSE, $no_escape);
+					$no_escape = isset($this->qb_no_escape[$key]) ? $this->qb_no_escape[$key] : NULL;
+					$this->qb_select[$key] = $this->protect_identifiers($val, FALSE, $no_escape);
 				}
 
-				$sql .= implode(', ', $this->ar_select);
+				$sql .= implode(', ', $this->qb_select);
 			}
 		}
 
 		// Write the "FROM" portion of the query
-		if (count($this->ar_from) > 0)
+		if (count($this->qb_from) > 0)
 		{
-			$sql .= "\nFROM ".$this->_from_tables($this->ar_from);
+			$sql .= "\nFROM ".$this->_from_tables($this->qb_from);
 		}
 
 		// Write the "JOIN" portion of the query
-		if (count($this->ar_join) > 0)
+		if (count($this->qb_join) > 0)
 		{
-			$sql .= "\n".implode("\n", $this->ar_join);
+			$sql .= "\n".implode("\n", $this->qb_join);
 		}
 
 		// Write the "WHERE" portion of the query
-		if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)
+		if (count($this->qb_where) > 0 OR count($this->qb_like) > 0)
 		{
 			$sql .= "\nWHERE ";
 		}
 
-		$sql .= implode("\n", $this->ar_where);
+		$sql .= implode("\n", $this->qb_where);
 
 		// Write the "LIKE" portion of the query
-		if (count($this->ar_like) > 0)
+		if (count($this->qb_like) > 0)
 		{
-			if (count($this->ar_where) > 0)
+			if (count($this->qb_where) > 0)
 			{
 				$sql .= "\nAND ";
 			}
 
-			$sql .= implode("\n", $this->ar_like);
+			$sql .= implode("\n", $this->qb_like);
 		}
 
 		// Write the "GROUP BY" portion of the query
-		if (count($this->ar_groupby) > 0)
+		if (count($this->qb_groupby) > 0)
 		{
-			$sql .= "\nGROUP BY ".implode(', ', $this->ar_groupby);
+			$sql .= "\nGROUP BY ".implode(', ', $this->qb_groupby);
 		}
 
 		// Write the "HAVING" portion of the query
-		if (count($this->ar_having) > 0)
+		if (count($this->qb_having) > 0)
 		{
-			$sql .= "\nHAVING ".implode("\n", $this->ar_having);
+			$sql .= "\nHAVING ".implode("\n", $this->qb_having);
 		}
 
 		// Write the "ORDER BY" portion of the query
-		if (count($this->ar_orderby) > 0)
+		if (count($this->qb_orderby) > 0)
 		{
-			$sql .= "\nORDER BY ".implode(', ', $this->ar_orderby);
-			if ($this->ar_order !== FALSE)
+			$sql .= "\nORDER BY ".implode(', ', $this->qb_orderby);
+			if ($this->qb_order !== FALSE)
 			{
-				$sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
+				$sql .= ($this->qb_order === 'desc') ? ' DESC' : ' ASC';
 			}
 		}
 
 		// Write the "LIMIT" portion of the query
-		if (is_numeric($this->ar_limit))
+		if (is_numeric($this->qb_limit))
 		{
-			return $this->_limit($sql."\n", $this->ar_limit, $this->ar_offset);
+			return $this->_limit($sql."\n", $this->qb_limit, $this->qb_offset);
 		}
 
 		return $sql;
@@ -1961,7 +2113,7 @@
 	 * @param	object
 	 * @return	array
 	 */
-	public function _object_to_array($object)
+	protected function _object_to_array($object)
 	{
 		if ( ! is_object($object))
 		{
@@ -1972,7 +2124,7 @@
 		foreach (get_object_vars($object) as $key => $val)
 		{
 			// There are some built in keys we need to ignore for this conversion
-			if ( ! is_object($val) && ! is_array($val) && $key != '_parent_name')
+			if ( ! is_object($val) && ! is_array($val) && $key !== '_parent_name')
 			{
 				$array[$key] = $val;
 			}
@@ -1991,7 +2143,7 @@
 	 * @param	object
 	 * @return	array
 	 */
-	public function _object_to_array_batch($object)
+	protected function _object_to_array_batch($object)
 	{
 		if ( ! is_object($object))
 		{
@@ -2023,13 +2175,13 @@
 	/**
 	 * Start Cache
 	 *
-	 * Starts AR caching
+	 * Starts QB caching
 	 *
 	 * @return	void
 	 */
 	public function start_cache()
 	{
-		$this->ar_caching = TRUE;
+		$this->qb_caching = TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -2037,13 +2189,13 @@
 	/**
 	 * Stop Cache
 	 *
-	 * Stops AR caching
+	 * Stops QB caching
 	 *
 	 * @return	void
 	 */
 	public function stop_cache()
 	{
-		$this->ar_caching = FALSE;
+		$this->qb_caching = FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -2051,24 +2203,24 @@
 	/**
 	 * Flush Cache
 	 *
-	 * Empties the AR cache
+	 * Empties the QB cache
 	 *
 	 * @return	void
 	 */
 	public function flush_cache()
 	{
 		$this->_reset_run(array(
-			'ar_cache_select'		=> array(),
-			'ar_cache_from'			=> array(),
-			'ar_cache_join'			=> array(),
-			'ar_cache_where'		=> array(),
-			'ar_cache_like'			=> array(),
-			'ar_cache_groupby'		=> array(),
-			'ar_cache_having'		=> array(),
-			'ar_cache_orderby'		=> array(),
-			'ar_cache_set'			=> array(),
-			'ar_cache_exists'		=> array(),
-			'ar_cache_no_escape'	=> array()
+			'qb_cache_select'		=> array(),
+			'qb_cache_from'			=> array(),
+			'qb_cache_join'			=> array(),
+			'qb_cache_where'		=> array(),
+			'qb_cache_like'			=> array(),
+			'qb_cache_groupby'		=> array(),
+			'qb_cache_having'		=> array(),
+			'qb_cache_orderby'		=> array(),
+			'qb_cache_set'			=> array(),
+			'qb_cache_exists'		=> array(),
+			'qb_cache_no_escape'	=> array()
 		));
 	}
 
@@ -2077,47 +2229,47 @@
 	/**
 	 * Merge Cache
 	 *
-	 * When called, this function merges any cached AR arrays with
+	 * When called, this function merges any cached QB arrays with
 	 * locally called ones.
 	 *
 	 * @return	void
 	 */
 	protected function _merge_cache()
 	{
-		if (count($this->ar_cache_exists) === 0)
+		if (count($this->qb_cache_exists) === 0)
 		{
 			return;
 		}
 
-		foreach ($this->ar_cache_exists as $val)
+		foreach ($this->qb_cache_exists as $val)
 		{
-			$ar_variable	= 'ar_'.$val;
-			$ar_cache_var	= 'ar_cache_'.$val;
+			$qb_variable	= 'qb_'.$val;
+			$qb_cache_var	= 'qb_cache_'.$val;
 
-			if (count($this->$ar_cache_var) === 0)
+			if (count($this->$qb_cache_var) === 0)
 			{
 				continue;
 			}
 
-			$this->$ar_variable = array_unique(array_merge($this->$ar_cache_var, $this->$ar_variable));
+			$this->$qb_variable = array_unique(array_merge($this->$qb_cache_var, $this->$qb_variable));
 		}
 
 		// If we are "protecting identifiers" we need to examine the "from"
 		// portion of the query to determine if there are any aliases
-		if ($this->_protect_identifiers === TRUE && count($this->ar_cache_from) > 0)
+		if ($this->_protect_identifiers === TRUE && count($this->qb_cache_from) > 0)
 		{
-			$this->_track_aliases($this->ar_from);
+			$this->_track_aliases($this->qb_from);
 		}
 
-		$this->ar_no_escape = $this->ar_cache_no_escape;
+		$this->qb_no_escape = $this->qb_cache_no_escape;
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Reset Active Record values.
+	 * Reset Query Builder values.
 	 *
-	 * Publicly-visible method to reset the AR values.
+	 * Publicly-visible method to reset the QB values.
 	 *
 	 * @return	void
 	 */
@@ -2130,16 +2282,16 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Resets the active record values.  Called by the get() function
+	 * Resets the query builder values.  Called by the get() function
 	 *
 	 * @param	array	An array of fields to reset
 	 * @return	void
 	 */
-	protected function _reset_run($ar_reset_items)
+	protected function _reset_run($qb_reset_items)
 	{
-		foreach ($ar_reset_items as $item => $default_value)
+		foreach ($qb_reset_items as $item => $default_value)
 		{
-			if ( ! in_array($item, $this->ar_store_array))
+			if ( ! in_array($item, $this->qb_store_array))
 			{
 				$this->$item = $default_value;
 			}
@@ -2149,28 +2301,28 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Resets the active record values.  Called by the get() function
+	 * Resets the query builder values.  Called by the get() function
 	 *
 	 * @return	void
 	 */
 	protected function _reset_select()
 	{
 		$this->_reset_run(array(
-					'ar_select'		=> array(),
-					'ar_from'		=> array(),
-					'ar_join'		=> array(),
-					'ar_where'		=> array(),
-					'ar_like'		=> array(),
-					'ar_groupby'		=> array(),
-					'ar_having'		=> array(),
-					'ar_orderby'		=> array(),
-					'ar_wherein'		=> array(),
-					'ar_aliased_tables'	=> array(),
-					'ar_no_escape'		=> array(),
-					'ar_distinct'		=> FALSE,
-					'ar_limit'		=> FALSE,
-					'ar_offset'		=> FALSE,
-					'ar_order'		=> FALSE
+					'qb_select'		=> array(),
+					'qb_from'		=> array(),
+					'qb_join'		=> array(),
+					'qb_where'		=> array(),
+					'qb_like'		=> array(),
+					'qb_groupby'		=> array(),
+					'qb_having'		=> array(),
+					'qb_orderby'		=> array(),
+					'qb_wherein'		=> array(),
+					'qb_aliased_tables'	=> array(),
+					'qb_no_escape'		=> array(),
+					'qb_distinct'		=> FALSE,
+					'qb_limit'		=> FALSE,
+					'qb_offset'		=> FALSE,
+					'qb_order'		=> FALSE
 					)
 				);
 	}
@@ -2178,7 +2330,7 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Resets the active record "write" values.
+	 * Resets the query builder "write" values.
 	 *
 	 * Called by the insert() update() insert_batch() update_batch() and delete() functions
 	 *
@@ -2187,19 +2339,19 @@
 	protected function _reset_write()
 	{
 		$this->_reset_run(array(
-			'ar_set'	=> array(),
-			'ar_from'	=> array(),
-			'ar_where'	=> array(),
-			'ar_like'	=> array(),
-			'ar_orderby'	=> array(),
-			'ar_keys'	=> array(),
-			'ar_limit'	=> FALSE,
-			'ar_order'	=> FALSE
+			'qb_set'	=> array(),
+			'qb_from'	=> array(),
+			'qb_where'	=> array(),
+			'qb_like'	=> array(),
+			'qb_orderby'	=> array(),
+			'qb_keys'	=> array(),
+			'qb_limit'	=> FALSE,
+			'qb_order'	=> FALSE
 			)
 		);
 	}
 
 }
 
-/* End of file DB_active_rec.php */
-/* Location: ./system/database/DB_active_rec.php */
\ No newline at end of file
+/* End of file DB_query_builder.php */
+/* Location: ./system/database/DB_query_builder.php */
\ No newline at end of file
diff --git a/system/database/DB_result.php b/system/database/DB_result.php
index 04f964f..991f6ba 100644
--- a/system/database/DB_result.php
+++ b/system/database/DB_result.php
@@ -57,7 +57,7 @@
 	 * Query result.  Acts as a wrapper function for the following functions.
 	 *
 	 * @param	string	can be "object" or "array"
-	 * @return	mixed	either a result object or array
+	 * @return	object
 	 */
 	public function result($type = 'object')
 	{
@@ -81,7 +81,7 @@
 			return $this->custom_result_object[$class_name];
 		}
 
-		if ($this->result_id === FALSE OR $this->num_rows() == 0)
+		if ($this->result_id === FALSE OR $this->num_rows() === 0)
 		{
 			return array();
 		}
@@ -108,9 +108,9 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Query result.  "object" version.
+	 * Query result. "object" version.
 	 *
-	 * @return	object
+	 * @return	array
 	 */
 	public function result_object()
 	{
@@ -122,7 +122,7 @@
 		// In the event that query caching is on the result_id variable
 		// will return FALSE since there isn't a valid SQL resource so
 		// we'll simply return an empty array.
-		if ($this->result_id === FALSE OR $this->num_rows() == 0)
+		if ($this->result_id === FALSE OR $this->num_rows() === 0)
 		{
 			return array();
 		}
@@ -153,7 +153,7 @@
 		// In the event that query caching is on the result_id variable
 		// will return FALSE since there isn't a valid SQL resource so
 		// we'll simply return an empty array.
-		if ($this->result_id === FALSE OR $this->num_rows() == 0)
+		if ($this->result_id === FALSE OR $this->num_rows() === 0)
 		{
 			return array();
 		}
@@ -224,7 +224,7 @@
 			return;
 		}
 
-		if ($key != '' AND ! is_null($value))
+		if ($key !== '' && ! is_null($value))
 		{
 			$this->row_data[$key] = $value;
 		}
@@ -242,10 +242,10 @@
 		$result = $this->custom_result_object($type);
 		if (count($result) === 0)
 		{
-			return $result;
+			return NULL;
 		}
 
-		if ($n != $this->current_row AND isset($result[$n]))
+		if ($n !== $this->current_row && isset($result[$n]))
 		{
 			$this->current_row = $n;
 		}
@@ -253,6 +253,8 @@
 		return $result[$this->current_row];
 	}
 
+	// --------------------------------------------------------------------
+
 	/**
 	 * Returns a single result row - object version
 	 *
@@ -263,10 +265,10 @@
 		$result = $this->result_object();
 		if (count($result) === 0)
 		{
-			return $result;
+			return NULL;
 		}
 
-		if ($n != $this->current_row AND isset($result[$n]))
+		if ($n !== $this->current_row && isset($result[$n]))
 		{
 			$this->current_row = $n;
 		}
@@ -286,10 +288,10 @@
 		$result = $this->result_array();
 		if (count($result) === 0)
 		{
-			return $result;
+			return NULL;
 		}
 
-		if ($n != $this->current_row AND isset($result[$n]))
+		if ($n !== $this->current_row && isset($result[$n]))
 		{
 			$this->current_row = $n;
 		}
@@ -297,7 +299,6 @@
 		return $result[$this->current_row];
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
@@ -308,7 +309,7 @@
 	public function first_row($type = 'object')
 	{
 		$result = $this->result($type);
-		return (count($result) === 0) ? $result : $result[0];
+		return (count($result) === 0) ? NULL : $result[0];
 	}
 
 	// --------------------------------------------------------------------
@@ -321,7 +322,7 @@
 	public function last_row($type = 'object')
 	{
 		$result = $this->result($type);
-		return (count($result) === 0) ? $result : $result[count($result) - 1];
+		return (count($result) === 0) ? NULL : $result[count($result) - 1];
 	}
 
 	// --------------------------------------------------------------------
@@ -336,7 +337,7 @@
 		$result = $this->result($type);
 		if (count($result) === 0)
 		{
-			return $result;
+			return NULL;
 		}
 
 		if (isset($result[$this->current_row + 1]))
@@ -359,7 +360,7 @@
 		$result = $this->result($type);
 		if (count($result) === 0)
 		{
-			return $result;
+			return NULL;
 		}
 
 		if (isset($result[$this->current_row - 1]))
@@ -372,11 +373,23 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Returns an unbuffered row and move pointer to next row
+	 *
+	 * @return	mixed	either a result object or array
+	 */
+	public function unbuffered_row($type = 'object')
+	{
+		return ($type !== 'array') ? $this->_fetch_object() : $this->_fetch_assoc();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * The following functions are normally overloaded by the identically named
 	 * methods in the platform-specific driver -- except when query caching
-	 * is used.  When caching is enabled we do not load the other driver.
+	 * is used. When caching is enabled we do not load the other driver.
 	 * These functions are primarily here to prevent undefined function errors
-	 * when a cached result object is in use.  They are not otherwise fully
+	 * when a cached result object is in use. They are not otherwise fully
 	 * operational due to the unavailability of the database resource IDs with
 	 * cached results.
 	 */
@@ -384,8 +397,8 @@
 	public function num_fields() { return 0; }
 	public function list_fields() { return array(); }
 	public function field_data() { return array(); }
-	public function free_result() { return TRUE; }
-	protected function _data_seek() { return TRUE; }
+	public function free_result() { $this->result_id = FALSE; }
+	protected function _data_seek() { return FALSE; }
 	protected function _fetch_assoc() { return array(); }
 	protected function _fetch_object() { return array(); }
 
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index 642a004..02c9218 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -37,6 +37,11 @@
 	public $db;
 	public $data_cache		= array();
 
+	// Platform specific SQL strings
+	// Just setting those defaults to FALSE as they are mostly MySQL-specific
+	protected $_optimize_table	= FALSE;
+	protected $_repair_table	= FALSE;
+
 	public function __construct()
 	{
 		// Assign the main database object to $this->db
@@ -50,7 +55,7 @@
 	/**
 	 * List databases
 	 *
-	 * @return	bool
+	 * @return	array
 	 */
 	public function list_databases()
 	{
@@ -59,18 +64,25 @@
 		{
 			return $this->data_cache['db_names'];
 		}
-
-		$query = $this->db->query($this->_list_databases());
-		$dbs = array();
-		if ($query->num_rows() > 0)
+		elseif ($this->_list_databases === FALSE)
 		{
-			foreach ($query->result_array() as $row)
-			{
-				$dbs[] = current($row);
-			}
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 		}
 
-		return $this->data_cache['db_names'] = $dbs;
+		$this->data_cache['db_names'] = array();
+
+		$query = $this->db->query($this->_list_databases);
+		if ($query === FALSE)
+		{
+			return $this->data_cache['db_names'];
+		}
+
+		for ($i = 0, $c = count($query); $i < $c; $i++)
+		{
+			$this->data_cache['db_names'] = current($query[$i]);
+		}
+
+		return $this->data_cache['db_names'];
 	}
 
 	// --------------------------------------------------------------------
@@ -79,48 +91,36 @@
 	 * Determine if a particular database exists
 	 *
 	 * @param	string
-	 * @return	boolean
+	 * @return	bool
 	 */
 	public function database_exists($database_name)
 	{
-		// Some databases won't have access to the list_databases() function, so
-		// this is intended to allow them to override with their own functions as
-		// defined in $driver_utility.php
-		if (method_exists($this, '_database_exists'))
-		{
-			return $this->_database_exists($database_name);
-		}
-		else
-		{
-			return ( ! in_array($database_name, $this->list_databases())) ? FALSE : TRUE;
-		}
+		return in_array($database_name, $this->list_databases());
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * Optimize Table
 	 *
 	 * @param	string	the table name
-	 * @return	bool
+	 * @return	mixed
 	 */
 	public function optimize_table($table_name)
 	{
-		$sql = $this->_optimize_table($table_name);
-
-		if (is_bool($sql))
+		if ($this->_optimize_table === FALSE)
 		{
-			show_error('db_must_use_set');
-			return FALSE;
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 		}
 
-		$query = $this->db->query($sql);
-		$res = $query->result_array();
+		$query = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
+		if ($query !== FALSE)
+		{
+			$query = $query->result_array();
+			return current($res);
+		}
 
-		// Note: Due to a bug in current() that affects some versions
-		// of PHP we can not pass function call directly into it
-		return current($res);
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -128,26 +128,26 @@
 	/**
 	 * Optimize Database
 	 *
-	 * @return	array
+	 * @return	mixed
 	 */
 	public function optimize_database()
 	{
+		if ($this->_optimize_table === FALSE)
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
+		}
+
 		$result = array();
 		foreach ($this->db->list_tables() as $table_name)
 		{
-			$sql = $this->_optimize_table($table_name);
-
-			if (is_bool($sql))
+			$res = $this->db->query(sprintf($this->_optimize_table, $this->db->escape_identifiers($table_name)));
+			if (is_bool($res))
 			{
-				return $sql;
+				return $res;
 			}
 
-			$query = $this->db->query($sql);
-
 			// Build the result array...
-			// Note: Due to a bug in current() that affects some versions
-			// of PHP we can not pass function call directly into it
-			$res = $query->result_array();
+			$res = $res->result_array();
 			$res = current($res);
 			$key = str_replace($this->db->database.'.', '', current($res));
 			$keys = array_keys($res);
@@ -165,23 +165,23 @@
 	 * Repair Table
 	 *
 	 * @param	string	the table name
-	 * @return	bool
+	 * @return	mixed
 	 */
 	public function repair_table($table_name)
 	{
-		$sql = $this->_repair_table($table_name);
-
-		if (is_bool($sql))
+		if ($this->_repair_table === FALSE)
 		{
-			return $sql;
+			return ($this->db->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 		}
 
-		$query = $this->db->query($sql);
+		$query = $this->db->query(sprintf($this->_repair_table, $this->db->escape_identifiers($table_name)));
+		if (is_bool($query))
+		{
+			return $query;
+		}
 
-		// Note: Due to a bug in current() that affects some versions
-		// of PHP we can not pass function call directly into it
-		$res = $query->result_array();
-		return current($res);
+		$query = $query->result_array();
+		return current($query);
 	}
 
 	// --------------------------------------------------------------------
@@ -212,7 +212,7 @@
 		$out = rtrim($out).$newline;
 
 		// Next blast through the result array and build out the rows
-		foreach ($query->result_array() as $row)
+		while ($row = $query->unbuffered_row('array'))
 		{
 			foreach ($row as $item)
 			{
@@ -257,18 +257,18 @@
 		$CI->load->helper('xml');
 
 		// Generate the result
-		$xml = "<{$root}>".$newline;
-		foreach ($query->result_array() as $row)
+		$xml = '<'.$root.'>'.$newline;
+		while ($row = $query->unbuffered_row())
 		{
-			$xml .= $tab."<{$element}>".$newline;
+			$xml .= $tab.'<'.$element.'>'.$newline;
 			foreach ($row as $key => $val)
 			{
-				$xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;
+				$xml .= $tab.$tab.'<'.$key.'>'.xml_convert($val).'</'.$key.'>'.$newline;
 			}
-			$xml .= $tab."</{$element}>".$newline;
+			$xml .= $tab.'</'.$element.'>'.$newline;
 		}
 
-		return $xml .= "</$root>".$newline;
+		return $xml.'</'.$root.'>'.$newline;
 	}
 
 	// --------------------------------------------------------------------
@@ -328,8 +328,8 @@
 
 		// Is the encoder supported? If not, we'll either issue an
 		// error or use plain text depending on the debug settings
-		if (($prefs['format'] === 'gzip' AND ! @function_exists('gzencode'))
-			OR ($prefs['format'] === 'zip'  AND ! @function_exists('gzcompress')))
+		if (($prefs['format'] === 'gzip' && ! @function_exists('gzencode'))
+			OR ($prefs['format'] === 'zip' && ! @function_exists('gzcompress')))
 		{
 			if ($this->db->db_debug)
 			{
@@ -343,7 +343,7 @@
 		if ($prefs['format'] === 'zip')
 		{
 			// Set the filename if not provided (only needed with Zip files)
-			if ($prefs['filename'] == '')
+			if ($prefs['filename'] === '')
 			{
 				$prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
 							.date('Y-m-d_H-i', time()).'.sql';
@@ -369,7 +369,7 @@
 			$CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
 			return $CI->zip->get_zip();
 		}
-		elseif ($prefs['format'] == 'txt') // Was a text file requested?
+		elseif ($prefs['format'] === 'txt') // Was a text file requested?
 		{
 			return $this->_backup($prefs);
 		}
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
index bed3d86..6b67b75 100644
--- a/system/database/drivers/cubrid/cubrid_driver.php
+++ b/system/database/drivers/cubrid/cubrid_driver.php
@@ -21,7 +21,7 @@
  * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
- * @since		Version 2.0.2
+ * @since		Version 2.1
  * @filesource
  */
 
@@ -29,7 +29,7 @@
  * CUBRID Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -43,7 +43,7 @@
 	public $dbdriver = 'cubrid';
 
 	// The character used for escaping - no need in CUBRID
-	protected $_escape_char = '';
+	protected $_escape_char = '`';
 
 	// clause and character used for LIKE escape sequences - not used in CUBRID
 	protected $_like_escape_str = '';
@@ -74,7 +74,7 @@
 		else
 		{
 			// If no port is defined by the user, use the default value
-			$this->port == '' OR $this->port = 33000;
+			empty($this->port) OR $this->port = 33000;
 		}
 	}
 
@@ -159,22 +159,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @return	resource
-	 */
-	public function db_select()
-	{
-		// In CUBRID there is no need to select a database as the database
-		// is chosen at the connection time.
-		// So, to determine if the database is "selected", all we have to
-		// do is ping the server and return that value.
-		return cubrid_ping($this->conn_id);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -208,13 +192,8 @@
 	 */
 	public function trans_begin($test_mode = FALSE)
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -222,7 +201,7 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+		$this->_trans_failure = ($test_mode === TRUE);
 
 		if (cubrid_get_autocommit($this->conn_id))
 		{
@@ -241,13 +220,8 @@
 	 */
 	public function trans_commit()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -271,13 +245,8 @@
 	 */
 	public function trans_rollback()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -313,7 +282,9 @@
 			return $str;
 		}
 
-		if (function_exists('cubrid_real_escape_string') AND is_resource($this->conn_id))
+		if (function_exists('cubrid_real_escape_string') &&
+			(is_resource($this->conn_id)
+				OR (get_resource_type($this->conn_id) === 'Unknown' && preg_match('/Resource id #/', strval($this->conn_id)))))
 		{
 			$str = cubrid_real_escape_string($str, $this->conn_id);
 		}
@@ -325,7 +296,7 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+			return str_replace(array('%', '_'), array('\\%', '\\_'), $str);
 		}
 
 		return $str;
@@ -358,35 +329,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified table
-	 *
-	 * @param	string
-	 * @return	int
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$row = $query->row();
-		$this->_reset_select();
-		return (int) $row->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * List table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -396,11 +338,11 @@
 	 */
 	protected function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = "SHOW TABLES";
+		$sql = 'SHOW TABLES';
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix !== '')
 		{
-			$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%'";
+			return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'";
 		}
 
 		return $sql;
@@ -433,7 +375,7 @@
 	 */
 	protected function _field_data($table)
 	{
-		return "SELECT * FROM ".$table." LIMIT 1";
+		return 'SELECT * FROM '.$table.' LIMIT 1';
 	}
 
 	// --------------------------------------------------------------------
@@ -451,157 +393,9 @@
 		return array('code' => cubrid_errno($this->conn_id), 'message' => cubrid_error($this->conn_id));
 	}
 
-	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
 	// --------------------------------------------------------------------
 
 	/**
-	 * From Tables
-	 *
-	 * This function implicitly groups FROM tables so there is no confusion
-	 * about operator precedence in harmony with SQL standards
-	 *
-	 * @param	array
-	 * @return	string
-	 */
-	protected function _from_tables($tables)
-	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return '('.implode(', ', $tables).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * Generates a platform-specific replace string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _replace($table, $keys, $values)
-	{
-		return "REPLACE INTO ".$table." (\"".implode('", "', $keys)."\") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert_batch($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (\"".implode('", "', $keys)."\") VALUES ".implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = sprintf('"%s" = %s', $key, $val);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
@@ -614,90 +408,30 @@
 	protected function _update_batch($table, $values, $index, $where = NULL)
 	{
 		$ids = array();
-		$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
-
 		foreach ($values as $key => $val)
 		{
 			$ids[] = $val[$index];
 
 			foreach (array_keys($val) as $field)
 			{
-				if ($field != $index)
+				if ($field !== $index)
 				{
 					$final[$field][] = 'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
 				}
 			}
 		}
 
-		$sql = "UPDATE ".$table." SET ";
 		$cases = '';
-
 		foreach ($final as $k => $v)
 		{
-			$cases .= $k.' = CASE '."\n";
-			foreach ($v as $row)
-			{
-				$cases .= $row."\n";
-			}
-
-			$cases .= 'ELSE '.$k.' END, ';
+			$cases .= $k." = CASE \n"
+				.implode("\n", $v)
+				.'ELSE '.$k.' END, ';
 		}
 
-		$sql .= substr($cases, 0, -2);
-
-		$sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Truncate statement
-	 *
-	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	protected function _truncate($table)
-	{
-		return "TRUNCATE ".$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
+			.' WHERE '.(($where !== '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
+			.$index.' IN ('.implode(',', $ids).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -714,16 +448,7 @@
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		if ($offset == 0)
-		{
-			$offset = '';
-		}
-		else
-		{
-			$offset .= ", ";
-		}
-
-		return $sql."LIMIT ".$offset.$limit;
+		return $sql.'LIMIT '.($offset == 0 ? '' : $offset.', ').$limit;
 	}
 
 	// --------------------------------------------------------------------
@@ -731,12 +456,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@cubrid_close($conn_id);
+		@cubrid_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php
index bbda484..d328aa2 100644
--- a/system/database/drivers/cubrid/cubrid_forge.php
+++ b/system/database/drivers/cubrid/cubrid_forge.php
@@ -21,7 +21,7 @@
  * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
- * @since		Version 1.0
+ * @since		Version 2.1
  * @filesource
  */
 
@@ -34,35 +34,8 @@
  */
 class CI_DB_cubrid_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _create_database($name)
-	{
-		// CUBRID does not allow to create a database in SQL. The GUI tools
-		// have to be used for this purpose.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _drop_database($name)
-	{
-		// CUBRID does not allow to drop a database in SQL. The GUI tools
-		// have to be used for this purpose.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= FALSE;
+	protected $_drop_database	= FALSE;
 
 	/**
 	 * Process Fields
@@ -82,35 +55,33 @@
 			// entered the field information, so we'll simply add it to the list
 			if (is_numeric($field))
 			{
-				$sql .= "\n\t$attributes";
+				$sql .= "\n\t".$attributes;
 			}
 			else
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t\"".$this->db->protect_identifiers($field).'"';
+				$sql .= "\n\t".$this->db->escape_identifiers($field);
 
-				if (array_key_exists('NAME', $attributes))
-				{
-					$sql .= ' '.$this->db->protect_identifiers($attributes['NAME']).' ';
-				}
+				empty($attributes['NAME']) OR $sql .= ' '.$this->db->escape_identifiers($attributes['NAME']).' ';
 
-				if (array_key_exists('TYPE', $attributes))
+				if ( ! empty($attributes['TYPE']))
 				{
 					$sql .= ' '.$attributes['TYPE'];
 
-					if (array_key_exists('CONSTRAINT', $attributes))
+					if ( ! empty($attributes['CONSTRAINT']))
 					{
-						switch ($attributes['TYPE'])
+						switch (strtolower($attributes['TYPE']))
 						{
 							case 'decimal':
 							case 'float':
 							case 'numeric':
 								$sql .= '('.implode(',', $attributes['CONSTRAINT']).')';
 								break;
-							case 'enum': 	// As of version 8.4.0 CUBRID does not support
-											// enum data type.
-											break;
+							case 'enum':
+								// Will be supported in the future as part a part of
+								// MySQL compatibility features.
+								break;
 							case 'set':
 								$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
 								break;
@@ -120,33 +91,29 @@
 					}
 				}
 
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+			/* As of version 8.4.1 CUBRID does not support UNSIGNED INTEGER data type.
+			 * Will be supported in the next release as a part of MySQL Compatibility.
+			 *
+				if (isset($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
 				{
-					//$sql .= ' UNSIGNED';
-					// As of version 8.4.0 CUBRID does not support UNSIGNED INTEGER data type.
-					// Will be supported in the next release as a part of MySQL Compatibility.
+					$sql .= ' UNSIGNED';
+				}
+			 */
+
+				if (isset($attributes['DEFAULT']))
+				{
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
 				}
 
-				if (array_key_exists('DEFAULT', $attributes))
-				{
-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
-				}
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
 
-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
-				{
-					$sql .= ' NULL';
-				}
-				else
-				{
-					$sql .= ' NOT NULL';
-				}
-
-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
 				{
 					$sql .= ' AUTO_INCREMENT';
 				}
 
-				if (array_key_exists('UNIQUE', $attributes) && $attributes['UNIQUE'] === TRUE)
+				if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE)
 				{
 					$sql .= ' UNIQUE';
 				}
@@ -174,27 +141,24 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
+		/* As of version 8.4.1 CUBRID does not support this SQL syntax.
 		if ($if_not_exists === TRUE)
 		{
-			//$sql .= 'IF NOT EXISTS ';
-			// As of version 8.4.0 CUBRID does not support this SQL syntax.
+			$sql .= 'IF NOT EXISTS ';
 		}
+		*/
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
-
-		$sql .= $this->_process_fields($fields);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields);
 
 		// If there is a PK defined
 		if (count($primary_keys) > 0)
 		{
-			$key_name = 'pk_'.$table.'_'.$this->db->protect_identifiers(implode('_', $primary_keys));
-
-			$primary_keys = $this->db->protect_identifiers($primary_keys);
-			$sql .= ",\n\tCONSTRAINT " . $key_name . " PRIMARY KEY(" . implode(', ', $primary_keys) . ")";
+			$key_name = $this->db->escape_identifiers('pk_'.$table.'_'.implode('_', $primary_keys));
+			$sql .= ",\n\tCONSTRAINT ".$key_name.' PRIMARY KEY('.implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
@@ -203,34 +167,20 @@
 			{
 				if (is_array($key))
 				{
-					$key_name = $this->db->protect_identifiers(implode('_', $key));
-					$key = $this->db->protect_identifiers($key);
+					$key_name = $this->db->escape_identifiers('idx_'.$table.implode('_', $key));
+					$key = $this->db->escape_identifiers($key);
 				}
 				else
 				{
-					$key_name = $this->db->protect_identifiers($key);
+					$key_name = $this->db->escape_identifiers('idx_'.$table.$key);
 					$key = array($key_name);
 				}
 
-				$sql .= ",\n\tKEY \"{$key_name}\" (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tKEY ".$key_name.' ('.implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n);";
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
+		return $sql."\n);";
 	}
 
 	// --------------------------------------------------------------------
@@ -247,40 +197,18 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
+		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' ';
 
 		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		if ($alter_type === 'DROP')
 		{
-			return $sql.$this->db->protect_identifiers($fields);
+			return $sql.$this->db->escape_identifiers($fields);
 		}
 
-		$sql .= $this->_process_fields($fields);
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'RENAME TABLE '.$this->db->protect_identifiers($table_name).' AS '.$this->db->protect_identifiers($new_table_name);
+		return $sql.$this->_process_fields($fields)
+			.($after_field !== '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 	}
 
 }
diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php
index 6a61a21..3eb9f7e 100644
--- a/system/database/drivers/cubrid/cubrid_result.php
+++ b/system/database/drivers/cubrid/cubrid_result.php
@@ -21,7 +21,7 @@
  * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
- * @since		Version 2.0.2
+ * @since		Version 2.1
  * @filesource
  */
 
@@ -84,53 +84,20 @@
 	public function field_data()
 	{
 		$retval = array();
-
-		$tablePrimaryKeys = array();
+		$i = 0;
 
 		while ($field = cubrid_fetch_field($this->result_id))
 		{
-			$F				= new stdClass();
-			$F->name		= $field->name;
-			$F->type		= $field->type;
-			$F->default		= $field->def;
-			$F->max_length	= $field->max_length;
-
-			// At this moment primary_key property is not returned when
-			// cubrid_fetch_field is called. The following code will
-			// provide a patch for it. primary_key property will be added
-			// in the next release.
-
-			// TODO: later version of CUBRID will provide primary_key
-			// property.
-			// When PK is defined in CUBRID, an index is automatically
-			// created in the db_index system table in the form of
-			// pk_tblname_fieldname. So the following will count how many
-			// columns are there which satisfy this format.
-			// The query will search for exact single columns, thus
-			// compound PK is not supported.
-			$res = cubrid_query($this->conn_id,
-				"SELECT COUNT(*) FROM db_index WHERE class_name = '" . $field->table .
-				"' AND is_primary_key = 'YES' AND index_name = 'pk_" .
-				$field->table . "_" . $field->name . "'"
-			);
-
-			if ($res)
-			{
-				$row = cubrid_fetch_array($res, CUBRID_NUM);
-				$F->primary_key = ($row[0] > 0 ? 1 : null);
-			}
-			else
-			{
-				$F->primary_key = null;
-			}
-
-			if (is_resource($res))
-			{
-				cubrid_close_request($res);
-				$this->result_id = FALSE;
-			}
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $field->name;
+			// CUBRID returns type as e.g. varchar(100),
+			// so we need to remove all digits and brackets.
+			$retval[$i]->type		= preg_replace('/[\d()]/', '', $field->type);
+			$retval[$i]->default		= $field->def;
+			// Use CUBRID's native API to obtain column's max_length,
+			// otherwise $field->max_length has incorrect info
+			$retval[$i]->max_length		= cubrid_field_len($this->result_id, $i);
+			$retval[$i++]->primary_key	= $field->primary_key;
 		}
 
 		return $retval;
@@ -145,9 +112,8 @@
 	 */
 	public function free_result()
 	{
-		if(is_resource($this->result_id) ||
-			get_resource_type($this->result_id) == "Unknown" &&
-			preg_match('/Resource id #/', strval($this->result_id)))
+		if (is_resource($this->result_id) OR
+			(get_resource_type($this->result_id) === 'Unknown' && preg_match('/Resource id #/', strval($this->result_id))))
 		{
 			cubrid_close_request($this->result_id);
 			$this->result_id = FALSE;
@@ -163,7 +129,7 @@
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php
index dafd661..c8cee99 100644
--- a/system/database/drivers/cubrid/cubrid_utility.php
+++ b/system/database/drivers/cubrid/cubrid_utility.php
@@ -21,7 +21,7 @@
  * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
- * @since		Version 1.0
+ * @since		Version 2.1
  * @filesource
  */
 
@@ -39,69 +39,25 @@
 	 *
 	 * @return	array
 	 */
-	public function _list_databases()
+	public function list_databases()
 	{
-		// CUBRID does not allow to see the list of all databases on the
-		// server. It is the way its architecture is designed. Every
-		// database is independent and isolated.
-		// For this reason we can return only the name of the currect
-		// connected database.
-		if ($this->conn_id)
+		if (isset($this->data_cache['db_names']))
 		{
-			return "SELECT '" . $this->database . "'";
+			return $this->data_cache['db_names'];
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return $this->data_cache['db_names'] = cubrid_list_dbs($this->db->conn_id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 * @link 	http://www.cubrid.org/manual/840/en/Optimize%20Database
-	 */
-	public function _optimize_table($table)
-	{
-		// No SQL based support in CUBRID as of version 8.4.0. Database or
-		// table optimization can be performed using CUBRID Manager
-		// database administration tool. See the link above for more info.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 * @link 	http://www.cubrid.org/manual/840/en/Checking%20Database%20Consistency
-	 */
-	public function _repair_table($table)
-	{
-		// Not supported in CUBRID as of version 8.4.0. Database or
-		// table consistency can be checked using CUBRID Manager
-		// database administration tool. See the link above for more info.
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-	/**
 	 * CUBRID Export
 	 *
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// No SQL based support in CUBRID as of version 8.4.0. Database or
 		// table backup can be performed using CUBRID Manager
diff --git a/system/database/drivers/interbase/interbase_driver.php b/system/database/drivers/interbase/interbase_driver.php
index d8b6ae5..5a03607 100644
--- a/system/database/drivers/interbase/interbase_driver.php
+++ b/system/database/drivers/interbase/interbase_driver.php
@@ -29,7 +29,7 @@
  * Firebird/Interbase Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -85,19 +85,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @return	bool
-	 */
-	public function db_select()
-	{
-		// Connection selects the database
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -257,35 +244,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$query = $query->row();
-		$this->_reset_select();
-		return (int) $query->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * List table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -297,7 +255,7 @@
 	{
 		$sql = 'SELECT "RDB$RELATION_NAME" FROM "RDB$RELATIONS" WHERE "RDB$RELATION_NAME" NOT LIKE \'RDB$%\' AND "RDB$RELATION_NAME" NOT LIKE \'MON$%\'';
 
-		if ($prefix_limit !== FALSE && $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix !== '')
 		{
 			return $sql.' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 		}
@@ -356,38 +314,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This public function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	protected function _escape_identifiers($item)
-	{
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$item = str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$item = str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This public function implicitly groups FROM tables so there is no confusion
@@ -398,30 +324,7 @@
 	 */
 	protected function _from_tables($tables)
 	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		//Interbase/Firebird doesn't like grouped tables
-		return implode(', ', $tables);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
+		return is_array($tables) ? implode(', ', $tables) : $tables;
 	}
 
 	// --------------------------------------------------------------------
@@ -435,20 +338,26 @@
 	 * @param	array	the update data
 	 * @param	array	the where clause
 	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach ($values as $key => $val)
 		{
 			$valstr[] = $key.' = '.$val;
 		}
 
-		//$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
+
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
 		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
-			.(($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '')
+			.$where
 			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '');
 	}
 
@@ -459,15 +368,16 @@
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This public function maps to "DELETE FROM table"
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
 	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return $this->_delete($table);
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -479,25 +389,18 @@
 	 *
 	 * @param	string	the table name
 	 * @param	array	the where clause
-	 * @param	string	the limit clause
+	 * @param	array	the like clause
+	 * @param	string	the limit clause (ignored)
 	 * @return	string
 	 */
 	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ".implode("\n", $where)
-					.((count($where) > 0 && count($like) > 0) ? ' AND ' : '')
-					.implode("\n", $like);
-		}
-		else
-		{
-			$conditions = '';
-		}
+		$conditions = array();
 
-		//$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-		return 'DELETE FROM '.$table.' '.$conditions;
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -534,12 +437,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@ibase_close($conn_id);
+		@ibase_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/interbase/interbase_forge.php b/system/database/drivers/interbase/interbase_forge.php
index f460435..3f9967f 100644
--- a/system/database/drivers/interbase/interbase_forge.php
+++ b/system/database/drivers/interbase/interbase_forge.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Interbase/Firebird Forge Class
  *
@@ -36,18 +34,22 @@
  */
 class CI_DB_interbase_forge extends CI_DB_forge {
 
+	protected $_drop_table	= 'DROP TABLE %s';
+
 	/**
 	 * Create database
 	 *
 	 * @param	string	the database name
 	 * @return	string
 	 */
-	protected function _create_database($filename='')
+	public function create_database($db_name)
 	{
-		// Firebird databases are flat files, so a path is required 
+		// Firebird databases are flat files, so a path is required
+
 		// Hostname is needed for remote access
-		return 'CREATE DATABASE "'.$this->hostname.':'.$filename.'"';
-		
+		empty($this->db->hostname) OR $db_name = $this->hostname.':'.$db_name;
+
+		return parent::create_database('"'.$db_name.'"');
 	}
 
 	// --------------------------------------------------------------------
@@ -55,14 +57,20 @@
 	/**
 	 * Drop database
 	 *
-	 * @param	string	the database name - not used in this driver 
-	 *	- the current db is dropped
+	 * @param	string	the database name
+	 *		- not used in this driver, the current db is dropped
 	 * @return	bool
 	 */
-	protected function _drop_database($name='')
+	public function drop_database($db_name = '')
 	{
-		return ibase_drop_db($this->conn_id);
+		if ( ! ibase_drop_db($this->conn_id))
+		{
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
+		}
+
+		return TRUE;
 	}
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -72,14 +80,14 @@
 	 * @param	array	the fields
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	string
 	 */
 	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
-		$sql .= $this->db->protect_identifiers($table)."(";
+		$sql .= $this->db->escape_identifiers($table).'(';
 		$current_field_count = 0;
 
 		foreach ($fields as $field => $attributes)
@@ -89,41 +97,30 @@
 			// entered the field information, so we'll simply add it to the list
 			if (is_numeric($field))
 			{
-				$sql .= "\n\t$attributes";
+				$sql .= "\n\t".$attributes;
 			}
 			else
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field);
+				$sql .= "\n\t".$this->db->escape_identifiers($field).' '.$attributes['TYPE'];
 
-				$sql .=  ' '.$attributes['TYPE'];
+				empty($attributes['CONSTRAINT']) OR $sql .= '('.$attributes['CONSTRAINT'].')';
 
-				if (array_key_exists('CONSTRAINT', $attributes))
-				{
-					$sql .= '('.$attributes['CONSTRAINT'].')';
-				}
-
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
 				{
 					$sql .= ' UNSIGNED';
 				}
 
-				if (array_key_exists('DEFAULT', $attributes))
+				if (isset($attributes['DEFAULT']))
 				{
-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
 				}
 
-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
-				{
-					$sql .= ' NULL';
-				}
-				else
-				{
-					$sql .= ' NOT NULL';
-				}
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
 
-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
 				{
 					$sql .= ' AUTO_INCREMENT';
 				}
@@ -138,42 +135,23 @@
 
 		if (count($primary_keys) > 0)
 		{
-			$primary_keys = $this->db->protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+			$primary_keys = $this->db->escape_identifiers($primary_keys);
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $primary_keys).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
 		{
 			foreach ($keys as $key)
 			{
-				if (is_array($key))
-				{
-					$key = $this->db->protect_identifiers($key);
-				}
-				else
-				{
-					$key = array($this->db->protect_identifiers($key));
-				}
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->db->escape_identifiers($key));
 
-				$sql .= ",\n\tUNIQUE (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tUNIQUE (".implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n)";
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @return	string
-	 */
-	protected function _drop_table($table)
-	{
-		return 'DROP TABLE '.$name;
+		return $sql."\n)";
 	}
 
 	// --------------------------------------------------------------------
@@ -189,54 +167,19 @@
 	 * @param	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
 	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table)." $alter_type ".$this->db->protect_identifiers($column_name);
-
-		$sql .= " {$column_definition}";
-
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"{$default_value}\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			$sql .= ' AFTER ' . $this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
+		return 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' '.$this->db->escape_identifiers($column_name)
+			.' '.$column_definition
+			.($default_value !== '' ? ' DEFAULT "'.$default_value.'"' : '')
+			.($null === NULL ? ' NULL' : ' NOT NULL')
+			.($after_field !== '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	protected function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
 }
 
 /* End of file interbase_forge.php */
diff --git a/system/database/drivers/interbase/interbase_result.php b/system/database/drivers/interbase/interbase_result.php
index fd4178d..5ddb6fa 100644
--- a/system/database/drivers/interbase/interbase_result.php
+++ b/system/database/drivers/interbase/interbase_result.php
@@ -131,23 +131,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset. We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @return	array
-	 */
-	protected function _data_seek($n = 0)
-	{
-		// Interbase driver doesn't implement a suitable function
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
diff --git a/system/database/drivers/interbase/interbase_utility.php b/system/database/drivers/interbase/interbase_utility.php
index a88055e..1642118 100644
--- a/system/database/drivers/interbase/interbase_utility.php
+++ b/system/database/drivers/interbase/interbase_utility.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Interbase/Firebird Utility Class
  *
@@ -36,56 +34,7 @@
  */
 class CI_DB_interbase_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * I don't believe you can do a database listing with Firebird
-	 * since each database is its own file.  I suppose we could
-	 * try reading a directory looking for Firebird files, but
-	 * that doesn't seem like a terribly good idea
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		if ($this->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Is optimization even supported in Interbase/Firebird?
-	 *
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	public function _optimize_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Table repairs are not supported in Interbase/Firebird
-	 *
-	 * @param	string	the table name
-	 * @return	object
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * Interbase/Firebird Export
@@ -93,22 +42,20 @@
 	 * @param	string	$filename
 	 * @return	mixed
 	 */
-	public function backup($filename)
+	protected function _backup($filename)
 	{
 		if ($service = ibase_service_attach($this->db->hostname, $this->db->username, $this->db->password))
 		{
 			$res = ibase_backup($service, $this->db->database, $filename.'.fbk');
-			
-			//Close the service connection	
+
+			// Close the service connection
 			ibase_service_detach($service);
-			
 			return $res;
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return FALSE;
 	}
+
 }
 
 /* End of file interbase_utility.php */
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 9128086..87094e7 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -29,7 +29,7 @@
  * MS SQL Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -43,7 +43,7 @@
 	public $dbdriver = 'mssql';
 
 	// The character used for escaping
-	protected $_escape_char = '';
+	protected $_escape_char = '"';
 
 	// clause and character used for LIKE escape sequences
 	protected $_like_escape_str = " ESCAPE '%s' ";
@@ -52,10 +52,33 @@
 	/**
 	 * The syntax to count rows is slightly different across different
 	 * database engines, so this string appears in each driver and is
-	 * used for the count_all() and count_all_results() functions.
+	 * used for the count_all() and count_all_results() methods.
 	 */
 	protected $_count_string = 'SELECT COUNT(*) AS ';
-	protected $_random_keyword = ' ASC'; // not currently supported
+	protected $_random_keyword = ' NEWID()';
+
+	// MSSQL-specific properties
+	protected $_quoted_identifier = TRUE;
+
+	/*
+	 * Constructor
+	 *
+	 * Appends the port number to the hostname, if needed.
+	 *
+	 * @param	array
+	 * @return	void
+	 */
+	public function __construct($params)
+	{
+		parent::__construct($params);
+
+		if ( ! empty($this->port))
+		{
+			$this->hostname .= (DIRECTORY_SEPARATOR === '\\' ? ',' : ':').$this->port;
+		}
+	}
+
+	// --------------------------------------------------------------------
 
 	/**
 	 * Non-persistent database connection
@@ -64,12 +87,7 @@
 	 */
 	public function db_connect()
 	{
-		if ($this->port != '')
-		{
-			$this->hostname .= ','.$this->port;
-		}
-
-		return @mssql_connect($this->hostname, $this->username, $this->password);
+		return $this->_mssql_connect();
 	}
 
 	// --------------------------------------------------------------------
@@ -81,12 +99,35 @@
 	 */
 	public function db_pconnect()
 	{
-		if ($this->port != '')
+		return $this->_mssql_connect(TRUE);
+	}
+
+	// --------------------------------------------------------------------
+
+	/*
+	 * MSSQL Connect
+	 *
+	 * @param	bool
+	 * @return	resource
+	 */
+	protected function _mssql_connect($persistent = FALSE)
+	{
+		$conn_id = ($persistent)
+				? @mssql_pconnect($this->hostname, $this->username, $this->password)
+				: @mssql_connect($this->hostname, $this->username, $this->password);
+
+		if ( ! $conn_id)
 		{
-			$this->hostname .= ','.$this->port;
+			return FALSE;
 		}
 
-		return @mssql_pconnect($this->hostname, $this->username, $this->password);
+		// Determine how identifiers are escaped
+		$query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi');
+		$query = $query->row_array();
+		$this->_quoted_identifier = empty($query) ? FALSE : (bool) $query->qi;
+		$this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']');
+
+		return $conn_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -106,7 +147,7 @@
 
 		// Note: The brackets are required in the event that the DB name
 		// contains reserved characters
-		if (@mssql_select_db('['.$database.']', $this->conn_id))
+		if (@mssql_select_db($this->escape_identifiers($database), $this->conn_id))
 		{
 			$this->database = $database;
 			return TRUE;
@@ -121,7 +162,7 @@
 	 * Execute the query
 	 *
 	 * @param	string	an SQL query
-	 * @return	resource
+	 * @return	mixed	resource if rows are returned, bool otherwise
 	 */
 	protected function _execute($sql)
 	{
@@ -137,13 +178,8 @@
 	 */
 	public function trans_begin($test_mode = FALSE)
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -151,10 +187,9 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+		$this->_trans_failure = ($test_mode === TRUE);
 
-		$this->simple_query('BEGIN TRAN');
-		return TRUE;
+		return $this->simple_query('BEGIN TRAN');
 	}
 
 	// --------------------------------------------------------------------
@@ -166,19 +201,13 @@
 	 */
 	public function trans_commit()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
 
-		$this->simple_query('COMMIT TRAN');
-		return TRUE;
+		return $this->simple_query('COMMIT TRAN');
 	}
 
 	// --------------------------------------------------------------------
@@ -190,19 +219,13 @@
 	 */
 	public function trans_rollback()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
 
-		$this->simple_query('ROLLBACK TRAN');
-		return TRUE;
+		return $this->simple_query('ROLLBACK TRAN');
 	}
 
 	// --------------------------------------------------------------------
@@ -232,7 +255,7 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(
+			return str_replace(
 				array($this->_like_escape_chr, '%', '_'),
 				array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
 				$str
@@ -265,11 +288,13 @@
 	 */
 	public function insert_id()
 	{
-		$ver = self::_parse_major_version($this->version());
-		$sql = ($ver >= 8 ? "SELECT SCOPE_IDENTITY() AS last_id" : "SELECT @@IDENTITY AS last_id");
-		$query = $this->query($sql);
-		$row = $query->row();
-		return $row->last_id;
+		$query = (self::_parse_major_version($this->version()) > 7)
+			? 'SELECT SCOPE_IDENTITY() AS last_id'
+			: 'SELECT @@IDENTITY AS last_id';
+
+		$query = $this->query($query);
+		$query = $query->row();
+		return $query->last_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -304,35 +329,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$row = $query->row();
-		$this->_reset_select();
-		return (int) $row->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * List table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -345,7 +341,7 @@
 		$sql = "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name";
 
 		// for future compatibility
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE AND $this->dbprefix !== '')
 		{
 			//$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 			return FALSE; // not currently supported
@@ -381,7 +377,7 @@
 	 */
 	protected function _field_data($table)
 	{
-		return "SELECT TOP 1 * FROM ".$table;
+		return 'SELECT TOP 1 * FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -404,47 +400,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
@@ -455,29 +410,7 @@
 	 */
 	protected function _from_tables($tables)
 	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return implode(', ', $tables);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return is_array($tables) ? implode(', ', $tables) : $tables;
 	}
 
 	// --------------------------------------------------------------------
@@ -490,46 +423,44 @@
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
-		foreach ($values as $key => $val)
+		foreach($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
 
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).' WHERE '.$where;
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
 	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return "TRUNCATE ".$table;
+		return 'TRUNCATE TABLE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -541,28 +472,22 @@
 	 *
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
 	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
+		$conditions = (count($conditions) > 0) ? ' WHERE '.implode(' AND ', $conditions) : '';
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return ($limit)
+			? 'WITH ci_delete AS (SELECT TOP '.$limit.' * FROM '.$table.$conditions.') DELETE FROM ci_delete'
+			: 'DELETE FROM '.$table.$conditions;
 	}
 
 	// --------------------------------------------------------------------
@@ -579,9 +504,7 @@
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		$i = $limit + $offset;
-
-		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql);
+		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.($limit + $offset).' ', $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -589,12 +512,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@mssql_close($conn_id);
+		@mssql_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php
index 2e3e314..3a3528f 100644
--- a/system/database/drivers/mssql/mssql_forge.php
+++ b/system/database/drivers/mssql/mssql_forge.php
@@ -34,44 +34,7 @@
  */
 class CI_DB_mssql_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @param	string	table name
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return "DROP TABLE ".$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_table	= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
@@ -83,18 +46,15 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	string
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
-		$sql = 'CREATE TABLE ';
+		$sql = ($if_not_exists === TRUE)
+			? "IF NOT EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'".$table."') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\n"
+			: '';
 
-		if ($if_not_exists === TRUE)
-		{
-			$sql .= 'IF NOT EXISTS ';
-		}
+		$sql .= 'CREATE TABLE '.$this->db->escape_identifiers($table).' (';
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
 		$current_field_count = 0;
-
 		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
@@ -102,41 +62,33 @@
 			// entered the field information, so we'll simply add it to the list
 			if (is_numeric($field))
 			{
-				$sql .= "\n\t$attributes";
+				$sql .= "\n\t".$attributes;
 			}
 			else
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field);
+				$sql .= "\n\t".$this->db->escape_identifiers($field).' '.$attributes['TYPE'];
 
-				$sql .=  ' '.$attributes['TYPE'];
-
-				if (array_key_exists('CONSTRAINT', $attributes))
+				if (stripos($attributes['TYPE'], 'INT') === FALSE && ! empty($attributes['CONSTRAINT']))
 				{
 					$sql .= '('.$attributes['CONSTRAINT'].')';
 				}
 
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
 				{
 					$sql .= ' UNSIGNED';
 				}
 
-				if (array_key_exists('DEFAULT', $attributes))
+				if (isset($attributes['DEFAULT']))
 				{
-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
 				}
 
-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
-				{
-					$sql .= ' NULL';
-				}
-				else
-				{
-					$sql .= ' NOT NULL';
-				}
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
 
-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
 				{
 					$sql .= ' AUTO_INCREMENT';
 				}
@@ -151,30 +103,22 @@
 
 		if (count($primary_keys) > 0)
 		{
-			$primary_keys = $this->db->protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
 		{
 			foreach ($keys as $key)
 			{
-				if (is_array($key))
-				{
-					$key = $this->db->protect_identifiers($key);
-				}
-				else
-				{
-					$key = array($this->db->protect_identifiers($key));
-				}
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->db->escape_identifiers($key));
 
-				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tFOREIGN KEY (".implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n)";
-
-		return $sql;
+		return $sql."\n)";
 	}
 
 	// --------------------------------------------------------------------
@@ -194,56 +138,20 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
+		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' '.$this->db->escape_identifiers($column_name);
 
 		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		if ($alter_type === 'DROP')
 		{
 			return $sql;
 		}
 
-		$sql .= " $column_definition";
-
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		// I think this syntax will work, but can find little documentation on renaming tables in MSSQL
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
+		return $sql.' '.$column_definition
+			.($default_value != '' ? ' DEFAULT "'.$default_value.'"' : '')
+			.($null === NULL ? ' NULL' : ' NOT NULL')
+			.($after_field != '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 	}
 
 }
diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php
index 2723f46..5929306 100644
--- a/system/database/drivers/mssql/mssql_result.php
+++ b/system/database/drivers/mssql/mssql_result.php
@@ -92,12 +92,12 @@
 		$retval = array();
 		while ($field = mssql_fetch_field($this->result_id))
 		{
-			$F				= new stdClass();
-			$F->name		= $field->name;
-			$F->type		= $field->type;
+			$F		= new stdClass();
+			$F->name	= $field->name;
+			$F->type	= $field->type;
 			$F->max_length	= $field->max_length;
 			$F->primary_key = 0;
-			$F->default		= '';
+			$F->default	= '';
 
 			$retval[] = $F;
 		}
@@ -126,11 +126,11 @@
 	/**
 	 * Data Seek
 	 *
-	 * Moves the internal pointer to the desired offset.  We call
+	 * Moves the internal pointer to the desired offset. We call
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php
index 5c14433..69fcec5 100644
--- a/system/database/drivers/mssql/mssql_utility.php
+++ b/system/database/drivers/mssql/mssql_utility.php
@@ -34,55 +34,16 @@
  */
 class CI_DB_mssql_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'EXEC sp_helpdb'; // Can also be: EXEC sp_databases
+	protected $_optimize_table	= 'ALTER INDEX all ON %s REORGANIZE';
 
 	/**
 	 * MSSQL Export
 	 *
 	 * @param	array	Preferences
-	 * @return	mixed
+	 * @return	bool
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index bef4111..8938d22 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -29,7 +29,7 @@
  * MySQL Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -47,7 +47,7 @@
 
 	// clause and character used for LIKE escape sequences - not used in MySQL
 	protected $_like_escape_str = '';
-	protected $_like_escape_chr = '';
+	protected $_like_escape_chr = '\\';
 
 	/**
 	 * The syntax to count rows is slightly different across different
@@ -68,7 +68,7 @@
 	{
 		parent::__construct($params);
 
-		if ($this->port != '')
+		if ( ! empty($this->port))
 		{
 			$this->hostname .= ':'.$this->port;
 		}
@@ -291,7 +291,9 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			return str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
 		}
 
 		return $str;
@@ -324,35 +326,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$query = $query->row();
-		$this->_reset_select();
-		return (int) $query->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * List table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -364,7 +337,7 @@
 	{
 		$sql = 'SHOW TABLES FROM '.$this->_escape_char.$this->database.$this->_escape_char;
 
-		if ($prefix_limit !== FALSE && $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix !== '')
 		{
 			return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'";
 		}
@@ -397,7 +370,7 @@
 	 */
 	public function field_data($table = '')
 	{
-		if ($table == '')
+		if ($table === '')
 		{
 			return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
 		}
@@ -439,150 +412,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$item = str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$item = str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * From Tables
-	 *
-	 * This function implicitly groups FROM tables so there is no confusion
-	 * about operator precedence in harmony with SQL standards
-	 *
-	 * @param	string	table name
-	 * @return	string
-	 */
-	protected function _from_tables($tables)
-	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return '('.implode(', ', $tables).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * Generates a platform-specific replace string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _replace($table, $keys, $values)
-	{
-		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert_batch($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key.' = '.$val;
-		}
-
-		$where = ($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '';
-		if (count($like) > 0)
-		{
-			$where .= ($where == '' ? ' WHERE ' : ' AND ').implode(' ', $like);
-		}
-
-		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where
-			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
-			.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
@@ -601,7 +430,7 @@
 
 			foreach (array_keys($val) as $field)
 			{
-				if ($field != $index)
+				if ($field !== $index)
 				{
 					$final[$field][] =  'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
 				}
@@ -617,60 +446,13 @@
 		}
 
 		return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
-			.' WHERE '.(($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
+			.' WHERE '.(($where !== '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
 			.$index.' IN('.implode(',', $ids).')';
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Truncate statement
-	 *
-	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	protected function _truncate($table)
-	{
-		return 'TRUNCATE '.$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ".implode("\n", $this->ar_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= ' AND ';
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Limit string
 	 *
 	 * Generates a platform-specific LIMIT clause
@@ -690,12 +472,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@mysql_close($conn_id);
+		@mysql_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index 11172b4..d22454d 100644
--- a/system/database/drivers/mysql/mysql_forge.php
+++ b/system/database/drivers/mysql/mysql_forge.php
@@ -34,31 +34,7 @@
  */
 class CI_DB_mysql_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _create_database($name)
-	{
-		return 'CREATE DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _drop_database($name)
-	{
-		return 'DROP DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s';
 
 	/**
 	 * Process Fields
@@ -84,8 +60,9 @@
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field)
-					.( ! empty($attributes['NAME']) ? ' '.$this->db->protect_identifiers($attributes['NAME']).' ' : '');
+				$sql .= "\n\t".$this->db->escape_identifiers($field);
+
+				empty($attributes['NAME']) OR ' '.$this->db->escape_identifiers($attributes['NAME']).' ';
 
 				if ( ! empty($attributes['TYPE']))
 				{
@@ -110,10 +87,23 @@
 					}
 				}
 
-				$sql .= (( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE) ? ' UNSIGNED' : '')
-					.(isset($attributes['DEFAULT']) ? " DEFAULT '".$attributes['DEFAULT']."'" : '')
-					.(( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL')
-					.(( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) ? ' AUTO_INCREMENT' : '');
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+
+				if (isset($attributes['DEFAULT']))
+				{
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
+				}
+
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
+
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
 			}
 
 			// don't add a comma on the end of the last field
@@ -138,7 +128,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -147,12 +137,12 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->protect_identifiers($table).' ('.$this->_process_fields($fields);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields);
 
 		if (count($primary_keys) > 0)
 		{
-			$key_name = $this->db->protect_identifiers(implode('_', $primary_keys));
-			$sql .= ",\n\tPRIMARY KEY ".$key_name.' ('.implode(', ', $this->db->protect_identifiers($primary_keys)).')';
+			$key_name = $this->db->escape_identifiers(implode('_', $primary_keys));
+			$sql .= ",\n\tPRIMARY KEY ".$key_name.' ('.implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
@@ -161,12 +151,12 @@
 			{
 				if (is_array($key))
 				{
-					$key_name = $this->db->protect_identifiers(implode('_', $key));
-					$key = $this->db->protect_identifiers($key);
+					$key_name = $this->db->escape_identifiers(implode('_', $key));
+					$key = $this->db->escape_identifiers($key);
 				}
 				else
 				{
-					$key_name = $this->db->protect_identifiers($key);
+					$key_name = $this->db->escape_identifiers($key);
 					$key = array($key_name);
 				}
 
@@ -180,19 +170,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @param	string	table name
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -204,34 +181,18 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
+		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' ';
 
 		// DROP has everything it needs now.
 		if ($alter_type === 'DROP')
 		{
-			return $sql.$this->db->protect_identifiers($fields);
+			return $sql.$this->db->escape_identifiers($fields);
 		}
 
 		return $sql.$this->_process_fields($fields)
-			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
+			.($after_field !== '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 	}
 
 }
diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php
index f76076f..14d6d07 100644
--- a/system/database/drivers/mysql/mysql_result.php
+++ b/system/database/drivers/mysql/mysql_result.php
@@ -128,7 +128,7 @@
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php
index 2d89cb9..f0bbc66 100644
--- a/system/database/drivers/mysql/mysql_utility.php
+++ b/system/database/drivers/mysql/mysql_utility.php
@@ -34,54 +34,17 @@
  */
 class CI_DB_mysql_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SHOW DATABASES';
-	}
+	protected $_list_databases	= 'SHOW DATABASES';
+	protected $_optimize_table	= 'OPTIMIZE TABLE %s';
+	protected $_repair_table	= 'REPAIR TABLE %s';
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'OPTIMIZE TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _repair_table($table)
-	{
-		return 'REPAIR TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
 	/**
 	 * MySQL Export
 	 *
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		if (count($params) === 0)
 		{
@@ -102,7 +65,7 @@
 			}
 
 			// Get the table schema
-			$query = $this->db->query('SHOW CREATE TABLE '.$this->db->protect_identifiers($this->db->database).'.'.$this->db->protect_identifiers($table));
+			$query = $this->db->query('SHOW CREATE TABLE '.$this->db->escape_identifiers($this->db->database.'.'.$table));
 
 			// No result means the table name was invalid
 			if ($query === FALSE)
@@ -113,7 +76,7 @@
 			// Write out the table schema
 			$output .= '#'.$newline.'# TABLE STRUCTURE FOR: '.$table.$newline.'#'.$newline.$newline;
 
-			if ($add_drop == TRUE)
+			if ($add_drop === TRUE)
 			{
 				$output .= 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table).';'.$newline.$newline;
 			}
@@ -129,7 +92,7 @@
 			}
 
 			// If inserts are not needed we're done...
-			if ($add_insert == FALSE)
+			if ($add_insert === FALSE)
 			{
 				continue;
 			}
@@ -137,7 +100,7 @@
 			// Grab all the data from the current table
 			$query = $this->db->query('SELECT * FROM '.$this->db->protect_identifiers($table));
 
-			if ($query->num_rows() == 0)
+			if ($query->num_rows() === 0)
 			{
 				continue;
 			}
@@ -157,7 +120,7 @@
 							TRUE);
 
 				// Create a string of field names
-				$field_str .= $this->db->protect_identifiers($field->name).', ';
+				$field_str .= $this->db->escape_identifiers($field->name).', ';
 				$i++;
 			}
 
@@ -180,7 +143,7 @@
 					else
 					{
 						// Escape the data if it's not an integer
-						$val_str .= ($is_int[$i] == FALSE) ? $this->db->escape($v) : $v;
+						$val_str .= ($is_int[$i] === FALSE) ? $this->db->escape($v) : $v;
 					}
 
 					// Append a comma
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 47b0449..d3fb77a 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -29,7 +29,7 @@
  * MySQLi Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -47,7 +47,7 @@
 
 	// clause and character used for LIKE escape sequences - not used in MySQL
 	protected $_like_escape_str = '';
-	protected $_like_escape_chr = '';
+	protected $_like_escape_chr = '\\';
 
 	/**
 	 * The syntax to count rows is slightly different across different
@@ -71,9 +71,9 @@
 	 */
 	public function db_connect()
 	{
-		return ($this->port != '')
-			? @new mysqli($this->hostname, $this->username, $this->password, $this->database, $this->port)
-			: @new mysqli($this->hostname, $this->username, $this->password, $this->database);
+		return empty($this->port)
+			? @new mysqli($this->hostname, $this->username, $this->password, $this->database)
+			: @new mysqli($this->hostname, $this->username, $this->password, $this->database, $this->port);
 	}
 
 	// --------------------------------------------------------------------
@@ -91,9 +91,9 @@
 			return $this->db_connect();
 		}
 
-		return ($this->port != '')
-			? @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database, $this->port)
-			: @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database);
+		return empty($this->port)
+			? @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database)
+			: @new mysqli('p:'.$this->hostname, $this->username, $this->password, $this->database, $this->port);
 	}
 
 	// --------------------------------------------------------------------
@@ -291,7 +291,9 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			return str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
 		}
 
 		return $str;
@@ -324,35 +326,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$query = $query->row();
-		$this->_reset_select();
-		return (int) $query->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * List table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -364,7 +337,7 @@
 	{
 		$sql = 'SHOW TABLES FROM '.$this->_escape_char.$this->database.$this->_escape_char;
 
-		if ($prefix_limit !== FALSE && $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix !== '')
 		{
 			return $sql." LIKE '".$this->escape_like_str($this->dbprefix)."%'";
 		}
@@ -397,7 +370,7 @@
 	 */
 	public function field_data($table = '')
 	{
-		if ($table == '')
+		if ($table === '')
 		{
 			return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
 		}
@@ -439,143 +412,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$item = str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$item = str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * From Tables
-	 *
-	 * This function implicitly groups FROM tables so there is no confusion
-	 * about operator precedence in harmony with SQL standards
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	protected function _from_tables($tables)
-	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return '('.implode(', ', $tables).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert_batch($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-
-	/**
-	 * Replace statement
-	 *
-	 * Generates a platform-specific replace string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _replace($table, $keys, $values)
-	{
-		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key.' = '.$val;
-		}
-
-		return 'UPDATE '.$table.' SET '.implode(', ', $valstr)
-			.(($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '')
-			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
-			.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
@@ -594,7 +430,7 @@
 
 			foreach (array_keys($val) as $field)
 			{
-				if ($field != $index)
+				if ($field !== $index)
 				{
 					$final[$field][] =  'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
 				}
@@ -609,62 +445,16 @@
 				.'ELSE '.$k.' END, ';
 		}
 
-		$where = ($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '';
+		$where = ($where !== '' && count($where) > 0) ? implode(' ', $where).' AND ' : '';
 
 		return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
-			.' WHERE '.(($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
+			.' WHERE '.(($where !== '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
 			.$index.' IN('.implode(',', $ids).')';
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Truncate statement
-	 *
-	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	protected function _truncate($table)
-	{
-		return 'TRUNCATE '.$table;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ".implode("\n", $this->ar_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= ' AND ';
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Limit string
 	 *
 	 * Generates a platform-specific LIMIT clause
@@ -685,13 +475,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	object
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
 		$this->conn_id->close();
-		$this->conn_id = FALSE;
 	}
 
 }
diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php
index 8cf0ae1..b74c775 100644
--- a/system/database/drivers/mysqli/mysqli_forge.php
+++ b/system/database/drivers/mysqli/mysqli_forge.php
@@ -34,31 +34,7 @@
  */
 class CI_DB_mysqli_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _create_database($name)
-	{
-		return 'CREATE DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _drop_database($name)
-	{
-		return 'DROP DATABASE '.$name;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s';
 
 	/**
 	 * Process Fields
@@ -84,13 +60,13 @@
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field)
-					.( ! empty($attributes['NAME']) ? ' '.$this->db->protect_identifiers($attributes['NAME']).' ' : '')
-				;
+				$sql .= "\n\t".$this->db->escape_identifiers($field);
+
+				empty($attributes['NAME']) OR $sql .= ' '.$this->db->escape_identifiers($attributes['NAME']).' ';
 
 				if ( ! empty($attributes['TYPE']))
 				{
-					$sql .=  ' '.$attributes['TYPE'];
+					$sql .= ' '.$attributes['TYPE'];
 
 					if ( ! empty($attributes['CONSTRAINT']))
 					{
@@ -111,10 +87,23 @@
 					}
 				}
 
-				$sql .= (( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE) ? ' UNSIGNED' : '')
-					.(isset($attributes['DEFAULT']) ? " DEFAULT '".$attributes['DEFAULT']."'" : '')
-					.(( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL')
-					.(( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE) ? ' AUTO_INCREMENT' : '');
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+
+				if (isset($attributes['DEFAULT']))
+				{
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
+				}
+
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
+
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
 			}
 
 			// don't add a comma on the end of the last field
@@ -139,7 +128,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -148,12 +137,12 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table).' ('.$this->_process_fields($fields);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields);
 
 		if (count($primary_keys) > 0)
 		{
-			$key_name = $this->db->protect_identifiers(implode('_', $primary_keys));
-			$sql .= ",\n\tPRIMARY KEY ".$key_name.' ('.implode(', ', $this->db->protect_identifiers($primary_keys)).')';
+			$key_name = $this->db->escape_identifiers(implode('_', $primary_keys));
+			$sql .= ",\n\tPRIMARY KEY ".$key_name.' ('.implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
@@ -162,12 +151,12 @@
 			{
 				if (is_array($key))
 				{
-					$key_name = $this->db->protect_identifiers(implode('_', $key));
-					$key = $this->db->protect_identifiers($key);
+					$key_name = $this->db->escape_identifiers(implode('_', $key));
+					$key = $this->db->escape_identifiers($key);
 				}
 				else
 				{
-					$key_name = $this->db->protect_identifiers($key);
+					$key_name = $this->db->escape_identifiers($key);
 					$key = array($key_name);
 				}
 
@@ -181,18 +170,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return 'DROP TABLE IF EXISTS '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -204,34 +181,18 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
+		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' ';
 
 		// DROP has everything it needs now.
 		if ($alter_type === 'DROP')
 		{
-			return $sql.$this->db->protect_identifiers($fields);
+			return $sql.$this->db->escape_identifiers($fields);
 		}
 
 		return $sql.$this->_process_fields($fields)
-			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
+			.($after_field !== '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 	}
 
 }
diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php
index cf03622..9b4d494 100644
--- a/system/database/drivers/mysqli/mysqli_result.php
+++ b/system/database/drivers/mysqli/mysqli_result.php
@@ -125,11 +125,11 @@
 	/**
 	 * Data Seek
 	 *
-	 * Moves the internal pointer to the desired offset.  We call
+	 * Moves the internal pointer to the desired offset. We call
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php
index 4d7002e..27d4ef8 100644
--- a/system/database/drivers/mysqli/mysqli_utility.php
+++ b/system/database/drivers/mysqli/mysqli_utility.php
@@ -34,47 +34,9 @@
  */
 class CI_DB_mysqli_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SHOW DATABASES';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'OPTIMIZE TABLE '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _repair_table($table)
-	{
-		return 'REPAIR TABLE '.$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SHOW DATABASES';
+	protected $_optimize_table	= 'OPTIMIZE TABLE %s';
+	protected $_repair_table	= 'REPAIR TABLE %s';
 
 	/**
 	 * MySQLi Export
@@ -82,7 +44,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 3bc8c11..e780916 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -29,7 +29,7 @@
  * oci8 Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -46,7 +46,6 @@
  * permit access to oracle databases
  *
  * @author	  Kelly McArdle
- *
  */
 class CI_DB_oci8_driver extends CI_DB {
 
@@ -68,7 +67,7 @@
 	protected $_random_keyword = ' ASC'; // not currently supported
 
 	// Set "auto commit" by default
-	protected $_commit = OCI_COMMIT_ON_SUCCESS;
+	public $commit_mode = OCI_COMMIT_ON_SUCCESS;
 
 	// need to track statement id and cursor id
 	public $stmt_id;
@@ -186,19 +185,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @return	resource
-	 */
-	public function db_select()
-	{
-		// Not in Oracle - schemas are actually usernames
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -220,12 +206,13 @@
 	 */
 	protected function _execute($sql)
 	{
-		// oracle must parse the query before it is run. All of the actions with
-		// the query are based on the statement id returned by ociparse
+		/* Oracle must parse the query before it is run. All of the actions with
+		 * the query are based on the statement id returned by oci_parse().
+		 */
 		$this->stmt_id = FALSE;
 		$this->_set_stmt_id($sql);
 		oci_set_prefetch($this->stmt_id, 1000);
-		return @oci_execute($this->stmt_id, $this->_commit);
+		return @oci_execute($this->stmt_id, $this->commit_mode);
 	}
 
 	/**
@@ -251,8 +238,7 @@
 	 */
 	public function get_cursor()
 	{
-		$this->curs_id = oci_new_cursor($this->conn_id);
-		return $this->curs_id;
+		return $this->curs_id = oci_new_cursor($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -260,23 +246,23 @@
 	/**
 	 * Stored Procedure.  Executes a stored procedure
 	 *
-	 * @param	string	package stored procedure is in
-	 * @param	string	stored procedure to execute
+	 * @param	string	package name in which the stored procedure is in
+	 * @param	string	stored procedure name to execute
 	 * @param	array	parameters
-	 * @return	object
+	 * @return	mixed
 	 *
 	 * params array keys
 	 *
 	 * KEY	  OPTIONAL	NOTES
-	 * name		no		the name of the parameter should be in :<param_name> format
-	 * value	no		the value of the parameter.  If this is an OUT or IN OUT parameter,
-	 *					this should be a reference to a variable
-	 * type		yes		the type of the parameter
-	 * length	yes		the max size of the parameter
+	 * name		no	the name of the parameter should be in :<param_name> format
+	 * value	no	the value of the parameter.  If this is an OUT or IN OUT parameter,
+	 *				this should be a reference to a variable
+	 * type		yes	the type of the parameter
+	 * length	yes	the max size of the parameter
 	 */
 	public function stored_procedure($package, $procedure, $params)
 	{
-		if ($package == '' OR $procedure == '' OR ! is_array($params))
+		if ($package === '' OR $procedure === '' OR ! is_array($params))
 		{
 			if ($this->db_debug)
 			{
@@ -287,24 +273,24 @@
 		}
 
 		// build the query string
-		$sql = "begin $package.$procedure(";
+		$sql = 'BEGIN '.$package.'.'.$procedure.'(';
 
 		$have_cursor = FALSE;
 		foreach ($params as $param)
 		{
-			$sql .= $param['name'] . ",";
+			$sql .= $param['name'].',';
 
-			if (array_key_exists('type', $param) && ($param['type'] === OCI_B_CURSOR))
+			if (isset($param['type']) && $param['type'] === OCI_B_CURSOR)
 			{
 				$have_cursor = TRUE;
 			}
 		}
-		$sql = trim($sql, ",") . "); end;";
+		$sql = trim($sql, ',') . '); END;';
 
 		$this->stmt_id = FALSE;
 		$this->_set_stmt_id($sql);
 		$this->_bind_params($params);
-		$this->query($sql, FALSE, $have_cursor);
+		return $this->query($sql, FALSE, $have_cursor);
 	}
 
 	// --------------------------------------------------------------------
@@ -360,7 +346,7 @@
 		// even if the queries produce a successful result.
 		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
 
-		$this->_commit = OCI_DEFAULT;
+		$this->commit_mode = (is_php('5.3.2')) ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT;
 		return TRUE;
 	}
 
@@ -384,9 +370,8 @@
 			return TRUE;
 		}
 
-		$ret = oci_commit($this->conn_id);
-		$this->_commit = OCI_COMMIT_ON_SUCCESS;
-		return $ret;
+		$this->commit_mode = OCI_COMMIT_ON_SUCCESS;
+		return oci_commit($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -398,20 +383,14 @@
 	 */
 	public function trans_rollback()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
 
-		$ret = oci_rollback($this->conn_id);
-		$this->_commit = OCI_COMMIT_ON_SUCCESS;
-		return $ret;
+		$this->commit_mode = OCI_COMMIT_ON_SUCCESS;
+		return oci_rollback($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -476,35 +455,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
-		if ($query == FALSE)
-		{
-			return 0;
-		}
-
-		$row = $query->row();
-		$this->_reset_select();
-		return (int) $row->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Show table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -514,11 +464,11 @@
 	 */
 	protected function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = "SELECT TABLE_NAME FROM ALL_TABLES";
+		$sql = 'SELECT TABLE_NAME FROM ALL_TABLES';
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix !== '')
 		{
-			$sql .= " WHERE TABLE_NAME LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
+			return $sql." WHERE TABLE_NAME LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 		}
 
 		return $sql;
@@ -536,7 +486,7 @@
 	 */
 	protected function _list_columns($table = '')
 	{
-		return "SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = '$table'";
+		return 'SELECT COLUMN_NAME FROM all_tab_columns WHERE table_name = \''.$table.'\'';
 	}
 
 	// --------------------------------------------------------------------
@@ -551,7 +501,7 @@
 	 */
 	protected function _field_data($table)
 	{
-		return "SELECT * FROM ".$table." where rownum = 1";
+		return 'SELECT * FROM '.$table.' WHERE rownum = 1';
 	}
 
 	// --------------------------------------------------------------------
@@ -588,47 +538,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
@@ -639,29 +548,7 @@
 	 */
 	protected function _from_tables($tables)
 	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return implode(', ', $tables);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return is_array($tables) ? implode(', ', $tables) : $tables;
 	}
 
 	// --------------------------------------------------------------------
@@ -683,46 +570,10 @@
 
 		for ($i = 0, $c = count($values); $i < $c; $i++)
 		{
-			$sql .= '	INTO ' . $table . ' (' . $keys . ') VALUES ' . $values[$i] . "\n";
+			$sql .= '	INTO '.$table.' ('.$keys.') VALUES '.$values[$i]."\n";
 		}
 
-		$sql .= 'SELECT * FROM dual';
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key." = ".$val;
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
+		return $sql.'SELECT * FROM dual';
 	}
 
 	// --------------------------------------------------------------------
@@ -731,15 +582,16 @@
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
 	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return "TRUNCATE TABLE ".$table;
+		return 'TRUNCATE TABLE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -751,28 +603,19 @@
 	 *
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
 	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
+		empty($limit) OR $conditions[] = 'rownum <= '.$limit;
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -789,18 +632,9 @@
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		$limit = $offset + $limit;
-		$newsql = "SELECT * FROM (select inner_query.*, rownum rnum FROM ($sql) inner_query WHERE rownum < $limit)";
-
-		if ($offset != 0)
-		{
-			$newsql .= " WHERE rnum >= $offset";
-		}
-
-		// remember that we used limits
 		$this->limit_used = TRUE;
-
-		return $newsql;
+		return 'SELECT * FROM (SELECT inner_query.*, rownum rnum FROM ('.$sql.') inner_query WHERE rownum < '.($offset + $limit).')'
+			.($offset !== 0 ? ' WHERE rnum >= '.$offset : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -808,12 +642,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@oci_close($conn_id);
+		@oci_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php
index 8285a29..92e8c02 100644
--- a/system/database/drivers/oci8/oci8_forge.php
+++ b/system/database/drivers/oci8/oci8_forge.php
@@ -34,31 +34,9 @@
  */
 class CI_DB_oci8_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _create_database($name)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _drop_database($name)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_create_database	= FALSE;
+	protected $_drop_database	= FALSE;
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
@@ -68,9 +46,9 @@
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
-	 * @return	bool
+	 * @return	string
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -79,7 +57,7 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table).' (';
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
 		foreach ($fields as $field => $attributes)
@@ -95,11 +73,22 @@
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field).' '.$attributes['TYPE']
-					.((isset($attributes['UNSINGED']) && $attributes['UNSIGNED'] === TRUE) ? ' UNSIGNED' : '')
-					.(isset($attributes['DEFAULT']) ? " DEFAULT '".$attributes['DEFAULT']."'" : '')
-					.((isset($attributes['NULL']) && $attributes['NULL'] === TRUE) ? '' : ' NOT NULL')
-					.(isset($attributes['CONSTRAINT']) ? ' CONSTRAINT '.$attributes['CONSTRAINT'] : '');
+				$sql .= "\n\t".$this->db->escape_identifiers($field).' '.$attributes['TYPE'];
+
+				if (isset($attributes['UNSINGED']) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+
+				if (isset($attributes['DEFAULT']))
+				{
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
+				}
+
+				$sql .= (isset($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? '' : ' NOT NULL';
+
+				empty($attributes['CONSTRAINT']) OR ' CONSTRAINT '.$attributes['CONSTRAINT'];
 			}
 
 			// don't add a comma on the end of the last field
@@ -111,24 +100,18 @@
 
 		if (count($primary_keys) > 0)
 		{
-			$primary_keys = $this->db->protect_identifiers($primary_keys);
-			$sql .= ",\n\tCONSTRAINT ".$table.' PRIMARY KEY ('.implode(', ', $primary_keys).')';
+			$sql .= ",\n\tCONSTRAINT ".$table.' PRIMARY KEY ('.implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
 		{
 			foreach ($keys as $key)
 			{
-				if (is_array($key))
-				{
-					$key = $this->db->protect_identifiers($key);
-				}
-				else
-				{
-					$key = array($this->db->protect_identifiers($key));
-				}
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->db->escape_identifiers($key));
 
-				$sql .= ",\n\tUNIQUE COLUMNS (".implode(', ', $key).")";
+				$sql .= ",\n\tUNIQUE COLUMNS (".implode(', ', $key).')';
 			}
 		}
 
@@ -138,18 +121,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @return	bool
-	 */
-	public function _drop_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -164,55 +135,21 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
+		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' '.$this->db->escape_identifiers($column_name);
 
 		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		if ($alter_type === 'DROP')
 		{
 			return $sql;
 		}
 
-		$sql .= " $column_definition";
+		return $sql.' '.$column_definition
+			.($default_value !== '' ? ' DEFAULT "'.$default_value.'"' : '')
+			.($null === NULL ? ' NULL' : ' NOT NULL')
+			.($after_field !== '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
 	}
 
 }
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index c3f7757..6fb6c81 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -39,6 +39,12 @@
 	public $stmt_id;
 	public $curs_id;
 	public $limit_used;
+	public $commit_mode;
+
+	/* Overwriting the parent here, so we have a way to know if it's
+	 * already called or not:
+	 */
+	public $num_rows;
 
 	public function __construct(&$driver_object)
 	{
@@ -46,28 +52,32 @@
 		$this->stmt_id = $driver_object->stmt_id;
 		$this->curs_id = $driver_object->curs_id;
 		$this->limit_used = $driver_object->limit_used;
+		$this->commit_mode =& $driver_object->commit_mode;
 		$driver_object->stmt_id = FALSE;
 	}
 
 	/**
 	 * Number of rows in the result set.
 	 *
-	 * Oracle doesn't have a graceful way to retun the number of rows
+	 * Oracle doesn't have a graceful way to return the number of rows
 	 * so we have to use what amounts to a hack.
 	 *
 	 * @return	int
 	 */
 	public function num_rows()
 	{
-		if ($this->num_rows === 0 && count($this->result_array()) > 0)
+		if ( ! is_int($this->num_rows))
 		{
-			$this->num_rows = count($this->result_array());
-			@oci_execute($this->stmt_id, OCI_DEFAULT);
-
-			if ($this->curs_id)
+			if (count($this->result_array) > 0)
 			{
-				@oci_execute($this->curs_id, OCI_DEFAULT);
+				return $this->num_rows = count($this->result_array);
 			}
+			elseif (count($this->result_object) > 0)
+			{
+				return $this->num_rows = count($this->result_object);
+			}
+
+			return $this->num_rows = count($this->result_array());
 		}
 
 		return $this->num_rows;
@@ -85,12 +95,7 @@
 		$count = @oci_num_fields($this->stmt_id);
 
 		// if we used a limit we subtract it
-		if ($this->limit_used)
-		{
-			$count = $count - 1;
-		}
-
-		return $count;
+		return ($this->limit_used) ? $count - 1 : $count;
 	}
 
 	// --------------------------------------------------------------------
@@ -126,10 +131,10 @@
 		$retval = array();
 		for ($c = 1, $fieldCount = $this->num_fields(); $c <= $fieldCount; $c++)
 		{
-			$F			= new stdClass();
-			$F->name		= oci_field_name($this->stmt_id, $c);
-			$F->type		= oci_field_type($this->stmt_id, $c);
-			$F->max_length		= oci_field_size($this->stmt_id, $c);
+			$F		= new stdClass();
+			$F->name	= oci_field_name($this->stmt_id, $c);
+			$F->type	= oci_field_type($this->stmt_id, $c);
+			$F->max_length	= oci_field_size($this->stmt_id, $c);
 
 			$retval[] = $F;
 		}
@@ -151,6 +156,17 @@
 			oci_free_statement($this->result_id);
 			$this->result_id = FALSE;
 		}
+
+		if (is_resource($this->stmt_id))
+		{
+			oci_free_statement($this->stmt_id);
+		}
+
+		if (is_resource($this->curs_id))
+		{
+			oci_cancel($this->curs_id);
+			$this->curs_id = NULL;
+		}
 	}
 
 	// --------------------------------------------------------------------
@@ -180,13 +196,13 @@
 	protected function _fetch_object()
 	{
 		$id = ($this->curs_id) ? $this->curs_id : $this->stmt_id;
-		return @oci_fetch_object($id);
+		return oci_fetch_object($id);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Query result.  "array" version.
+	 * Query result. Array version.
 	 *
 	 * @return	array
 	 */
@@ -196,14 +212,429 @@
 		{
 			return $this->result_array;
 		}
+		elseif (count($this->result_object) > 0)
+		{
+			for ($i = 0, $c = count($this->result_object); $i < $c; $i++)
+			{
+				$this->result_array[$i] = (array) $this->result_object[$i];
+			}
+
+			return $this->result_array;
+		}
+		elseif (is_array($this->row_data))
+		{
+			if (count($this->row_data) === 0)
+			{
+				return $this->result_array;
+			}
+			else
+			{
+				$row_index = count($this->row_data);
+			}
+		}
+		else
+		{
+			$row_index = 0;
+			$this->row_data = array();
+		}
 
 		$row = NULL;
 		while ($row = $this->_fetch_assoc())
 		{
-			$this->result_array[] = $row;
+			$this->row_data[$row_index++] = $row;
 		}
 
-		return $this->result_array;
+		return $this->result_array = $this->row_data;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. "object" version.
+	 *
+	 * @return	array
+	 */
+	public function result_object()
+	{
+		if (count($this->result_object) > 0)
+		{
+			return $this->result_object;
+		}
+		elseif (count($this->result_array) > 0)
+		{
+			for ($i = 0, $c = count($this->result_array); $i < $c; $i++)
+			{
+				$this->result_object[] = (object) $this->result_array[$i];
+			}
+
+			return $this->result_object;
+		}
+		elseif (is_array($this->row_data))
+		{
+			if (count($this->row_data) === 0)
+			{
+				return $this->result_object;
+			}
+			else
+			{
+				$row_index = count($this->row_data);
+				for ($i = 0; $i < $row_index; $i++)
+				{
+					$this->result_object[$i] = (object) $this->row_data[$i];
+				}
+			}
+		}
+		else
+		{
+			$row_index = 0;
+			$this->row_data = array();
+		}
+
+		$row = NULL;
+		while ($row = $this->_fetch_object())
+		{
+			$this->row_data[$row_index] = (array) $row;
+			$this->result_object[$row_index++] = $row;
+		}
+
+		return $this->result_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. Custom object version.
+	 *
+	 * @param	string	class name used to instantiate rows to
+	 * @return	array
+	 */
+	public function custom_result_object($class_name)
+	{
+		if (isset($this->custom_result_object[$class_name]))
+		{
+			return $this->custom_result_object[$class_name];
+		}
+
+		if ( ! class_exists($class_name) OR $this->result_id === FALSE OR $this->num_rows() === 0)
+		{
+			return array();
+		}
+
+		/* Even if we didn't have result_array or result_object
+		 * set prior to custom_result_object() being called,
+		 * num_rows() has already done so.
+		 * Pass by reference, as we don't know how
+		 * large it might be and we don't want 1000 row
+		 * sets being copied.
+		 */
+		if (count($this->result_array) > 0)
+		{
+			$data = &$this->result_array;
+		}
+		elseif (count($this->result_object) > 0)
+		{
+			$data = &$this->result_object;
+		}
+
+		$this->custom_result_object[$class_name] = array();
+		for ($i = 0, $c = count($data); $i < $c; $i++)
+		{
+			$this->custom_result_object[$class_name][$i] = new $class_name();
+			foreach ($data[$i] as $key => $value)
+			{
+				$this->custom_result_object[$class_name][$i]->$key = $value;
+			}
+		}
+
+		return $this->custom_result_object[$class_name];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result.
+	 *
+	 * Acts as a wrapper for row_object(), row_array()
+	 * and custom_row_object(). Also used by first_row(), next_row()
+	 * and previous_row().
+	 *
+	 * @param	int	row index
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function row($n = 0, $type = 'object')
+	{
+		if ($type === 'object')
+		{
+			return $this->row_object($n);
+		}
+		elseif ($type === 'array')
+		{
+			return $this->row_array($n);
+		}
+
+		return $this->custom_row_object($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Array version.
+	 *
+	 * @param	int	row index
+	 * @return	array
+	 */
+	public function row_array($n = 0)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		/* If row_data is initialized, it means that we've already tried
+		 * (at least) to fetch some data, so ... check if we already have
+		 * this row.
+		*/
+		if (is_array($this->row_data))
+		{
+			/* If we already have row_data[$n] - return it.
+			 *
+			 * If we enter the elseif, there's a number of reasons to
+			 * return an empty array:
+			 *
+			 *	- count($this->row_data) === 0 means there are no results
+			 *	- num_rows being set, result_array and/or result_object
+			 *	  having count() > 0 means that we've already fetched all
+			 *	  data and $n is greater than our highest row index available
+			 *	- $n < $this->current_row means that if such row existed,
+			 *	  we would've already returned it, therefore $n is an
+			 *	  invalid index
+			 */
+			if (isset($this->row_data[$n])) // We already have this row
+			{
+				$this->current_row = $n;
+				return $this->row_data[$n];
+			}
+			elseif (count($this->row_data) === 0 OR is_int($this->num_rows)
+				OR count($this->result_array) > 0 OR count($this->result_object) > 0
+				OR $n < $this->current_row)
+			{
+				// No such row exists
+				return NULL;
+			}
+
+			// Get the next row index that would actually need to be fetched
+			$current_row = ($this->current_row < count($this->row_data)) ? count($this->row_data) : $this->current_row + 1;
+		}
+		else
+		{
+			$current_row = $this->current_row = 0;
+			$this->row_data = array();
+		}
+
+		/* Fetch more data, if available
+		 *
+		 * NOTE: Operator precedence is important here, if you change
+		 *	 'AND' with '&&' - it WILL BREAK the results, as
+		 *	 $row will be assigned the scalar value of both
+		 *	 expressions!
+		 */
+		while ($row = $this->_fetch_assoc() AND $current_row <= $n)
+		{
+			$this->row_data[$current_row++] = $row;
+		}
+
+		// This would mean that there's no (more) data to fetch
+		if ( ! is_array($this->row_data) OR ! isset($this->row_data[$n]))
+		{
+			// Cache what we already have
+			if (is_array($this->row_data))
+			{
+				$this->num_rows = count($this->row_data);
+				/* Usually, row_data could have less elements than result_array,
+				 * but at this point - they should be exactly the same.
+				 */
+				$this->result_array = $this->row_data;
+			}
+			else
+			{
+				$this->num_rows = 0;
+			}
+
+			return NULL;
+		}
+
+		$this->current_row = $n;
+		return $this->row_data[$n];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Object version.
+	 *
+	 * @param	int	row index
+	 * @return	mixed	object if row found; empty array if not
+	 */
+	public function row_object($n = 0)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+		/* Logic here is exactly the same as in row_array,
+		 * except we have to cast row_data[$n] to an object.
+		 *
+		 * If we already have result_object though - we can
+		 * directly return from it.
+		 */
+		if (isset($this->result_object[$n]))
+		{
+			$this->current_row = $n;
+			// Set this, if not already done.
+			if ( ! is_int($this->num_rows))
+			{
+				$this->num_rows = count($this->result_object);
+			}
+
+			return $this->result_object[$n];
+		}
+
+		$row = $this->row_array($n);
+		// Cast only if the row exists
+		if (count($row) > 0)
+		{
+			$this->current_row = $n;
+			return (object) $row;
+		}
+
+		return NULL;
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Custom object version.
+	 *
+	 * @param	int	row index
+	 * @param	string	custom class name
+	 * @return	mixed	custom object if row found; empty array otherwise
+	 */
+	public function custom_row_object($n = 0, $class_name)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		if (array_key_exists($class_name, $this->custom_result_object))
+		{
+			/* We already have a the whole result set with this class_name,
+			 * return the specified row if it exists, and an empty array if
+			 * it doesn't.
+			 */
+			if (isset($this->custom_result_object[$class_name][$n]))
+			{
+				$this->current_row = $n;
+				return $this->custom_result_object[$class_name][$n];
+			}
+			else
+			{
+				return NULL;
+			}
+		}
+		elseif ( ! class_exists($class_name)) // No such class exists
+		{
+			return NULL;
+		}
+
+		$row = $this->row_array($n);
+		// A non-array would mean that the row doesn't exist
+		if ( ! is_array($row))
+		{
+			return NULL;
+		}
+
+		// Convert to the desired class and return
+		$row_object = new $class_name();
+		foreach ($row as $key => $value)
+		{
+			$row_object->$key = $value;
+		}
+
+		$this->current_row = $n;
+		return $row_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/* First row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function first_row($type = 'object')
+	{
+		return $this->row(0, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Last row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function last_row($type = 'object')
+	{
+		$result = &$this->result($type);
+		if ( ! isset($this->num_rows))
+		{
+			$this->num_rows = count($result);
+		}
+		$this->current_row = $this->num_rows - 1;
+		return $result[$this->current_row];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Next row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function next_row($type = 'object')
+	{
+		if (is_array($this->row_data))
+		{
+			$count = count($this->row_data);
+			if ($this->current_row > $count OR ($this->current_row === 0 && $count === 0))
+			{
+				$n = $count;
+			}
+			else
+			{
+				$n = $this->current_row + 1;
+			}
+		}
+		else
+		{
+			$n = 0;
+		}
+
+		return $this->row($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Previous row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function previous_row($type = 'object')
+	{
+		$n = ($this->current_row !== 0) ? $this->current_row - 1 : 0;
+		return $this->row($n, $type);
 	}
 
 	// --------------------------------------------------------------------
@@ -213,13 +644,54 @@
 	 *
 	 * Moves the internal pointer to the desired offset. We call
 	 * this internally before fetching results to make sure the
-	 * result set starts at zero
+	 * result set starts at zero.
 	 *
-	 * @return	array
+	 * Oracle's PHP extension doesn't have an easy way of doing this
+	 * and the only workaround is to (re)execute the statement or cursor
+	 * in order to go to the first (zero) index of the result set.
+	 * Then, we would need to "dummy" fetch ($n - 1) rows to get to the
+	 * right one.
+	 *
+	 * This is as ridiculous as it sounds and it's the reason why every
+	 * other method that is fetching data tries to use an already "cached"
+	 * result set. Keeping this just in case it becomes needed at
+	 * some point in the future, but it will only work for resetting the
+	 * pointer to zero.
+	 *
+	 * @return	bool
 	 */
-	protected function _data_seek($n = 0)
+	protected function _data_seek()
 	{
-		return FALSE; // Not needed
+		/* The PHP manual says that if OCI_NO_AUTO_COMMIT mode
+		 * is used, and oci_rollback() and/or oci_commit() are
+		 * not subsequently called - this will cause an unnecessary
+		 * rollback to be triggered at the end of the script execution.
+		 *
+		 * Therefore we'll try to avoid using that mode flag
+		 * if we're not currently in the middle of a transaction.
+		 */
+		if ($this->commit_mode !== OCI_COMMIT_ON_SUCCESS)
+		{
+			$result = @oci_execute($this->stmt_id, $this->commit_mode);
+		}
+		else
+		{
+			$result = @oci_execute($this->stmt_id);
+		}
+
+		if ($result && $this->curs_id)
+		{
+			if ($this->commit_mode !== OCI_COMMIT_ON_SUCCESS)
+			{
+				return @oci_execute($this->curs_id, $this->commit_mode);
+			}
+			else
+			{
+				return @oci_execute($this->curs_id);
+			}
+		}
+
+		return $result;
 	}
 
 }
diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php
index e303fb6..0183eda 100644
--- a/system/database/drivers/oci8/oci8_utility.php
+++ b/system/database/drivers/oci8/oci8_utility.php
@@ -34,47 +34,7 @@
  */
 class CI_DB_oci8_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in Oracle?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE; // Is this supported in Oracle?
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SELECT username FROM dba_users'; // Schemas are actual usernames
 
 	/**
 	 * Oracle Export
@@ -82,7 +42,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index ad77311..222c311 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -29,7 +29,7 @@
  * ODBC Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -64,7 +64,7 @@
 		$this->_random_keyword = ' RND('.time().')'; // database specific random keyword
 
 		// Legacy support for DSN in the hostname field
-		if ($this->dsn == '')
+		if (empty($this->dsn))
 		{
 			$this->dsn = $this->hostname;
 		}
@@ -95,19 +95,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @return	resource
-	 */
-	public function db_select()
-	{
-		// Not needed for ODBC
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Execute the query
 	 *
 	 * @param	string	an SQL query
@@ -127,13 +114,8 @@
 	 */
 	public function trans_begin($test_mode = FALSE)
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -141,7 +123,7 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+		$this->_trans_failure = ($test_mode === TRUE);
 
 		return odbc_autocommit($this->conn_id, FALSE);
 	}
@@ -155,13 +137,8 @@
 	 */
 	public function trans_commit()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -180,13 +157,8 @@
 	 */
 	public function trans_rollback()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -217,7 +189,6 @@
 			return $str;
 		}
 
-		// ODBC doesn't require escaping
 		$str = remove_invisible_characters($str);
 
 		// escape LIKE condition wildcards
@@ -258,36 +229,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string . $this->protect_identifiers('numrows') . " FROM " . $this->protect_identifiers($table, TRUE, NULL, FALSE));
-
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$row = $query->row();
-		$this->_reset_select();
-		return (int) $row->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Show table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -297,9 +238,9 @@
 	 */
 	protected function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = "SHOW TABLES FROM `".$this->database."`";
+		$sql = 'SHOW TABLES FROM '.$this->database;
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix !== '')
 		{
 			//$sql .= " LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 			return FALSE; // not currently supported
@@ -320,7 +261,7 @@
 	 */
 	protected function _list_columns($table = '')
 	{
-		return "SHOW COLUMNS FROM ".$table;
+		return 'SHOW COLUMNS FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -335,7 +276,7 @@
 	 */
 	protected function _field_data($table)
 	{
-		return "SELECT TOP 1 FROM ".$table;
+		return 'SELECT TOP 1 FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -356,47 +297,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
@@ -407,114 +307,25 @@
 	 */
 	protected function _from_tables($tables)
 	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return '('.implode(', ', $tables).')';
+		return is_array($tables) ? implode(', ', $tables) : $tables;
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key." = ".$val;
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
 	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -531,8 +342,7 @@
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		// Does ODBC doesn't use the LIMIT clause?
-		return $sql;
+		return $sql.($offset == 0 ? '' : $offset.', ').$limit;
 	}
 
 	// --------------------------------------------------------------------
@@ -540,12 +350,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@odbc_close($conn_id);
+		@odbc_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php
index 486a8dd..b074c58 100644
--- a/system/database/drivers/odbc/odbc_forge.php
+++ b/system/database/drivers/odbc/odbc_forge.php
@@ -34,43 +34,8 @@
  */
 class CI_DB_odbc_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _create_database()
-	{
-		// ODBC has no "create database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _drop_database($name)
-	{
-		// ODBC has no "drop database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_database	= 'DROP DATABASE %s';
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
@@ -82,7 +47,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -91,7 +56,7 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
 		foreach ($fields as $field => $attributes)
@@ -101,41 +66,30 @@
 			// entered the field information, so we'll simply add it to the list
 			if (is_numeric($field))
 			{
-				$sql .= "\n\t$attributes";
+				$sql .= "\n\t".$attributes;
 			}
 			else
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field);
+				$sql .= "\n\t".$this->db->escape_identifiers($field).' '.$attributes['TYPE'];
 
-				$sql .=  ' '.$attributes['TYPE'];
+				empty($attributes['CONSTRAINT']) OR $sql .= '('.$attributes['CONSTRAINT'].')';
 
-				if (array_key_exists('CONSTRAINT', $attributes))
-				{
-					$sql .= '('.$attributes['CONSTRAINT'].')';
-				}
-
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
 				{
 					$sql .= ' UNSIGNED';
 				}
 
-				if (array_key_exists('DEFAULT', $attributes))
+				if (isset($attributes['DEFAULT']))
 				{
-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
 				}
 
-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
-				{
-					$sql .= ' NULL';
-				}
-				else
-				{
-					$sql .= ' NOT NULL';
-				}
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
 
-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
 				{
 					$sql .= ' AUTO_INCREMENT';
 				}
@@ -150,47 +104,22 @@
 
 		if (count($primary_keys) > 0)
 		{
-			$primary_keys = $this->db->protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $this->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
 		{
 			foreach ($keys as $key)
 			{
-				if (is_array($key))
-				{
-					$key = $this->db->protect_identifiers($key);
-				}
-				else
-				{
-					$key = array($this->db->protect_identifiers($key));
-				}
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->db->escape_identifiers($key));
 
-				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tFOREIGN KEY (".implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n)";
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @return	bool
-	 */
-	public function _drop_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
+		return $sql."\n)";
 	}
 
 	// --------------------------------------------------------------------
@@ -210,56 +139,20 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
+		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' '.$this->db->escape_identifiers($column_name);
 
 		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		if ($alter_type === 'DROP')
 		{
 			return $sql;
 		}
 
-		$sql .= " $column_definition";
-
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
-
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
+		return $sql.' '.$column_definition
+			.($default_value != '' ? ' DEFAULT "'.$default_value.'"' : '')
+			.($null === NULL ? ' NULL' : ' NOT NULL')
+			.($after_field != '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 	}
 
 }
diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php
index 30cc979..227fe4f 100644
--- a/system/database/drivers/odbc/odbc_result.php
+++ b/system/database/drivers/odbc/odbc_result.php
@@ -59,8 +59,6 @@
 		return $this->num_rows;
 	}
 
-	// --------------------------------------------------------------------
-
 	/**
 	 * Number of fields in the result set
 	 *
@@ -140,22 +138,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset.  We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @return	bool
-	 */
-	protected function _data_seek($n = 0)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
@@ -164,14 +146,9 @@
 	 */
 	protected function _fetch_assoc()
 	{
-		if (function_exists('odbc_fetch_array'))
-		{
-			return odbc_fetch_array($this->result_id);
-		}
-		else
-		{
-			return $this->_odbc_fetch_array($this->result_id);
-		}
+		return function_exists('odbc_fetch_array')
+			? odbc_fetch_array($this->result_id)
+			: $this->_odbc_fetch_array($this->result_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -185,14 +162,9 @@
 	 */
 	protected function _fetch_object()
 	{
-		if (function_exists('odbc_fetch_object'))
-		{
-			return odbc_fetch_object($this->result_id);
-		}
-		else
-		{
-			return $this->_odbc_fetch_object($this->result_id);
-		}
+		return function_exists('odbc_fetch_object')
+			? odbc_fetch_object($this->result_id)
+			: $this->_odbc_fetch_object($this->result_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -208,15 +180,18 @@
 	protected function _odbc_fetch_object(& $odbc_result)
 	{
 		$rs = array();
-		$rs_obj = FALSE;
-		if (odbc_fetch_into($odbc_result, $rs))
+		if ( ! odbc_fetch_into($odbc_result, $rs))
 		{
-			foreach ($rs as $k => $v)
-			{
-				$field_name = odbc_field_name($odbc_result, $k+1);
-				$rs_obj->$field_name = $v;
-			}
+			return FALSE;
 		}
+
+		$rs_obj = new stdClass();
+		foreach ($rs as $k => $v)
+		{
+			$field_name = odbc_field_name($odbc_result, $k+1);
+			$rs_obj->$field_name = $v;
+		}
+
 		return $rs_obj;
 	}
 
@@ -233,16 +208,18 @@
 	protected function _odbc_fetch_array(& $odbc_result)
 	{
 		$rs = array();
-		$rs_assoc = FALSE;
-		if (odbc_fetch_into($odbc_result, $rs))
+		if ( ! odbc_fetch_into($odbc_result, $rs))
 		{
-			$rs_assoc = array();
-			foreach ($rs as $k => $v)
-			{
-				$field_name = odbc_field_name($odbc_result, $k+1);
-				$rs_assoc[$field_name] = $v;
-			}
+			return FALSE;
 		}
+
+		$rs_assoc = array();
+		foreach ($rs as $k => $v)
+		{
+			$field_name = odbc_field_name($odbc_result, $k+1);
+			$rs_assoc[$field_name] = $v;
+		}
+
 		return $rs_assoc;
 	}
 
diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php
index 65445e9..224d48d 100644
--- a/system/database/drivers/odbc/odbc_utility.php
+++ b/system/database/drivers/odbc/odbc_utility.php
@@ -34,62 +34,7 @@
  */
 class CI_DB_odbc_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		// Not sure if ODBC lets you list all databases...
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _optimize_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		// Not a supported ODBC feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * ODBC Export
@@ -97,7 +42,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index f336eb0..e25013a 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_driver.php
@@ -29,7 +29,7 @@
  * PDO Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -46,8 +46,8 @@
 	protected $_escape_char = '';
 
 	// clause and character used for LIKE escape sequences
-	protected $_like_escape_str;
-	protected $_like_escape_chr;
+	protected $_like_escape_str = " ESCAPE '%s' ";
+	protected $_like_escape_chr = '!';
 
 	/**
 	 * The syntax to count rows is slightly different across different
@@ -65,7 +65,7 @@
 	{
 		parent::__construct($params);
 
-		if (preg_match('/([^;]+):/', $this->dsn, $match) && count($match) == 2)
+		if (preg_match('/([^;]+):/', $this->dsn, $match) && count($match) === 2)
 		{
 			// If there is a minimum valid dsn string pattern found, we're done
 			// This is for general PDO users, who tend to have a full DSN string.
@@ -79,20 +79,19 @@
 
 		// clause and character used for LIKE escape sequences
 		// this one depends on the driver being used
-		if ($this->pdodriver == 'mysql')
+		if ($this->pdodriver === 'mysql')
 		{
+			$this->_escape_char = '`';
 			$this->_like_escape_str = '';
-			$this->_like_escape_chr = '';
+			$this->_like_escape_chr = '\\';
 		}
-		elseif ($this->pdodriver == 'odbc')
+		elseif ($this->pdodriver === 'odbc')
 		{
 			$this->_like_escape_str = " {escape '%s'} ";
-			$this->_like_escape_chr = '!';
 		}
-		else
+		elseif ( ! in_array($this->pdodriver, array('sqlsrv', 'mssql', 'dblib', 'sybase')))
 		{
-			$this->_like_escape_str = " ESCAPE '%s' ";
-			$this->_like_escape_chr = '!';
+			$this->_escape_char = '"';
 		}
 
 		$this->trans_enabled = FALSE;
@@ -184,6 +183,8 @@
 	    }
 	}
 
+	// --------------------------------------------------------------------
+
 	/**
 	 * Non-persistent database connection
 	 *
@@ -191,9 +192,7 @@
 	 */
 	public function db_connect()
 	{
-		$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
-
-		return $this->pdo_connect();
+		return $this->_pdo_connect();
 	}
 
 	// --------------------------------------------------------------------
@@ -205,10 +204,7 @@
 	 */
 	public function db_pconnect()
 	{
-		$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
-		$this->options[PDO::ATTR_PERSISTENT] = TRUE;
-
-		return $this->pdo_connect();
+		return $this->_pdo_connect(TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -216,20 +212,29 @@
 	/**
 	 * PDO connection
 	 *
+	 * @param	bool
 	 * @return	object
 	 */
-	public function pdo_connect()
+	protected function _pdo_connect($persistent = FALSE)
 	{
-		// Refer : http://php.net/manual/en/ref.pdo-mysql.connection.php
-		if ($this->pdodriver === 'mysql' && ! is_php('5.3.6'))
+		$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
+		$persistent === FALSE OR $this->options[PDO::ATTR_PERSISTENT] = TRUE;
+
+		/* Prior to PHP 5.3.6, even if the charset was supplied in the DSN
+		 * on connect - it was ignored. This is a work-around for the issue.
+		 *
+		 * Reference: http://www.php.net/manual/en/ref.pdo-mysql.connection.php
+		 */
+		if ($this->pdodriver === 'mysql' && ! is_php('5.3.6') && ! empty($this->char_set))
 		{
-			$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES $this->char_set COLLATE '$this->dbcollat'";
+			$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES '.$this->char_set
+					.( ! empty($this->db_collat) ? " COLLATE '".$this->dbcollat."'" : '');
 		}
 
 		// Connecting...
 		try
 		{
-			$db = new PDO($this->dsn, $this->username, $this->password, $this->options);
+			return new PDO($this->dsn, $this->username, $this->password, $this->options);
 		}
 		catch (PDOException $e)
 		{
@@ -240,21 +245,6 @@
 
 			return FALSE;
 		}
-
-		return $db;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Select the database
-	 *
-	 * @return	resource
-	 */
-	public function db_select()
-	{
-		// Not needed for PDO
-		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -281,46 +271,7 @@
 	 */
 	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
-
-		$result_id = $this->conn_id->query($sql);
-
-		if (is_object($result_id))
-		{
-			$this->affect_rows = $result_id->rowCount();
-		}
-		else
-		{
-			$this->affect_rows = 0;
-		}
-
-		return $result_id;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Prep the query
-	 *
-	 * If needed, each database adapter can prep the query string
-	 *
-	 * @param	string	an SQL query
-	 * @return	string
-	 */
-	protected function _prep_query($sql)
-	{
-		if ($this->pdodriver === 'pgsql')
-		{
-			// Change the backtick(s) for Postgre
-			$sql = str_replace('`', '"', $sql);
-		}
-		elseif ($this->pdodriver === 'sqlite')
-		{
-			// Change the backtick(s) for SQLite
-			$sql = str_replace('`', '', $sql);
-		}
-
-		return $sql;
+		return $this->conn_id->query($sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -332,13 +283,8 @@
 	 */
 	public function trans_begin($test_mode = FALSE)
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -346,7 +292,7 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = (bool) ($test_mode === TRUE);
+		$this->_trans_failure = ($test_mode === TRUE);
 
 		return $this->conn_id->beginTransaction();
 	}
@@ -360,20 +306,13 @@
 	 */
 	public function trans_commit()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
 
-		$ret = $this->conn->commit();
-
-		return $ret;
+		return $this->conn_id->commit();
 	}
 
 	// --------------------------------------------------------------------
@@ -385,20 +324,13 @@
 	 */
 	public function trans_rollback()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
 
-		$ret = $this->conn_id->rollBack();
-
-		return $ret;
+		return $this->conn_id->rollBack();
 	}
 
 	// --------------------------------------------------------------------
@@ -422,10 +354,10 @@
 			return $str;
 		}
 
-		//Escape the string
+		// Escape the string
 		$str = $this->conn_id->quote($str);
 
-		//If there are duplicated quotes, trim them away
+		// If there are duplicated quotes, trim them away
 		if (strpos($str, "'") === 0)
 		{
 			$str = substr($str, 1, -1);
@@ -451,7 +383,7 @@
 	 */
 	public function affected_rows()
 	{
-		return $this->affect_rows;
+		return is_object($this->result_id) ? $this->result_id->rowCount() : 0;
 	}
 
 	// --------------------------------------------------------------------
@@ -459,6 +391,7 @@
 	/**
 	 * Insert ID
 	 *
+	 * @param	string
 	 * @return	int
 	 */
 	public function insert_id($name = NULL)
@@ -476,38 +409,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$sql = $this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE);
-		$query = $this->query($sql);
-
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$row = $query->row();
-		$this->_reset_select();
-
-		return (int) $row->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Show table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -517,22 +418,22 @@
 	 */
 	protected function _list_tables($prefix_limit = FALSE)
 	{
-		if ($this->pdodriver == 'pgsql')
+		if ($this->pdodriver === 'pgsql')
 		{
 			// Analog function to show all tables in postgre
 			$sql = "SELECT * FROM information_schema.tables WHERE table_schema = 'public'";
 		}
-		elseif ($this->pdodriver == 'sqlite')
+		elseif ($this->pdodriver === 'sqlite')
 		{
 			// Analog function to show all tables in sqlite
 			$sql = "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'";
 		}
 		else
 		{
-			$sql = "SHOW TABLES FROM `".$this->database."`";
+			$sql = 'SHOW TABLES FROM '.$this->escape_identifiers($this->database);
 		}
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE AND $this->dbprefix !== '')
 		{
 			return FALSE;
 		}
@@ -552,7 +453,7 @@
 	 */
 	protected function _list_columns($table = '')
 	{
-		return 'SHOW COLUMNS FROM '.$this->_from_tables($table);
+		return 'SHOW COLUMNS FROM '.$this->escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -567,23 +468,23 @@
 	 */
 	protected function _field_data($table)
 	{
-		if ($this->pdodriver == 'mysql' or $this->pdodriver == 'pgsql')
+		if ($this->pdodriver === 'mysql' or $this->pdodriver === 'pgsql')
 		{
 			// Analog function for mysql and postgre
-			return 'SELECT * FROM '.$this->_from_tables($table).' LIMIT 1';
+			return 'SELECT * FROM '.$this->escape_identifiers($table).' LIMIT 1';
 		}
-		elseif ($this->pdodriver == 'oci')
+		elseif ($this->pdodriver === 'oci')
 		{
 			// Analog function for oci
-			return 'SELECT * FROM '.$this->_from_tables($table).' WHERE ROWNUM <= 1';
+			return 'SELECT * FROM '.$this->escape_identifiers($table).' WHERE ROWNUM <= 1';
 		}
-		elseif ($this->pdodriver == 'sqlite')
+		elseif ($this->pdodriver === 'sqlite')
 		{
 			// Analog function for sqlite
-			return 'PRAGMA table_info('.$this->_from_tables($table).')';
+			return 'PRAGMA table_info('.$this->escape_identifiers($table).')';
 		}
 
-		return 'SELECT TOP 1 FROM '.$this->_from_tables($table);
+		return 'SELECT TOP 1 FROM '.$this->escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -618,134 +519,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str  = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
-			$str .= $this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * From Tables
-	 *
-	 * This function implicitly groups FROM tables so there is no confusion
-	 * about operator precedence in harmony with SQL standards
-	 *
-	 * @param	array
-	 * @return	string
-	 */
-	protected function _from_tables($tables)
-	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return (count($tables) == 1) ? '`'.$tables[0].'`' : '('.implode(', ', $tables).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$this->_from_tables($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert_batch($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$this->_from_tables($table).' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key." = ".$val;
-		}
-
-		$limit   = ( ! $limit) ? '' : ' LIMIT '.$limit;
-		$orderby = (count($orderby) >= 1) ? ' ORDER BY '.implode(', ', $orderby) : '';
-
-		$sql  = 'UPDATE '.$this->_from_tables($table).' SET '.implode(', ', $valstr);
-		$sql .= ($where != '' && count($where) >= 1) ? ' WHERE '.implode(' ', $where) : '';
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Update_Batch statement
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
@@ -758,7 +531,7 @@
 	protected function _update_batch($table, $values, $index, $where = NULL)
 	{
 		$ids   = array();
-		$where = ($where != '' && count($where) >=1) ? implode(" ", $where).' AND ' : '';
+		$where = ($where !== '' && count($where) >=1) ? implode(" ", $where).' AND ' : '';
 
 		foreach ($values as $key => $val)
 		{
@@ -766,14 +539,14 @@
 
 			foreach (array_keys($val) as $field)
 			{
-				if ($field != $index)
+				if ($field !== $index)
 				{
 					$final[$field][] =  'WHEN '.$index.' = '.$val[$index].' THEN '.$val[$field];
 				}
 			}
 		}
 
-		$sql   = 'UPDATE '.$this->_from_tables($table).' SET ';
+		$sql   = 'UPDATE '.$table.' SET ';
 		$cases = '';
 
 		foreach ($final as $k => $v)
@@ -800,49 +573,16 @@
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
 	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions  = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return 'DELETE FROM '.$this->_from_tables($table).$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -859,7 +599,7 @@
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		if ($this->pdodriver == 'cubrid' OR $this->pdodriver == 'sqlite')
+		if ($this->pdodriver === 'cubrid' OR $this->pdodriver === 'sqlite')
 		{
 			$offset = ($offset == 0) ? '' : $offset.', ';
 
@@ -874,19 +614,6 @@
 		}
 	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Close DB Connection
-	 *
-	 * @param	resource
-	 * @return	void
-	 */
-	protected function _close($conn_id)
-	{
-		$this->conn_id = null;
-	}
-
 }
 
 /* End of file pdo_driver.php */
diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php
index 6bff354..02ceb74 100644
--- a/system/database/drivers/pdo/pdo_forge.php
+++ b/system/database/drivers/pdo/pdo_forge.php
@@ -34,43 +34,8 @@
  */
 class CI_DB_pdo_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _create_database()
-	{
-		// PDO has no "create database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _drop_database($name)
-	{
-		// PDO has no "drop database" command since it's
-		// designed to connect to an existing database
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_database	= 'DROP DATABASE %s';
+	protected $_drop_table		= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
@@ -82,7 +47,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -91,56 +56,48 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= '`'.$this->db->_escape_identifiers($table).'` (';
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
 			// entered the field information, so we'll simply add it to the list
 			if (is_numeric($field))
 			{
-				$sql .= "\n\t$attributes";
+				$sql .= "\n\t".$attributes;
 			}
 			else
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
-				$numeric    = array('SERIAL', 'INTEGER');
+				$numeric = array('SERIAL', 'INTEGER');
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field);
+				$sql .= "\n\t".$this->db->escape_identifiers($field).' '.$attributes['TYPE'];
 
-				$sql .=  ' '.$attributes['TYPE'];
-
-				if (array_key_exists('CONSTRAINT', $attributes))
+				if ( ! empty($attributes['CONSTRAINT']))
 				{
 					// Exception for Postgre numeric which not too happy with constraint within those type
-					if ( ! ($this->db->pdodriver == 'pgsql' && in_array($attributes['TYPE'], $numeric)))
+					if ( ! ($this->db->pdodriver === 'pgsql' && in_array($attributes['TYPE'], $numeric)))
 					{
 						$sql .= '('.$attributes['CONSTRAINT'].')';
 					}
 				}
 
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
 				{
 					$sql .= ' UNSIGNED';
 				}
 
-				if (array_key_exists('DEFAULT', $attributes))
+				if (isset($attributes['DEFAULT']))
 				{
-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
 				}
 
-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
-				{
-					$sql .= ' NULL';
-				}
-				else
-				{
-					$sql .= ' NOT NULL';
-				}
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
 
-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
 				{
 					$sql .= ' AUTO_INCREMENT';
 				}
@@ -155,47 +112,22 @@
 
 		if (count($primary_keys) > 0)
 		{
-			$primary_keys = $this->db->protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
 		{
 			foreach ($keys as $key)
 			{
-				if (is_array($key))
-				{
-					$key = $this->db->protect_identifiers($key);
-				}
-				else
-				{
-					$key = array($this->db->protect_identifiers($key));
-				}
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->db->escape_identifiers($key));
 
-				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tFOREIGN KEY (".implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n)";
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @return	bool
-	 */
-	public function _drop_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
+		return $sql."\n)";
 	}
 
 	// --------------------------------------------------------------------
@@ -215,56 +147,20 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
-		$sql = 'ALTER TABLE `'.$this->db->protect_identifiers($table).'` '.$alter_type.' '.$this->db->protect_identifiers($column_name);
+		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' '.$this->db->escape_identifiers($column_name);
 
 		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		if ($alter_type === 'DROP')
 		{
 			return $sql;
 		}
 
-		$sql .= " $column_definition";
-
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
-
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
+		return $sql .' '.$column_definition
+			.($default_value !== '' ? " DEFAULT '".$default_value."'" : '')
+			.($null === NULL ? ' NULL' : ' NOT NULL')
+			.($after_field !== '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 	}
 
 }
diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php
index 5bbd85d..0b8937c 100644
--- a/system/database/drivers/pdo/pdo_result.php
+++ b/system/database/drivers/pdo/pdo_result.php
@@ -84,20 +84,14 @@
 		// Define the output
 		$output = array('assoc', 'object');
 
+		// Initial value
+		$this->result_assoc = array() and $this->result_object = array();
+
 		// Fetch the result
-		foreach ($output as $type)
+		while ($row = $this->_fetch_assoc())
 		{
-			// Define the method and handler
-			$res_method  = '_fetch_'.$type;
-			$res_handler = 'result_'.$type;
-
-			$this->$res_handler = array();
-			$this->_data_seek(0);
-
-			while ($row = $this->$res_method())
-			{
-				$this->{$res_handler}[] = $row;
-			}
+			$this->result_assoc[] = $row;
+			$this->result_object[] = (object) $row;
 		}
 
 		// Save this as buffer and marked the fetch flag
@@ -228,22 +222,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset. We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @return	bool
-	 */
-	protected function _data_seek($n = 0)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
@@ -266,7 +244,7 @@
 	 */
 	protected function _fetch_object()
 	{
-		return $this->result_id->fetchObject();
+		return $this->result_id->fetch(PDO::FETCH_OBJ);
 	}
 
 }
diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php
index 86c7983..9308421 100644
--- a/system/database/drivers/pdo/pdo_utility.php
+++ b/system/database/drivers/pdo/pdo_utility.php
@@ -34,62 +34,7 @@
  */
 class CI_DB_pdo_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		// Not sure if PDO lets you list all databases...
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _optimize_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		// Not a supported PDO feature
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases = FALSE;
 
 	/**
 	 * PDO Export
@@ -97,7 +42,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 3e2d05c..7375fbf 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -29,7 +29,7 @@
  * Postgre Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -80,16 +80,16 @@
 			$this->port = '';
 		}
 
-		$this->hostname === '' OR $this->dsn = 'host='.$this->hostname;
+		$this->hostname === '' OR $this->dsn = 'host='.$this->hostname.' ';
 
 		if ( ! empty($this->port) && ctype_digit($this->port))
 		{
-			$this->dsn .= 'host='.$this->port.' ';
+			$this->dsn .= 'port='.$this->port.' ';
 		}
 
 		if ($this->username !== '')
 		{
-			$this->dsn .= 'username='.$this->username.' ';
+			$this->dsn .= 'user='.$this->username.' ';
 
 			/* An empty password is valid!
 			 *
@@ -162,23 +162,10 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @return	resource
-	 */
-	public function db_select()
-	{
-		// Not needed for Postgre so we'll return TRUE
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Set client character set
 	 *
-	 * @param       string
-	 * @return      bool
+	 * @param	string
+	 * @return	bool
 	 */
 	protected function _db_set_charset($charset)
 	{
@@ -232,6 +219,7 @@
 	/**
 	 * Begin Transaction
 	 *
+	 * @param	bool
 	 * @return	bool
 	 */
 	public function trans_begin($test_mode = FALSE)
@@ -247,7 +235,7 @@
 		// even if the queries produce a successful result.
 		$this->_trans_failure = ($test_mode === TRUE);
 
-		return @pg_query($this->conn_id, 'BEGIN');
+		return (bool) @pg_query($this->conn_id, 'BEGIN');
 	}
 
 	// --------------------------------------------------------------------
@@ -265,7 +253,7 @@
 			return TRUE;
 		}
 
-		return @pg_query($this->conn_id, 'COMMIT');
+		return (bool) @pg_query($this->conn_id, 'COMMIT');
 	}
 
 	// --------------------------------------------------------------------
@@ -283,7 +271,7 @@
 			return TRUE;
 		}
 
-		return @pg_query($this->conn_id, 'ROLLBACK');
+		return (bool) @pg_query($this->conn_id, 'ROLLBACK');
 	}
 
 	// --------------------------------------------------------------------
@@ -323,6 +311,27 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * "Smart" Escape String
+	 *
+	 * Escapes data based on type
+	 * Sets boolean and null types
+	 *
+	 * @param	string
+	 * @return	mixed
+	 */
+	public function escape($str)
+	{
+		if (is_bool($str))
+		{
+			return ($str) ? 'TRUE' : 'FALSE';
+		}
+
+		return parent::escape($str);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Affected Rows
 	 *
 	 * @return	int
@@ -341,63 +350,41 @@
 	 */
 	public function insert_id()
 	{
-		$v = $this->version();
+		$v = pg_version($this->conn_id);
+		$v = isset($v['server']) ? $v['server'] : 0; // 'server' key is only available since PosgreSQL 7.4
 
-		$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';
+			$sql = 'SELECT LASTVAL() AS ins_id';
 		}
-		elseif ($table != NULL && $column != NULL && $v >= '8.0')
+		elseif ($table !== NULL)
 		{
-			$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)
-		{
-			// seq_name passed in table parameter
-			$sql = sprintf("SELECT CURRVAL('%s') as ins_id", $table);
+			if ($column !== NULL && $v >= '8.0')
+			{
+				$sql = 'SELECT pg_get_serial_sequence(\''.$table."', '".$column."') AS seq";
+				$query = $this->query($sql);
+				$query = $query->row();
+				$seq = $query->seq;
+			}
+			else
+			{
+				// seq_name passed in table parameter
+				$seq = $table;
+			}
+
+			$sql = 'SELECT CURRVAL(\''.$seq."') AS ins_id";
 		}
 		else
 		{
 			return pg_last_oid($this->result_id);
 		}
+
 		$query = $this->query($sql);
-		$row = $query->row();
-		return $row->ins_id;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$row = $query->row();
-		$this->_reset_select();
-		return (int) $row->numrows;
+		$query = $query->row();
+		return (int) $query->ins_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -414,9 +401,9 @@
 	{
 		$sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix !== '')
 		{
-			$sql .= " AND table_name LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
+			return $sql." AND table_name LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 		}
 
 		return $sql;
@@ -434,7 +421,7 @@
 	 */
 	protected function _list_columns($table = '')
 	{
-		return "SELECT column_name FROM information_schema.columns WHERE table_name ='".$table."'";
+		return "SELECT column_name FROM information_schema.columns WHERE table_name = '".$table."'";
 	}
 
 	// --------------------------------------------------------------------
@@ -445,11 +432,11 @@
 	 * Generates a platform-specific query so that the column data can be retrieved
 	 *
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
 	protected function _field_data($table)
 	{
-		return "SELECT * FROM ".$table." LIMIT 1";
+		return 'SELECT * FROM '.$table.' LIMIT 1';
 	}
 
 	// --------------------------------------------------------------------
@@ -470,47 +457,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
@@ -521,46 +467,7 @@
 	 */
 	protected function _from_tables($tables)
 	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return implode(', ', $tables);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert_batch statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param   string  the table name
-	 * @param   array   the insert keys
-	 * @param   array   the insert values
-	 * @return  string
-	 */
-	protected function _insert_batch($table, $keys, $values)
-	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
+		return is_array($tables) ? implode(', ', $tables) : $tables;
 	}
 
 	// --------------------------------------------------------------------
@@ -573,39 +480,67 @@
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach ($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
 
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
 
-		return $sql;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where;
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Truncate statement
+	 * Update_Batch statement
 	 *
-	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
+	 * Generates a platform-specific batch update string from the supplied data
 	 *
 	 * @param	string	the table name
+	 * @param	array	the update data
+	 * @param	array	the where clause
 	 * @return	string
 	 */
-	protected function _truncate($table)
+	protected function _update_batch($table, $values, $index, $where = NULL)
 	{
-		return "TRUNCATE ".$table;
+		$ids = array();
+		foreach ($values as $key => $val)
+		{
+			$ids[] = $val[$index];
+
+			foreach (array_keys($val) as $field)
+			{
+				if ($field !== $index)
+				{
+					$final[$field][] =  'WHEN '.$val[$index].' THEN '.$val[$field];
+				}
+			}
+		}
+
+		$cases = '';
+		foreach ($final as $k => $v)
+		{
+			$cases .= $k.' = (CASE '.$k."\n"
+				.implode("\n", $v)."\n"
+				.'ELSE '.$k.' END), ';
+		}
+
+		return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
+			.' WHERE '.(($where !== '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
+			.$index.' IN('.implode(',', $ids).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -617,29 +552,22 @@
 	 *
 	 * @param	string	the table name
 	 * @param	array	the where clause
-	 * @param	string	the limit clause
+	 * @param	array	the like clause
+	 * @param	string	the limit clause (ignored)
 	 * @return	string
 	 */
 	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		$conditions = '';
+		$conditions = array();
 
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
 
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		return "DELETE FROM ".$table.$conditions;
+		return 'DELETE FROM '.$table.(count($conditions) > 0 ? ' WHERE '.implode(' AND ', $conditions) : '');
 	}
 
 	// --------------------------------------------------------------------
+
 	/**
 	 * Limit string
 	 *
@@ -652,14 +580,79 @@
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		$sql .= "LIMIT ".$limit;
+		return $sql.' LIMIT '.$limit.($offset == 0 ? '' : ' OFFSET '.$offset);
+	}
 
-		if ($offset > 0)
+	// --------------------------------------------------------------------
+
+	/**
+	 * Where
+	 *
+	 * Called by where() or or_where()
+	 *
+	 * @param	mixed
+	 * @param	mixed
+	 * @param	string
+	 * @return	object
+	 *
+	 */
+	protected function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)
+	{
+		$type = $this->_group_get_type($type);
+
+		if ( ! is_array($key))
 		{
-			$sql .= " OFFSET ".$offset;
+			$key = array($key => $value);
 		}
 
-		return $sql;
+		// If the escape value was not set will will base it on the global setting
+		if ( ! is_bool($escape))
+		{
+			$escape = $this->_protect_identifiers;
+		}
+
+		foreach ($key as $k => $v)
+		{
+			$prefix = (count($this->qb_where) === 0 && count($this->qb_cache_where) === 0) ? '' : $type;
+
+			if (is_null($v) && ! $this->_has_operator($k))
+			{
+				// value appears not to have been set, assign the test to IS NULL
+				$k .= ' IS NULL';
+			}
+
+			if ( ! is_null($v))
+			{
+				if ($escape === TRUE)
+				{
+					$k = $this->protect_identifiers($k, FALSE, $escape);
+					$v = ' '.$this->escape($v);
+				}
+				elseif (is_bool($v))
+				{
+					$v = ($v ? ' TRUE' : ' FALSE');
+				}
+
+				if ( ! $this->_has_operator($k))
+				{
+					$k .= ' = ';
+				}
+			}
+			else
+			{
+				$k = $this->protect_identifiers($k, FALSE, $escape);
+			}
+
+			$this->qb_where[] = $prefix.$k.$v;
+			if ($this->qb_caching === TRUE)
+			{
+				$this->qb_cache_where[] = $prefix.$k.$v;
+				$this->qb_cache_exists[] = 'where';
+			}
+
+		}
+
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -667,12 +660,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@pg_close($conn_id);
+		@pg_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php
index a724498..c434e95 100644
--- a/system/database/drivers/postgre/postgre_forge.php
+++ b/system/database/drivers/postgre/postgre_forge.php
@@ -34,31 +34,7 @@
  */
 class CI_DB_postgre_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_table	= 'DROP TABLE IF EXISTS %s CASCADE';
 
 	/**
 	 * Process Fields
@@ -66,7 +42,7 @@
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	protected function _process_fields($fields, $primary_keys=array())
+	protected function _process_fields($fields, $primary_keys = array())
 	{
 		$sql = '';
 		$current_field_count = 0;
@@ -78,15 +54,14 @@
 			// entered the field information, so we'll simply add it to the list
 			if (is_numeric($field))
 			{
-				$sql .= "\n\t$attributes";
+				$sql .= "\n\t".$attributes;
 			}
 			else
 			{
+				$sql .= "\n\t".$this->db->escape_identifiers($field);
+
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
-
-				$sql .= "\n\t".$this->db->protect_identifiers($field);
-
-				$is_unsigned = (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE);
+				$is_unsigned = ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE);
 
 				// Convert datatypes to be PostgreSQL-compatible
 				switch (strtoupper($attributes['TYPE']))
@@ -118,41 +93,30 @@
 					case 'BLOB':
 						$attributes['TYPE'] = 'BYTEA';
 						break;
+					default:
+						break;
 				}
 
 				// If this is an auto-incrementing primary key, use the serial data type instead
-				if (in_array($field, $primary_keys) && array_key_exists('AUTO_INCREMENT', $attributes) 
-					&& $attributes['AUTO_INCREMENT'] === TRUE)
-				{
-					$sql .= ' SERIAL';
-				}
-				else
-				{
-					$sql .=  ' '.$attributes['TYPE'];
-				}
+				$sql .= (in_array($field, $primary_keys) && ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
+					? ' SERIAL' : ' '.$attributes['TYPE'];
 
 				// Modified to prevent constraints with integer data types
-				if (array_key_exists('CONSTRAINT', $attributes) && strpos($attributes['TYPE'], 'INT') === false)
+				if ( ! empty($attributes['CONSTRAINT']) && strpos($attributes['TYPE'], 'INT') === FALSE)
 				{
 					$sql .= '('.$attributes['CONSTRAINT'].')';
 				}
 
-				if (array_key_exists('DEFAULT', $attributes))
+				if (isset($attributes['DEFAULT']))
 				{
-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
 				}
 
-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
-				{
-					$sql .= ' NULL';
-				}
-				else
-				{
-					$sql .= ' NOT NULL';
-				}
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
 
-				// Added new attribute to create unqite fields. Also works with MySQL
-				if (array_key_exists('UNIQUE', $attributes) && $attributes['UNIQUE'] === TRUE)
+				// Added new attribute to create unique fields. Also works with MySQL
+				if ( ! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === TRUE)
 				{
 					$sql .= ' UNIQUE';
 				}
@@ -180,31 +144,21 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
-		if ($if_not_exists === TRUE)
+		// PostgreSQL doesn't support IF NOT EXISTS syntax so we check if table exists manually
+		if ($if_not_exists === TRUE && $this->db->table_exists($table))
 		{
-			// PostgreSQL doesn't support IF NOT EXISTS syntax so we check if table exists manually
-			if ($this->db->table_exists($table))
-			{
-				return TRUE;
-			}
+			return TRUE;
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
-		$sql .= $this->_process_fields($fields, $primary_keys);
+		$sql .= $this->db->escape_identifiers($table).' ('.$this->_process_fields($fields, $primary_keys);
 
 		if (count($primary_keys) > 0)
 		{
-			// Something seems to break when passing an array to protect_identifiers()
-			foreach ($primary_keys as $index => $key)
-			{
-				$primary_keys[$index] = $this->db->protect_identifiers($key);
-			}
-
-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		$sql .= "\n);";
@@ -213,18 +167,14 @@
 		{
 			foreach ($keys as $key)
 			{
-				if (is_array($key))
-				{
-					$key = $this->db->protect_identifiers($key);
-				}
-				else
-				{
-					$key = array($this->db->protect_identifiers($key));
-				}
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->db->escape_identifiers($key));
 
 				foreach ($key as $field)
 				{
-					$sql .= "CREATE INDEX " . $table . "_" . str_replace(array('"', "'"), '', $field) . "_index ON $table ($field); ";
+					$sql .= "\nCREATE INDEX ".$this->db->escape_identifiers($table.'_'.str_replace(array('"', "'"), '', $field).'_index')
+						.' ON '.$this->db->escape_identifiers($table).' ('.$this->db->escape_identifiers($field).');';
 				}
 			}
 		}
@@ -235,18 +185,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Drop Table
-	 *
-	 * @return	string
-	 */
-	public function _drop_table($table)
-	{
-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table)." CASCADE";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
@@ -257,45 +195,24 @@
 	 * @param	string	the table name
 	 * @param	string	the column definition
 	 * @param	string	the default value
-	 * @param	boolean	should 'NOT NULL' be added
+	 * @param	bool	should 'NOT NULL' be added
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $fields, $after_field = '')
+	protected function _alter_table($alter_type, $table, $fields, $after_field = '')
  	{
- 		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' ';
+ 		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' ';
 
  		// DROP has everything it needs now.
- 		if ($alter_type == 'DROP')
+ 		if ($alter_type === 'DROP')
  		{
- 			return $sql.$this->db->protect_identifiers($fields);
+ 			return $sql.$this->db->escape_identifiers($fields);
  		}
 
- 		$sql .= $this->_process_fields($fields);
-
- 		if ($after_field != '')
- 		{
- 			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
- 		}
-
- 		return $sql;
+ 		return $sql.$this->_process_fields($fields)
+			.($after_field !== '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
  	}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
-	}
 }
 
 /* End of file postgre_forge.php */
diff --git a/system/database/drivers/postgre/postgre_result.php b/system/database/drivers/postgre/postgre_result.php
index 8b22564..f913bc9 100644
--- a/system/database/drivers/postgre/postgre_result.php
+++ b/system/database/drivers/postgre/postgre_result.php
@@ -70,7 +70,7 @@
 	public function list_fields()
 	{
 		$field_names = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
 			$field_names[] = pg_field_name($this->result_id, $i);
 		}
@@ -90,16 +90,14 @@
 	public function field_data()
 	{
 		$retval = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$F				= new stdClass();
-			$F->name		= pg_field_name($this->result_id, $i);
-			$F->type		= pg_field_type($this->result_id, $i);
-			$F->max_length	= pg_field_size($this->result_id, $i);
-			$F->primary_key = 0;
-			$F->default		= '';
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= pg_field_name($this->result_id, $i);
+			$retval[$i]->type		= pg_field_type($this->result_id, $i);
+			$retval[$i]->max_length		= pg_field_size($this->result_id, $i);
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -130,7 +128,7 @@
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php
index cf29201..c95e6df 100644
--- a/system/database/drivers/postgre/postgre_utility.php
+++ b/system/database/drivers/postgre/postgre_utility.php
@@ -34,43 +34,8 @@
  */
 class CI_DB_postgre_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return 'SELECT datname FROM pg_database';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * @param	string	the table name
-	 * @return	string
-	 */
-	public function _optimize_table($table)
-	{
-		return 'REINDEX TABLE '.$this->db->protect_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'SELECT datname FROM pg_database';
+	protected $_optimize_table	= 'REINDEX TABLE %s';
 
 	/**
 	 * Postgre Export
@@ -78,7 +43,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index 102c79b..3305f60 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_driver.php
@@ -29,7 +29,7 @@
  * SQLite Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -43,7 +43,7 @@
 	public $dbdriver = 'sqlite';
 
 	// The character used to escape with - not needed for SQLite
-	protected $_escape_char = '';
+	protected $_escape_char = '"';
 
 	// clause and character used for LIKE escape sequences
 	protected $_like_escape_str = " ESCAPE '%s' ";
@@ -106,18 +106,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Select the database
-	 *
-	 * @return	resource
-	 */
-	public function db_select()
-	{
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -139,7 +127,9 @@
 	 */
 	protected function _execute($sql)
 	{
-		return @sqlite_query($this->conn_id, $sql);
+		return $this->is_write_type($sql)
+			? @sqlite_exec($this->conn_id, $sql)
+			: @sqlite_query($this->conn_id, $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -151,13 +141,8 @@
 	 */
 	public function trans_begin($test_mode = FALSE)
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -165,7 +150,7 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+		$this->_trans_failure = ($test_mode === TRUE);
 
 		$this->simple_query('BEGIN TRANSACTION');
 		return TRUE;
@@ -180,13 +165,8 @@
 	 */
 	public function trans_commit()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -204,13 +184,8 @@
 	 */
 	public function trans_rollback()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -280,35 +255,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query($this->_count_string.$this->protect_identifiers('numrows').' FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE));
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$row = $query->row();
-		$this->_reset_select();
-		return (int) $row->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * List table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -318,12 +264,13 @@
 	 */
 	protected function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = "SELECT name from sqlite_master WHERE type='table'";
+		$sql = "SELECT name FROM sqlite_master WHERE type='table'";
 
-		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		if ($prefix_limit !== FALSE && $this->dbprefix != '')
 		{
-			$sql .= " AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
+			return $sql." AND 'name' LIKE '".$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
 		}
+
 		return $sql;
 	}
 
@@ -355,7 +302,7 @@
 	 */
 	protected function _field_data($table)
 	{
-		return "SELECT * FROM ".$table." LIMIT 1";
+		return 'SELECT * FROM '.$this->escape_identifiers($table).' LIMIT 1';
 	}
 
 	// --------------------------------------------------------------------
@@ -378,165 +325,36 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
+	 * Replace statement
 	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		if ($this->_escape_char == '')
-		{
-			return $item;
-		}
-
-		foreach ($this->_reserved_identifiers as $id)
-		{
-			if (strpos($item, '.'.$id) !== FALSE)
-			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
-
-				// remove duplicates if the user already included the escape
-				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-			}
-		}
-
-		if (strpos($item, '.') !== FALSE)
-		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-		}
-		else
-		{
-			$str = $this->_escape_char.$item.$this->_escape_char;
-		}
-
-		// remove duplicates if the user already included the escape
-		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * From Tables
-	 *
-	 * This function implicitly groups FROM tables so there is no confusion
-	 * about operator precedence in harmony with SQL standards
-	 *
-	 * @param	array
-	 * @return	string
-	 */
-	protected function _from_tables($tables)
-	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return '('.implode(', ', $tables).')';
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
+	 * Generates a platform-specific replace string from the supplied data
 	 *
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	protected function _insert($table, $keys, $values)
+	protected function _replace($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return 'INSERT OR '.parent::_replace($table, $keys, $values);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Update statement
-	 *
-	 * Generates a platform-specific update string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the update data
-	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
-	 * @return	string
-	 */
-	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
-	{
-		foreach ($values as $key => $val)
-		{
-			$valstr[] = $key." = ".$val;
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
-		$sql .= $orderby.$limit;
-
-		return $sql;
-	}
-
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this function maps to 'DELETE FROM table'
 	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return $this->_delete($table);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Delete statement
-	 *
-	 * Generates a platform-specific delete string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the where clause
-	 * @param	string	the limit clause
-	 * @return	string
-	 */
-	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
-	{
-		$conditions = '';
-
-		if (count($where) > 0 OR count($like) > 0)
-		{
-			$conditions = "\nWHERE ";
-			$conditions .= implode("\n", $this->ar_where);
-
-			if (count($where) > 0 && count($like) > 0)
-			{
-				$conditions .= " AND ";
-			}
-			$conditions .= implode("\n", $like);
-		}
-
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -553,16 +371,7 @@
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		if ($offset == 0)
-		{
-			$offset = '';
-		}
-		else
-		{
-			$offset .= ", ";
-		}
-
-		return $sql."LIMIT ".$offset.$limit;
+		return $sql.'LIMIT '.($offset == 0 ? '' : $offset.', ').$limit;
 	}
 
 	// --------------------------------------------------------------------
@@ -570,12 +379,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@sqlite_close($conn_id);
+		@sqlite_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php
index 068a556..71eed7d 100644
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ b/system/database/drivers/sqlite/sqlite_forge.php
@@ -40,7 +40,7 @@
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	public function _create_database()
+	public function create_database($db_name = '')
 	{
 		// In SQLite, a database is created when you connect to the database.
 		// We'll return TRUE so that an error isn't generated
@@ -52,19 +52,16 @@
 	/**
 	 * Drop database
 	 *
-	 * @param	string	the database name
+	 * @param	string	the database name (ignored)
 	 * @return	bool
 	 */
-	public function _drop_database($name)
+	public function drop_database($db_name = '')
 	{
 		if ( ! @file_exists($this->db->database) OR ! @unlink($this->db->database))
 		{
-			if ($this->db->db_debug)
-			{
-				return $this->db->display_error('db_unable_to_drop');
-			}
-			return FALSE;
+			return ($this->db->db_debug) ? $this->db->display_error('db_unable_to_drop') : FALSE;
 		}
+
 		return TRUE;
 	}
 
@@ -80,7 +77,7 @@
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
 	 * @return	bool
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -90,51 +87,41 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)."(";
+		$sql .= $this->db->escape_identifiers($table).' (';
 		$current_field_count = 0;
 
-		foreach ($fields as $field=>$attributes)
+		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
 			// numeric, we know it was assigned by PHP and the developer manually
 			// entered the field information, so we'll simply add it to the list
 			if (is_numeric($field))
 			{
-				$sql .= "\n\t$attributes";
+				$sql .= "\n\t".$attributes;
 			}
 			else
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field);
+				$sql .= "\n\t".$this->db->escape_identifiers($field).' '.$attributes['TYPE'];
 
-				$sql .=  ' '.$attributes['TYPE'];
+				empty($attributes['CONSTRAINT']) OR $sql .= '('.$attributes['CONSTRAINT'].')';
 
-				if (array_key_exists('CONSTRAINT', $attributes))
-				{
-					$sql .= '('.$attributes['CONSTRAINT'].')';
-				}
-
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
 				{
 					$sql .= ' UNSIGNED';
 				}
 
-				if (array_key_exists('DEFAULT', $attributes))
+				if (isset($attributes['DEFAULT']))
 				{
-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
 				}
 
-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
-				{
-					$sql .= ' NULL';
-				}
-				else
-				{
-					$sql .= ' NOT NULL';
-				}
 
-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
+
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
 				{
 					$sql .= ' AUTO_INCREMENT';
 				}
@@ -149,46 +136,22 @@
 
 		if (count($primary_keys) > 0)
 		{
-			$primary_keys = $this->db->protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
 		{
 			foreach ($keys as $key)
 			{
-				if (is_array($key))
-				{
-					$key = $this->db->protect_identifiers($key);
-				}
-				else
-				{
-					$key = array($this->db->protect_identifiers($key));
-				}
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->db->escape_identifiers($key));
 
-				$sql .= ",\n\tUNIQUE (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tUNIQUE (".implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n)";
-
-		return $sql;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @return	bool
-	 */
-	public function _drop_table($table)
-	{
-		if ($this->db->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return array();
+		return $sql."\n)";
 	}
 
 	// --------------------------------------------------------------------
@@ -208,58 +171,23 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
-
-		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		/* SQLite only supports adding new columns and it does
+		 * NOT support the AFTER statement. Each new column will
+		 * be added as the last one in the table.
+		 */
+		if ($alter_type !== 'ADD COLUMN')
 		{
-			// SQLite does not support dropping columns
-			// http://www.sqlite.org/omitted.html
-			// http://www.sqlite.org/faq.html#q11
+			// Not supported
 			return FALSE;
 		}
 
-		$sql .= " $column_definition";
-
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
+		return 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' '.$this->db->escape_identifiers($column_name)
+			.' '.$column_definition
+			.($default_value != '' ? " DEFAULT '".$default_value."'" : '')
+			// If NOT NULL is specified, the field must have a DEFAULT value other than NULL
+			.(($null !== NULL && $default_value !== 'NULL') ? ' NOT NULL' : ' NULL');
 	}
 
 }
diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php
index b002aef..741dc9d 100644
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ b/system/database/drivers/sqlite/sqlite_result.php
@@ -70,9 +70,9 @@
 	public function list_fields()
 	{
 		$field_names = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$field_names[] = sqlite_field_name($this->result_id, $i);
+			$field_names[$i] = sqlite_field_name($this->result_id, $i);
 		}
 
 		return $field_names;
@@ -90,16 +90,14 @@
 	public function field_data()
 	{
 		$retval = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			$F				= new stdClass();
-			$F->name		= sqlite_field_name($this->result_id, $i);
-			$F->type		= 'varchar';
-			$F->max_length	= 0;
-			$F->primary_key = 0;
-			$F->default		= '';
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= sqlite_field_name($this->result_id, $i);
+			$retval[$i]->type		= 'varchar';
+			$retval[$i]->max_length		= 0;
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -108,25 +106,13 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Free the result
-	 *
-	 * @return	void
-	 */
-	public function free_result()
-	{
-		// Not implemented in SQLite
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Data Seek
 	 *
 	 * Moves the internal pointer to the desired offset. We call
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @return	array
+	 * @return	bool
 	 */
 	protected function _data_seek($n = 0)
 	{
@@ -162,17 +148,9 @@
 		{
 			return sqlite_fetch_object($this->result_id);
 		}
-		else
-		{
-			$arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);
-			if (is_array($arr))
-			{
-				$obj = (object) $arr;
-				return $obj;
-			} else {
-				return NULL;
-			}
-		}
+
+		$arr = sqlite_fetch_array($this->result_id, SQLITE_ASSOC);
+		return is_array($arr) ? (object) $arr : FALSE;
 	}
 
 }
diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php
index c07004c..1bcb42d 100644
--- a/system/database/drivers/sqlite/sqlite_utility.php
+++ b/system/database/drivers/sqlite/sqlite_utility.php
@@ -34,50 +34,7 @@
  */
 class CI_DB_sqlite_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * I don't believe you can do a database listing with SQLite
-	 * since each database is its own file. I suppose we could
-	 * try reading a directory looking for SQLite files, but
-	 * that doesn't seem like a terribly good idea
-	 *
-	 * @return	bool
-	 */
-	public function _list_databases()
-	{
-		return ($this->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Optimize table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _optimize_table($table)
-	{
-		// Not supported
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		// Not supported
-		return FALSE;
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= FALSE;
 
 	/**
 	 * SQLite Export
@@ -85,7 +42,7 @@
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/database/drivers/sqlite3/index.html b/system/database/drivers/sqlite3/index.html
new file mode 100644
index 0000000..c942a79
--- /dev/null
+++ b/system/database/drivers/sqlite3/index.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+	<title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_driver.php b/system/database/drivers/sqlite3/sqlite3_driver.php
new file mode 100644
index 0000000..bed6189
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_driver.php
@@ -0,0 +1,385 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.2.4 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst.  It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the query builder
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		Andrey Andreev
+ * @link		http://codeigniter.com/user_guide/database/
+ * @since		Version 3.0
+ */
+class CI_DB_sqlite3_driver extends CI_DB {
+
+	public $dbdriver = 'sqlite3';
+
+	// The character used for escaping
+	protected $_escape_char = '"';
+
+	// clause and character used for LIKE escape sequences
+	protected $_like_escape_str = ' ESCAPE \'%s\' ';
+	protected $_like_escape_chr = '!';
+
+	/**
+	 * The syntax to count rows is slightly different across different
+	 * database engines, so this string appears in each driver and is
+	 * used for the count_all() and count_all_results() functions.
+	 */
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' RANDOM()';
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @return	object	type SQLite3
+	 */
+	public function db_connect()
+	{
+		try
+		{
+			return ( ! $this->password)
+				? new SQLite3($this->database)
+				: new SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password);
+		}
+		catch (Exception $e)
+		{
+			return FALSE;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @return  object	type SQLite3
+	 */
+	public function db_pconnect()
+	{
+		log_message('debug', 'SQLite3 doesn\'t support persistent connections');
+		return $this->db_connect();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Database version number
+	 *
+	 * @return	string
+	 */
+	public function version()
+	{
+		if (isset($this->data_cache['version']))
+		{
+			return $this->data_cache['version'];
+		}
+
+		$version = SQLite3::version();
+		return $this->data_cache['version'] = $version['versionString'];
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @param	string	an SQL query
+	 * @return	mixed	SQLite3Result object or bool
+	 */
+	protected function _execute($sql)
+	{
+		// TODO: Implement use of SQLite3::querySingle(), if needed
+
+		return $this->is_write_type($sql)
+			? $this->conn_id->exec($sql)
+			: $this->conn_id->query($sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_begin($test_mode = FALSE)
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		// Reset the transaction failure flag.
+		// If the $test_mode flag is set to TRUE transactions will be rolled back
+		// even if the queries produce a successful result.
+		$this->_trans_failure = ($test_mode === TRUE);
+
+		return $this->conn_id->exec('BEGIN TRANSACTION');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_commit()
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		return $this->conn_id->exec('END TRANSACTION');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @return	bool
+	 */
+	public function trans_rollback()
+	{
+		// When transactions are nested we only begin/commit/rollback the outermost ones
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
+		{
+			return TRUE;
+		}
+
+		return $this->conn_id->exec('ROLLBACK');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Escape String
+	 *
+	 * @param	string
+	 * @param	bool	whether or not the string will be used in a LIKE condition
+	 * @return	string
+	 */
+	public function escape_str($str, $like = FALSE)
+	{
+		if (is_array($str))
+		{
+			foreach ($str as $key => $val)
+			{
+				$str[$key] = $this->escape_str($val, $like);
+			}
+
+			return $str;
+		}
+
+		$str = $this->conn_id->escapeString(remove_invisible_characters($str));
+
+		// escape LIKE condition wildcards
+		if ($like === TRUE)
+		{
+			return str_replace(array($this->_like_escape_chr, '%', '_'),
+						array($this->_like_escape_chr.$this->_like_escape_chr, $this->_like_escape_chr.'%', $this->_like_escape_chr.'_'),
+						$str);
+		}
+
+		return $str;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Affected Rows
+	 *
+	 * @return	int
+	 */
+	public function affected_rows()
+	{
+		return $this->conn_id->changes();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @return	int
+	 */
+	public function insert_id()
+	{
+		return $this->conn_id->lastInsertRowID();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show table query
+	 *
+	 * Generates a platform-specific query string so that the table names can be fetched
+	 *
+	 * @param	bool
+	 * @return	string
+	 */
+	protected function _list_tables($prefix_limit = FALSE)
+	{
+		return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\''
+			.(($prefix_limit !== FALSE && $this->dbprefix != '')
+				? ' AND "NAME" LIKE \''.$this->escape_like_str($this->dbprefix).'%\' '.sprintf($this->_like_escape_str, $this->_like_escape_chr)
+				: '');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Show column query
+	 *
+	 * Generates a platform-specific query string so that the column names can be fetched
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _list_columns($table = '')
+	{
+		// Not supported
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * Generates a platform-specific query so that the column data can be retrieved
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _field_data($table)
+	{
+		return 'SELECT * FROM '.$table.' LIMIT 0,1';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message string
+	 *
+	 * @return	string
+	 */
+	protected function _error_message()
+	{
+		return $this->conn_id->lastErrorMsg();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * The error message number
+	 *
+	 * @return	int
+	 */
+	protected function _error_number()
+	{
+		return $this->conn_id->lastErrorCode();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Replace statement
+	 *
+	 * Generates a platform-specific replace string from the supplied data
+	 *
+	 * @param	string	the table name
+	 * @param	array	the insert keys
+	 * @param	array	the insert values
+	 * @return	string
+	 */
+	protected function _replace($table, $keys, $values)
+	{
+		return 'INSERT OR '.parent::_replace($table, $keys, $values);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Truncate statement
+	 *
+	 * Generates a platform-specific truncate string from the supplied data
+	 *
+	 * If the database does not support the truncate() command, then,
+	 * then this method maps to 'DELETE FROM table'
+	 *
+	 * @param	string	the table name
+	 * @return	string
+	 */
+	protected function _truncate($table)
+	{
+		return 'DELETE FROM '.$table;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Limit string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @param	string	the sql query string
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
+	 * @return	string
+	 */
+	protected function _limit($sql, $limit, $offset)
+	{
+		return $sql.' LIMIT '.($offset ? $offset.',' : '').$limit;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @return	void
+	 */
+	protected function _close()
+	{
+		$this->conn_id->close();
+	}
+
+}
+
+/* End of file sqlite3_driver.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_driver.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_forge.php b/system/database/drivers/sqlite3/sqlite3_forge.php
new file mode 100644
index 0000000..f8bd116
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_forge.php
@@ -0,0 +1,203 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst.  It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Forge Class
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @param	string	the database name
+	 * @return	bool
+	 */
+	public function create_database($db_name = '')
+	{
+		// In SQLite, a database is created when you connect to the database.
+		// We'll return TRUE so that an error isn't generated
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @param	string	the database name (ignored)
+	 * @return	bool
+	 */
+	public function drop_database($db_name = '')
+	{
+		// In SQLite, a database is dropped when we delete a file
+		if (@file_exists($this->db->database))
+		{
+			// We need to close the pseudo-connection first
+			$this->db->close();
+			if ( ! @unlink($this->db->database))
+			{
+				return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE;
+			}
+
+			return TRUE;
+		}
+
+		return $this->db->db_debug ? $this->db->display_error('db_unable_to_drop') : FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	{
+		$sql = 'CREATE TABLE ';
+
+		// IF NOT EXISTS added to SQLite in 3.3.0
+		if ($if_not_exists === TRUE && version_compare($this->db->version(), '3.3.0', '>=') === TRUE)
+		{
+			$sql .= 'IF NOT EXISTS ';
+		}
+
+		$sql .= $this->db->escape_identifiers($table).' (';
+		$current_field_count = 0;
+
+		foreach ($fields as $field => $attributes)
+		{
+			// Numeric field names aren't allowed in databases, so if the key is
+			// numeric, we know it was assigned by PHP and the developer manually
+			// entered the field information, so we'll simply add it to the list
+			if (is_numeric($field))
+			{
+				$sql .= "\n\t".$attributes;
+			}
+			else
+			{
+				$attributes = array_change_key_case($attributes, CASE_UPPER);
+
+				$sql .= "\n\t".$this->db->escape_identifiers($field).' '.$attributes['TYPE'];
+
+				empty($attributes['CONSTRAINT']) OR $sql .= '('.$attributes['CONSTRAINT'].')';
+
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+
+				if (isset($attributes['DEFAULT']))
+				{
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
+				}
+
+				$sql .= ( ! empty($attributes['NULL']) && $attributes['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
+
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
+				{
+					$sql .= ' AUTO_INCREMENT';
+				}
+			}
+
+			// don't add a comma on the end of the last field
+			if (++$current_field_count < count($fields))
+			{
+				$sql .= ',';
+			}
+		}
+
+		if (count($primary_keys) > 0)
+		{
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $this->db->escape_identifiers($primary_keys)).')';
+		}
+
+		if (is_array($keys) && count($keys) > 0)
+		{
+			foreach ($keys as $key)
+			{
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->db->escape_identifiers($key));
+
+				$sql .= ",\n\tUNIQUE (".implode(', ', $key).')';
+			}
+		}
+
+		return $sql."\n)";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Alter table query
+	 *
+	 * Generates a platform-specific query so that a table can be altered
+	 * Called by add_column(), drop_column(), and column_alter(),
+	 *
+	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
+	 * @param	string	the column name
+	 * @param	string	the table name
+	 * @param	string	the column definition
+	 * @param	string	the default value
+	 * @param	bool	should 'NOT NULL' be added
+	 * @param	string	the field after which we should add the new field
+	 * @return	string
+	 */
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	{
+		/* SQLite only supports adding new columns and it does
+		 * NOT support the AFTER statement. Each new column will
+		 * be added as the last one in the table.
+		 */
+		if ($alter_type !== 'ADD COLUMN')
+		{
+			// Not supported
+			return FALSE;
+		}
+
+		return 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' '.$this->db->escape_identifiers($column_name)
+			.' '.$column_definition
+			.($default_value !== '' ? ' DEFAULT '.$default_value : '')
+			// If NOT NULL is specified, the field must have a DEFAULT value other than NULL
+			.(($null !== NULL && $default_value !== 'NULL') ? ' NOT NULL' : ' NULL');
+	}
+
+}
+
+/* End of file sqlite3_forge.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_result.php b/system/database/drivers/sqlite3/sqlite3_result.php
new file mode 100644
index 0000000..946b365
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_result.php
@@ -0,0 +1,615 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst.  It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_result extends CI_DB_result {
+
+	// Overwriting the parent here, so we have a way to know if it's already set
+	public $num_rows;
+
+	// num_fields() might be called multiple times, so we'll use this one to cache it's result
+	protected $_num_fields;
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @return	int
+	 */
+	public function num_rows()
+	{
+		/* The SQLite3 driver doesn't have a graceful way to do this,
+		 * so we'll have to do it on our own.
+		 */
+		return is_int($this->num_rows)
+			? $this->num_rows
+			: $this->num_rows = count($this->result_array());
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @return	int
+	 */
+	public function num_fields()
+	{
+		return ( ! is_int($this->_num_fields))
+			? $this->_num_fields = $this->result_id->numColumns()
+			: $this->_num_fields;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @return	array
+	 */
+	public function list_fields()
+	{
+		$field_names = array();
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
+		{
+			$field_names[] = $this->result_id->columnName($i);
+		}
+
+		return $field_names;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data
+	 *
+	 * Generates an array of objects containing field meta-data
+	 *
+	 * @return	array
+	 */
+	public function field_data()
+	{
+		$retval = array();
+		for ($i = 0, $c = $this->num_fields(); $i < $this->num_fields(); $i++)
+		{
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $this->result_id->columnName($i);
+			$retval[$i]->type		= 'varchar';
+			$retval[$i]->max_length		= 0;
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
+		}
+
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	void
+	 */
+	public function free_result()
+	{
+		if (is_object($this->result_id))
+		{
+			$this->result_id->finalize();
+			$this->result_id = NULL;
+		}
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @return	array
+	 */
+	protected function _fetch_assoc()
+	{
+		return $this->result_id->fetchArray(SQLITE3_ASSOC);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @return	object
+	 */
+	protected function _fetch_object()
+	{
+		// No native support for fetching as an object
+		$row = $this->_fetch_assoc();
+		return ($row !== FALSE) ? (object) $row : FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. "array" version.
+	 *
+	 * return	array
+	 */
+	public function result_array()
+	{
+		if (count($this->result_array) > 0)
+		{
+			return $this->result_array;
+		}
+		elseif (is_array($this->row_data))
+		{
+			if (count($this->row_data) === 0)
+			{
+				return $this->result_array;
+			}
+			else
+			{
+				$row_index = count($this->row_data);
+			}
+		}
+		else
+		{
+			$row_index = 0;
+			$this->row_data = array();
+		}
+
+		$row = NULL;
+		while ($row = $this->_fetch_assoc())
+		{
+			$this->row_data[$row_index++] = $row;
+		}
+
+		return $this->result_array = $this->row_data;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. "object" version.
+	 *
+	 * @return	array
+	 */
+	public function result_object()
+	{
+		if (count($this->result_object) > 0)
+		{
+			return $this->result_object;
+		}
+		elseif (count($this->result_array) > 0)
+		{
+			for ($i = 0, $c = count($this->result_array); $i < $c; $i++)
+			{
+				$this->result_object[] = (object) $this->result_array[$i];
+			}
+
+			return $this->result_object;
+		}
+		elseif (is_array($this->row_data))
+		{
+			if (count($this->row_data) === 0)
+			{
+				return $this->result_object;
+			}
+			else
+			{
+				$row_index = count($this->row_data);
+				for ($i = 0; $i < $row_index; $i++)
+				{
+					$this->result_object[$i] = (object) $this->row_data[$i];
+				}
+			}
+		}
+		else
+		{
+			$row_index = 0;
+			$this->row_data = array();
+		}
+
+		$row = NULL;
+		while ($row = $this->_fetch_assoc())
+		{
+			$this->row_data[$row_index] = $row;
+			$this->result_object[$row_index++] = (object) $row;
+		}
+
+		$this->result_array = $this->row_data;
+
+		/* As described for the num_rows() method - there's no easy
+		 * way to get the number of rows selected. Our work-around
+		 * solution (as in here as well) first checks if result_array
+		 * exists and returns its count. It doesn't however check for
+		 * custom_object_result, so - do it here.
+		 */
+		if ( ! is_int($this->num_rows))
+		{
+			$this->num_rows = count($this->result_object);
+		}
+
+		return $this->result_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result. Custom object version.
+	 *
+	 * @param	string	class name used to instantiate rows to
+	 * @return	array
+	 */
+	public function custom_result_object($class_name)
+	{
+		if (array_key_exists($class_name, $this->custom_result_object))
+		{
+			return $this->custom_result_object[$class_name];
+		}
+
+		if ( ! class_exists($class_name) OR ! is_object($this->result_id) OR $this->num_rows() === 0)
+		{
+			return array();
+		}
+
+		/* Even if result_array hasn't been set prior to custom_result_object being called,
+		 * num_rows() has done it.
+		*/
+		$data = &$this->result_array;
+
+		$result_object = array();
+		for ($i = 0, $c = count($data); $i < $c; $i++)
+		{
+			$result_object[$i] = new $class_name();
+			foreach ($data[$i] as $key => $value)
+			{
+				$result_object[$i]->$key = $value;
+			}
+		}
+
+		/* As described for the num_rows() method - there's no easy
+		 * way to get the number of rows selected. Our work-around
+		 * solution (as in here as well) first checks if result_array
+		 * exists and returns its count. It doesn't however check for
+		 * custom_object_result, so - do it here.
+		 */
+		if ( ! is_int($this->num_rows))
+		{
+			$this->num_rows = count($result_object);
+		}
+
+		// Cache and return the array
+		return $this->custom_result_object[$class_name] = $result_object;
+        }
+
+	// --------------------------------------------------------------------
+
+	/* Single row result.
+	 *
+	 * Acts as a wrapper for row_object(), row_array()
+	 * and custom_row_object(). Also used by first_row(), next_row()
+	 * and previous_row().
+	 *
+	 * @param	int	row index
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function row($n = 0, $type = 'object')
+	{
+		if ($type === 'object')
+		{
+			return $this->row_object($n);
+		}
+		elseif ($type === 'array')
+		{
+			return $this->row_array($n);
+		}
+
+		return $this->custom_row_object($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Array version.
+	 *
+	 * @param	int	row index
+	 * @return	array
+	 */
+	public function row_array($n = 0)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		/* If row_data is initialized, it means that we've already tried
+		 * (at least) to fetch some data, so ... check if we already have
+		 * this row.
+		*/
+		if (is_array($this->row_data))
+		{
+			/* If we already have row_data[$n] - return it.
+			 *
+			 * If we enter the elseif, there's a number of reasons to
+			 * return an empty array:
+			 *
+			 *	- count($this->row_data) === 0 means there are no results
+			 *	- num_rows being set or result_array having count() > 0 means
+			 *	  that we've already fetched all data and $n is greater than
+			 *	  our highest row index available
+			 *	- $n < $this->current_row means that if such row existed,
+			 *	  we would've already returned it, therefore $n is an
+			 *	  invalid index
+			 */
+			if (isset($this->row_data[$n])) // We already have this row
+			{
+				$this->current_row = $n;
+				return $this->row_data[$n];
+			}
+			elseif (count($this->row_data) === 0 OR is_int($this->num_rows)
+				OR count($this->result_array) > 0 OR $n < $this->current_row)
+			{
+				// No such row exists
+				return NULL;
+			}
+
+			// Get the next row index that would actually need to be fetched
+			$current_row = ($this->current_row < count($this->row_data)) ? count($this->row_data) : $this->current_row + 1;
+		}
+		else
+		{
+			$current_row = $this->current_row = 0;
+			$this->row_data = array();
+		}
+
+		/* Fetch more data, if available
+		 *
+		 * NOTE: Operator precedence is important here, if you change
+		 *	 'AND' with '&&' - it WILL BREAK the results, as
+		 *	 $row will be assigned the scalar value of both
+		 *	 expressions!
+		 */
+		while ($row = $this->_fetch_assoc() AND $current_row <= $n)
+		{
+			$this->row_data[$current_row++] = $row;
+		}
+
+		// This would mean that there's no (more) data to fetch
+		if ( ! is_array($this->row_data) OR ! isset($this->row_data[$n]))
+		{
+			// Cache what we already have
+			if (is_array($this->row_data))
+			{
+				$this->num_rows = count($this->row_data);
+				/* Usually, row_data could have less elements than result_array,
+				 * but at this point - they should be exactly the same.
+				 */
+				$this->result_array = $this->row_data;
+			}
+			else
+			{
+				$this->num_rows = 0;
+			}
+
+			return NULL;
+		}
+
+		$this->current_row = $n;
+		return $this->row_data[$n];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Object version.
+	 *
+	 * @param	int	row index
+	 * @return	mixed	object if row found; empty array if not
+	 */
+	public function row_object($n = 0)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		/* Logic here is exactly the same as in row_array,
+		 * except we have to cast row_data[$n] to an object.
+		 *
+		 * If we already have result_object though - we can
+		 * directly return from it.
+		 */
+		if (isset($this->result_object[$n]))
+		{
+			$this->current_row = $n;
+			return $this->result_object[$n];
+		}
+
+		$row = $this->row_array($n);
+		// Cast only if the row exists
+		if (count($row) > 0)
+		{
+			$this->current_row = $n;
+			return (object) $row;
+		}
+
+		return NULL;
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Single row result. Custom object version.
+	 *
+	 * @param	int	row index
+	 * @param	string	custom class name
+	 * @return	mixed	custom object if row found; empty array otherwise
+	 */
+	public function custom_row_object($n = 0, $class_name)
+	{
+		// Make sure $n is not a string
+		if ( ! is_int($n))
+		{
+			$n = (int) $n;
+		}
+
+		if (array_key_exists($class_name, $this->custom_result_object))
+		{
+			/* We already have a the whole result set with this class_name,
+			 * return the specified row if it exists, and an empty array if
+			 * it doesn't.
+			 */
+			if (isset($this->custom_result_object[$class_name][$n]))
+			{
+				$this->current_row = $n;
+				return $this->custom_result_object[$class_name][$n];
+			}
+			else
+			{
+				return NULL;
+			}
+		}
+		elseif ( ! class_exists($class_name)) // No such class exists
+		{
+			return NULL;
+		}
+
+		$row = $this->row_array($n);
+		// A non-array would mean that the row doesn't exist
+		if ( ! is_array($row))
+		{
+			return NULL;
+		}
+
+		// Convert to the desired class and return
+		$row_object = new $class_name();
+		foreach ($row as $key => $value)
+		{
+			$row_object->$key = $value;
+		}
+
+		$this->current_row = $n;
+		return $row_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/* First row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function first_row($type = 'object')
+	{
+		return $this->row(0, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Last row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function last_row($type = 'object')
+	{
+		$result = &$this->result($type);
+		if ( ! isset($this->num_rows))
+		{
+			$this->num_rows = count($result);
+		}
+		$this->current_row = $this->num_rows - 1;
+		return $result[$this->current_row];
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Next row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function next_row($type = 'object')
+	{
+		if (is_array($this->row_data))
+		{
+			$count = count($this->row_data);
+			$n = ($this->current_row > $count OR ($this->current_row === 0 && $count === 0)) ? $count : $this->current_row + 1;
+		}
+		else
+		{
+			$n = 0;
+		}
+
+		return $this->row($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/* Previous row result.
+	 *
+	 * @param	string	('object', 'array' or a custom class name)
+	 * @return	mixed	whatever was passed to the second parameter
+	 */
+	public function previous_row($type = 'object')
+	{
+		$n = ($this->current_row !== 0) ? $this->current_row - 1 : 0;
+		return $this->row($n, $type);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Data Seek
+	 *
+	 * Moves the internal pointer to the desired offset. We call
+	 * this internally before fetching results to make sure the
+	 * result set starts at zero
+	 *
+	 * @return	array
+	 */
+	protected function _data_seek($n = 0)
+	{
+		// Only resetting to the start of the result set is supported
+		return $this->result_id->reset();
+	}
+
+}
+
+/* End of file sqlite3_result.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlite3/sqlite3_utility.php b/system/database/drivers/sqlite3/sqlite3_utility.php
new file mode 100644
index 0000000..965c838
--- /dev/null
+++ b/system/database/drivers/sqlite3/sqlite3_utility.php
@@ -0,0 +1,54 @@
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+/**
+ * CodeIgniter
+ *
+ * An open source application development framework for PHP 5.1.6 or newer
+ *
+ * NOTICE OF LICENSE
+ *
+ * Licensed under the Open Software License version 3.0
+ *
+ * This source file is subject to the Open Software License (OSL 3.0) that is
+ * bundled with this package in the files license.txt / license.rst.  It is
+ * also available through the world wide web at this URL:
+ * http://opensource.org/licenses/OSL-3.0
+ * If you did not receive a copy of the license and are unable to obtain it
+ * through the world wide web, please send an email to
+ * licensing@ellislab.com so we can send you a copy immediately.
+ *
+ * @package		CodeIgniter
+ * @author		EllisLab Dev Team
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
+ * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 1.0
+ * @filesource
+ */
+
+/**
+ * SQLite3 Utility Class
+ *
+ * @category	Database
+ * @author	Andrey Andreev
+ * @link	http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_sqlite3_utility extends CI_DB_utility {
+
+	protected $_list_databases	= FALSE;
+
+	/**
+	 * SQLite Export
+	 *
+	 * @param	array	Preferences
+	 * @return	mixed
+	 */
+	protected function _backup($params = array())
+	{
+		// Not supported
+		return $this->db->display_error('db_unsuported_feature');
+	}
+
+}
+
+/* End of file sqlite3_utility.php */
+/* Location: ./system/database/drivers/sqlite3/sqlite3_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 9f2f886..655a9e9 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -29,7 +29,7 @@
  * SQLSRV Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
- * creates dynamically based on whether the active record
+ * creates dynamically based on whether the query builder
  * class is being used or not.
  *
  * @package		CodeIgniter
@@ -43,7 +43,7 @@
 	public $dbdriver = 'sqlsrv';
 
 	// The character used for escaping
-	protected $_escape_char = '';
+	protected $_escape_char = '"';
 
 	// clause and character used for LIKE escape sequences
 	protected $_like_escape_str = " ESCAPE '%s' ";
@@ -55,7 +55,10 @@
 	 * used for the count_all() and count_all_results() functions.
 	 */
 	protected $_count_string = 'SELECT COUNT(*) AS ';
-	protected $_random_keyword = ' ASC'; // not currently supported
+	protected $_random_keyword = ' NEWID()';
+
+	// SQLSRV-specific properties
+	protected $_quoted_identifier = TRUE;
 
 	/**
 	 * Non-persistent database connection
@@ -68,12 +71,12 @@
 		$character_set = (0 === strcasecmp('utf8', $this->char_set)) ? 'UTF-8' : $this->char_set;
 
 		$connection = array(
-			'UID'				=> empty($this->username) ? '' : $this->username,
-			'PWD'				=> empty($this->password) ? '' : $this->password,
-			'Database'			=> $this->database,
-			'ConnectionPooling' => $pooling ? 1 : 0,
+			'UID'			=> empty($this->username) ? '' : $this->username,
+			'PWD'			=> empty($this->password) ? '' : $this->password,
+			'Database'		=> $this->database,
+			'ConnectionPooling'	=> $pooling ? 1 : 0,
 			'CharacterSet'		=> $character_set,
-			'ReturnDatesAsStrings' => 1
+			'ReturnDatesAsStrings'	=> 1
 		);
 
 		// If the username and password are both empty, assume this is a
@@ -83,7 +86,15 @@
 			unset($connection['UID'], $connection['PWD']);
 		}
 
-		return sqlsrv_connect($this->hostname, $connection);
+		$conn_id = sqlsrv_connect($this->hostname, $connection);
+
+		// Determine how identifiers are escaped
+		$query = $this->query('SELECT CASE WHEN (@@OPTIONS | 256) = @@OPTIONS THEN 1 ELSE 0 END AS qi');
+		$query = $query->row_array();
+		$this->_quoted_identifier = empty($query) ? FALSE : (bool) $query->qi;
+		$this->_escape_char = ($this->_quoted_identifier) ? '"' : array('[', ']');
+
+		return $conn_id;
 	}
 
 	// --------------------------------------------------------------------
@@ -132,11 +143,9 @@
 	 */
 	protected function _execute($sql)
 	{
-		return sqlsrv_query($this->conn_id,
-					$sql,
-					NULL,
-					array('Scrollable'=> SQLSRV_CURSOR_STATIC, 'SendStreamParamsAtExec' => TRUE)
-			);
+		return (is_write_type($sql) && stripos($sql, 'INSERT') === FALSE)
+			? sqlsrv_query($this->conn_id, $sql)
+			: sqlsrv_query($this->conn_id, $sql, NULL, array('Scrollable' => SQLSRV_CURSOR_STATIC));
 	}
 
 	// --------------------------------------------------------------------
@@ -148,13 +157,8 @@
 	 */
 	public function trans_begin($test_mode = FALSE)
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -162,7 +166,7 @@
 		// Reset the transaction failure flag.
 		// If the $test_mode flag is set to TRUE transactions will be rolled back
 		// even if the queries produce a successful result.
-		$this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE;
+		$this->_trans_failure = ($test_mode === TRUE);
 
 		return sqlsrv_begin_transaction($this->conn_id);
 	}
@@ -176,13 +180,8 @@
 	 */
 	public function trans_commit()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -199,13 +198,8 @@
 	 */
 	public function trans_rollback()
 	{
-		if ( ! $this->trans_enabled)
-		{
-			return TRUE;
-		}
-
 		// When transactions are nested we only begin/commit/rollback the outermost ones
-		if ($this->_trans_depth > 0)
+		if ( ! $this->trans_enabled OR $this->_trans_depth > 0)
 		{
 			return TRUE;
 		}
@@ -237,7 +231,7 @@
 	 */
 	public function affected_rows()
 	{
-		return @sqlrv_rows_affected($this->conn_id);
+		return sqlrv_rows_affected($this->result_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -259,23 +253,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Parse major version
-	 *
-	 * Grabs the major version number from the
-	 * database server version string passed in.
-	 *
-	 * @param	string	$version
-	 * @return	int	major version number
-	 */
-	protected function _parse_major_version($version)
-	{
-		preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info);
-		return $ver_info[1]; // return the major version b/c that's all we're interested in.
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Database version number
 	 *
 	 * @return	string
@@ -298,35 +275,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * "Count All" query
-	 *
-	 * Generates a platform-specific query string that counts all records in
-	 * the specified database
-	 *
-	 * @param	string
-	 * @return	int
-	 */
-	public function count_all($table = '')
-	{
-		if ($table == '')
-		{
-			return 0;
-		}
-
-		$query = $this->query("SELECT COUNT(*) AS numrows FROM " . $this->dbprefix . $table);
-		if ($query->num_rows() == 0)
-		{
-			return 0;
-		}
-
-		$row = $query->row();
-		$this->_reset_select();
-		return (int) $row->numrows;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * List table query
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
@@ -410,21 +358,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Escape the SQL Identifiers
-	 *
-	 * This function escapes column and table names
-	 *
-	 * @param	string
-	 * @return	string
-	 */
-	public function _escape_identifiers($item)
-	{
-		return $item;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * From Tables
 	 *
 	 * This function implicitly groups FROM tables so there is no confusion
@@ -435,29 +368,7 @@
 	 */
 	protected function _from_tables($tables)
 	{
-		if ( ! is_array($tables))
-		{
-			$tables = array($tables);
-		}
-
-		return implode(', ', $tables);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Insert statement
-	 *
-	 * Generates a platform-specific insert string from the supplied data
-	 *
-	 * @param	string	the table name
-	 * @param	array	the insert keys
-	 * @param	array	the insert values
-	 * @return	string
-	 */
-	protected function _insert($table, $keys, $values)
-	{
-		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
+		return is_array($tables) ? implode(', ', $tables) : $tables;
 	}
 
 	// --------------------------------------------------------------------
@@ -470,18 +381,26 @@
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
-	 * @param	array	the orderby clause
-	 * @param	array	the limit clause
+	 * @param	array	the orderby clause (ignored)
+	 * @param	array	the limit clause (ignored)
+	 * @param	array	the like clause
 	 * @return	string
 	 */
-	protected function _update($table, $values, $where)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
-		foreach($values as $key => $val)
+		foreach ($values as $key => $val)
 		{
-			$valstr[] = $key." = ".$val;
+			$valstr[] = $key.' = '.$val;
 		}
 
-		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).' WHERE '.implode(' ', $where);
+		$where = empty($where) ? '' : ' WHERE '.implode(' ', $where);
+
+		if ( ! empty($like))
+		{
+			$where .= ($where === '' ? ' WHERE ' : ' AND ').implode(' ', $like);
+		}
+
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where;
 	}
 
 	// --------------------------------------------------------------------
@@ -490,15 +409,16 @@
 	 * Truncate statement
 	 *
 	 * Generates a platform-specific truncate string from the supplied data
-	 * If the database does not support the truncate() command
-	 * This function maps to "DELETE FROM table"
+	 *
+	 * If the database does not support the truncate() command,
+	 * then this method maps to 'DELETE FROM table'
 	 *
 	 * @param	string	the table name
 	 * @return	string
 	 */
 	protected function _truncate($table)
 	{
-		return "TRUNCATE ".$table;
+		return 'TRUNCATE TABLE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -510,12 +430,22 @@
 	 *
 	 * @param	string	the table name
 	 * @param	array	the where clause
+	 * @param	array	the like clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	protected function _delete($table, $where)
+	protected function _delete($table, $where = array(), $like = array(), $limit = FALSE)
 	{
-		return 'DELETE FROM '.$table.' WHERE '.implode(' ', $where);
+		$conditions = array();
+
+		empty($where) OR $conditions[] = implode(' ', $where);
+		empty($like) OR $conditions[] = implode(' ', $like);
+
+		$conditions = (count($conditions) > 0) ? ' WHERE '.implode(' AND ', $conditions) : '';
+
+		return ($limit)
+			? 'WITH ci_delete AS (SELECT TOP '.$limit.' * FROM '.$table.$conditions.') DELETE FROM ci_delete'
+			: 'DELETE FROM '.$table.$conditions;
 	}
 
 	// --------------------------------------------------------------------
@@ -532,7 +462,10 @@
 	 */
 	protected function _limit($sql, $limit, $offset)
 	{
-		return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.($limit + $offset).' ', $sql);
+		// As of SQL Server 2012 (11.0.*) OFFSET is supported
+		return version_compare($this->version(), '11', '>=')
+			? $sql.' OFFSET '.(int) $offset.' ROWS FETCH NEXT '.(int) $limit.' ROWS ONLY'
+			: preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.($limit + $offset).' ', $sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -540,12 +473,11 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @param	resource
 	 * @return	void
 	 */
-	protected function _close($conn_id)
+	protected function _close()
 	{
-		@sqlsrv_close($conn_id);
+		@sqlsrv_close($this->conn_id);
 	}
 
 }
diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php
index 0dc7b52..e6f7e1a 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_forge.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php
@@ -34,43 +34,7 @@
  */
 class CI_DB_sqlsrv_forge extends CI_DB_forge {
 
-	/**
-	 * Create database
-	 *
-	 * @param	string	the database name
-	 * @return	string
-	 */
-	public function _create_database($name)
-	{
-		return "CREATE DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop database
-	 *
-	 * @param	string	the database name
-	 * @return	bool
-	 */
-	public function _drop_database($name)
-	{
-		return "DROP DATABASE ".$name;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Drop Table
-	 *
-	 * @return	bool
-	 */
-	public function _drop_table($table)
-	{
-		return "DROP TABLE ".$this->db->_escape_identifiers($table);
-	}
-
-	// --------------------------------------------------------------------
+	protected $_drop_table	= 'DROP TABLE %s';
 
 	/**
 	 * Create Table
@@ -80,20 +44,17 @@
 	 * @param	mixed	primary key(s)
 	 * @param	mixed	key(s)
 	 * @param	bool	should 'IF NOT EXISTS' be added to the SQL
-	 * @return	bool
+	 * @return	string
 	 */
-	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	protected function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
-		$sql = 'CREATE TABLE ';
+		$sql = ($if_not_exists === TRUE)
+			? "IF NOT EXISTS (SELECT * FROM sysobjects WHERE ID = object_id(N'".$table."') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)\n"
+			: '';
 
-		if ($if_not_exists === TRUE)
-		{
-			$sql .= 'IF NOT EXISTS ';
-		}
+		$sql .= 'CREATE TABLE '.$this->db->escape_identifiers($table).' (';
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
 		$current_field_count = 0;
-
 		foreach ($fields as $field => $attributes)
 		{
 			// Numeric field names aren't allowed in databases, so if the key is
@@ -101,41 +62,33 @@
 			// entered the field information, so we'll simply add it to the list
 			if (is_numeric($field))
 			{
-				$sql .= "\n\t$attributes";
+				$sql .= "\n\t".$attributes;
 			}
 			else
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
 
-				$sql .= "\n\t".$this->db->protect_identifiers($field);
+				$sql .= "\n\t".$this->db->escape_identifiers($field).' '.$attributes['TYPE'];
 
-				$sql .=  ' '.$attributes['TYPE'];
-
-				if (array_key_exists('CONSTRAINT', $attributes))
+				if (stripos($attributes['TYPE'], 'INT') === FALSE && ! empty($attributes['CONSTRAINT']))
 				{
 					$sql .= '('.$attributes['CONSTRAINT'].')';
 				}
 
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				if ( ! empty($attributes['UNSIGNED']) && $attributes['UNSIGNED'] === TRUE)
 				{
 					$sql .= ' UNSIGNED';
 				}
 
-				if (array_key_exists('DEFAULT', $attributes))
+				if (isset($attributes['DEFAULT']))
 				{
-					$sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\'';
+					$sql .= " DEFAULT '".$attributes['DEFAULT']."'";
 				}
 
-				if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE)
-				{
-					$sql .= ' NULL';
-				}
-				else
-				{
-					$sql .= ' NOT NULL';
-				}
+				$sql .= ( ! empty($attributes['NULL']) && $attribues['NULL'] === TRUE)
+					? ' NULL' : ' NOT NULL';
 
-				if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE)
+				if ( ! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === TRUE)
 				{
 					$sql .= ' AUTO_INCREMENT';
 				}
@@ -150,30 +103,22 @@
 
 		if (count($primary_keys) > 0)
 		{
-			$primary_keys = $this->db->protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+			$sql .= ",\n\tPRIMARY KEY (".implode(', ', $this->db->escape_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
 		{
 			foreach ($keys as $key)
 			{
-				if (is_array($key))
-				{
-					$key = $this->db->protect_identifiers($key);
-				}
-				else
-				{
-					$key = array($this->db->protect_identifiers($key));
-				}
+				$key = is_array($key)
+					? $this->db->escape_identifiers($key)
+					: array($this->escape_identifiers($key));
 
-				$sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tFOREIGN KEY (".implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n)";
-
-		return $sql;
+		return $sql."\n)";
 	}
 
 	// --------------------------------------------------------------------
@@ -193,56 +138,20 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	string
 	 */
-	public function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
+	protected function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->protect_identifiers($table).' '.$alter_type.' '.$this->db->protect_identifiers($column_name);
+		$sql = 'ALTER TABLE '.$this->db->escape_identifiers($table).' '.$alter_type.' '.$this->db->escape_identifiers($column_name);
 
 		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
+		if ($alter_type === 'DROP')
 		{
 			return $sql;
 		}
 
-		$sql .= " $column_definition";
-
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
-
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			return $sql.' AFTER '.$this->db->protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Rename a table
-	 *
-	 * Generates a platform-specific query so that a table can be renamed
-	 *
-	 * @param	string	the old table name
-	 * @param	string	the new table name
-	 * @return	string
-	 */
-	public function _rename_table($table_name, $new_table_name)
-	{
-		// I think this syntax will work, but can find little documentation on renaming tables in MSSQL
-		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
+		return $sql.' '.$column_definition
+			.($default_value != '' ? ' DEFAULT "'.$default_value.'"' : '')
+			.($null === NULL ? ' NULL' : ' NOT NULL')
+			.($after_field != '' ? ' AFTER '.$this->db->escape_identifiers($after_field) : '');
 	}
 
 }
diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php
index 10d790e..f802383 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_result.php
@@ -92,12 +92,12 @@
 		$retval = array();
 		foreach (sqlsrv_field_metadata($this->result_id) as $offset => $field)
 		{
-			$F 				= new stdClass();
-			$F->name 		= $field['Name'];
-			$F->type 		= $field['Type'];
+			$F 		= new stdClass();
+			$F->name 	= $field['Name'];
+			$F->type 	= $field['Type'];
 			$F->max_length	= $field['Size'];
 			$F->primary_key = 0;
-			$F->default		= '';
+			$F->default	= '';
 
 			$retval[] = $F;
 		}
@@ -124,22 +124,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Data Seek
-	 *
-	 * Moves the internal pointer to the desired offset. We call
-	 * this internally before fetching results to make sure the
-	 * result set starts at zero
-	 *
-	 * @return	void
-	 */
-	protected function _data_seek($n = 0)
-	{
-		// Not implemented
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Result - associative array
 	 *
 	 * Returns the result set as an array
diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php
index 5830c62..5a71b16 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_utility.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php
@@ -34,55 +34,16 @@
  */
 class CI_DB_sqlsrv_utility extends CI_DB_utility {
 
-	/**
-	 * List databases
-	 *
-	 * @return	string
-	 */
-	public function _list_databases()
-	{
-		return "EXEC sp_helpdb"; // Can also be: EXEC sp_databases
-	}
-
-	// --------------------------------------------------------------------
+	protected $_list_databases	= 'EXEC sp_helpdb'; // Can also be: EXEC sp_databases
+	protected $_optimize_table	= 'ALTER INDEX all ON %s REORGANIZE';
 
 	/**
-	 * Optimize table query
-	 *
-	 * Generates a platform-specific query so that a table can be optimized
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _optimize_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Repair table query
-	 *
-	 * Generates a platform-specific query so that a table can be repaired
-	 *
-	 * @param	string	the table name
-	 * @return	bool
-	 */
-	public function _repair_table($table)
-	{
-		return FALSE; // Is this supported in MS SQL?
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * MSSQL Export
+	 * SQLSRV Export
 	 *
 	 * @param	array	Preferences
-	 * @return	mixed
+	 * @return	bool
 	 */
-	public function _backup($params = array())
+	protected function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php
index 6f56d9d..6a7c8e3 100644
--- a/system/helpers/array_helper.php
+++ b/system/helpers/array_helper.php
@@ -37,19 +37,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Element
- *
- * Lets you determine whether an array index is set and whether it has a value.
- * If the element is empty it returns FALSE (or whatever you specify as the default value.)
- *
- * @param	string
- * @param	array
- * @param	mixed
- * @return	mixed	depends on what the array contains
- */
 if ( ! function_exists('element'))
 {
+	/**
+	 * Element
+	 *
+	 * Lets you determine whether an array index is set and whether it has a value.
+	 * If the element is empty it returns FALSE (or whatever you specify as the default value.)
+	 *
+	 * @param	string
+	 * @param	array
+	 * @param	mixed
+	 * @return	mixed	depends on what the array contains
+	 */
 	function element($item, $array, $default = FALSE)
 	{
 		return empty($array[$item]) ? $default : $array[$item];
@@ -58,14 +58,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Random Element - Takes an array as input and returns a random element
- *
- * @param	array
- * @return	mixed	depends on what the array contains
- */
 if ( ! function_exists('random_element'))
 {
+	/**
+	 * Random Element - Takes an array as input and returns a random element
+	 *
+	 * @param	array
+	 * @return	mixed	depends on what the array contains
+	 */
 	function random_element($array)
 	{
 		return is_array($array) ? $array[array_rand($array)] : $array;
@@ -74,19 +74,19 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Elements
- *
- * Returns only the array items specified. Will return a default value if
- * it is not set.
- *
- * @param	array
- * @param	array
- * @param	mixed
- * @return	mixed	depends on what the array contains
- */
 if ( ! function_exists('elements'))
 {
+	/**
+	 * Elements
+	 *
+	 * Returns only the array items specified. Will return a default value if
+	 * it is not set.
+	 *
+	 * @param	array
+	 * @param	array
+	 * @param	mixed
+	 * @return	mixed	depends on what the array contains
+	 */
 	function elements($items, $array, $default = FALSE)
 	{
 		$return = array();
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index bdbc620..4676b2a 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -37,17 +37,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Create CAPTCHA
- *
- * @param	array	array of data for the CAPTCHA
- * @param	string	path to create the image in
- * @param	string	URL to the CAPTCHA image folder
- * @param	string	server path to font
- * @return	string
- */
 if ( ! function_exists('create_captcha'))
 {
+	/**
+	 * Create CAPTCHA
+	 *
+	 * @param	array	array of data for the CAPTCHA
+	 * @param	string	path to create the image in
+	 * @param	string	URL to the CAPTCHA image folder
+	 * @param	string	server path to font
+	 * @return	string
+	 */
 	function create_captcha($data = '', $img_path = '', $img_url = '', $font_path = '')
 	{
 		$defaults = array('word' => '', 'img_path' => '', 'img_url' => '', 'img_width' => '150', 'img_height' => '30', 'font_path' => '', 'expiration' => 7200);
@@ -64,7 +64,7 @@
 			}
 		}
 
-		if ($img_path == '' OR $img_url == ''
+		if ($img_path === '' OR $img_url === ''
 			OR ! @is_dir($img_path) OR ! is_writeable($img_path)
 			OR ! extension_loaded('gd'))
 		{
@@ -93,7 +93,7 @@
 		// Do we have a "word" yet?
 		// -----------------------------------
 
-		if ($word == '')
+		if ($word === '')
 		{
 			$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
 			$word = '';
@@ -156,7 +156,7 @@
 		//  Write the text
 		// -----------------------------------
 
-		$use_font = ($font_path != '' && file_exists($font_path) && function_exists('imagettftext'));
+		$use_font = ($font_path !== '' && file_exists($font_path) && function_exists('imagettftext'));
 		if ($use_font === FALSE)
 		{
 			$font_size = 5;
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
index 06560e7..f396c76 100644
--- a/system/helpers/cookie_helper.php
+++ b/system/helpers/cookie_helper.php
@@ -37,24 +37,24 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Set cookie
- *
- * Accepts seven parameters, or you can submit an associative
- * array in the first parameter containing all the values.
- *
- * @param	mixed
- * @param	string	the value of the cookie
- * @param	string	the number of seconds until expiration
- * @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
- * @param	bool	true makes the cookie accessible via http(s) only (no javascript)
- * @return	void
- */
 if ( ! function_exists('set_cookie'))
 {
+	/**
+	 * Set cookie
+	 *
+	 * Accepts seven parameters, or you can submit an associative
+	 * array in the first parameter containing all the values.
+	 *
+	 * @param	mixed
+	 * @param	string	the value of the cookie
+	 * @param	string	the number of seconds until expiration
+	 * @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
+	 * @param	bool	true makes the cookie accessible via http(s) only (no javascript)
+	 * @return	void
+	 */
 	function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE)
 	{
 		// Set the config file options
@@ -65,15 +65,15 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Fetch an item from the COOKIE array
- *
- * @param	string
- * @param	bool
- * @return	mixed
- */
 if ( ! function_exists('get_cookie'))
 {
+	/**
+	 * Fetch an item from the COOKIE array
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	mixed
+	 */
 	function get_cookie($index = '', $xss_clean = FALSE)
 	{
 		$CI =& get_instance();
@@ -84,17 +84,17 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Delete a COOKIE
- *
- * @param	mixed
- * @param	string	the cookie domain. Usually: .yourdomain.com
- * @param	string	the cookie path
- * @param	string	the cookie prefix
- * @return	void
- */
 if ( ! function_exists('delete_cookie'))
 {
+	/**
+	 * Delete a COOKIE
+	 *
+	 * @param	mixed
+	 * @param	string	the cookie domain. Usually: .yourdomain.com
+	 * @param	string	the cookie path
+	 * @param	string	the cookie prefix
+	 * @return	void
+	 */
 	function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '')
 	{
 		set_cookie($name, '', '', $domain, $path, $prefix);
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index 14d973f..3b0c328 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -37,17 +37,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Get "now" time
- *
- * Returns time() based on the timezone parameter or on the "timezone"
- * setting
- *
- * @param	string
- * @return	int
- */
 if ( ! function_exists('now'))
 {
+	/**
+	 * Get "now" time
+	 *
+	 * Returns time() based on the timezone parameter or on the "timezone"
+	 * setting
+	 *
+	 * @param	string
+	 * @return	int
+	 */
 	function now($timezone = NULL)
 	{
 		$CI			=& get_instance();
@@ -68,37 +68,37 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Convert MySQL Style Datecodes
- *
- * This function is identical to PHPs date() function,
- * except that it allows date codes to be formatted using
- * the MySQL style, where each code letter is preceded
- * with a percent sign:  %Y %m %d etc...
- *
- * The benefit of doing dates this way is that you don't
- * have to worry about escaping your text letters that
- * match the date codes.
- *
- * @param	string
- * @param	int
- * @return	int
- */
 if ( ! function_exists('mdate'))
 {
+	/**
+	 * Convert MySQL Style Datecodes
+	 *
+	 * This function is identical to PHPs date() function,
+	 * except that it allows date codes to be formatted using
+	 * the MySQL style, where each code letter is preceded
+	 * with a percent sign:  %Y %m %d etc...
+	 *
+	 * The benefit of doing dates this way is that you don't
+	 * have to worry about escaping your text letters that
+	 * match the date codes.
+	 *
+	 * @param	string
+	 * @param	int
+	 * @return	int
+	 */
 	function mdate($datestr = '', $time = '')
 	{
-		if ($datestr == '')
+		if ($datestr === '')
 		{
 			return '';
 		}
 
-		$time = ($time == '') ? now() : $time;
+		$time = ($time === '') ? now() : $time;
 
 		$datestr = str_replace(
 			'%\\',
 			'',
-			preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr)
+			preg_replace('/([a-z]+?){1}/i', '\\\\\\1', $datestr)
 		);
 
 		return date($datestr, $time);
@@ -107,17 +107,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Standard Date
- *
- * Returns a date formatted according to the submitted standard.
- *
- * @param	string	the chosen format
- * @param	int	Unix timestamp
- * @return	string
- */
 if ( ! function_exists('standard_date'))
 {
+	/**
+	 * Standard Date
+	 *
+	 * Returns a date formatted according to the submitted standard.
+	 *
+	 * @param	string	the chosen format
+	 * @param	int	Unix timestamp
+	 * @return	string
+	 */
 	function standard_date($fmt = 'DATE_RFC822', $time = '')
 	{
 		$formats = array(
@@ -144,19 +144,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Timespan
- *
- * Returns a span of seconds in this format:
- *	10 days 14 hours 36 minutes 47 seconds
- *
- * @param	int	a number of seconds
- * @param	int	Unix timestamp
- * @param	int	a number of display units
- * @return	string
- */
 if ( ! function_exists('timespan'))
 {
+	/**
+	 * Timespan
+	 *
+	 * Returns a span of seconds in this format:
+	 *	10 days 14 hours 36 minutes 47 seconds
+	 *
+	 * @param	int	a number of seconds
+	 * @param	int	Unix timestamp
+	 * @param	int	a number of display units
+	 * @return	string
+	 */
 	function timespan($seconds = 1, $time = '', $units = 7)
 	{
 		$CI =& get_instance();
@@ -259,18 +259,18 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Number of days in a month
- *
- * Takes a month/year as input and returns the number of days
- * for the given month/year. Takes leap years into consideration.
- *
- * @param	int	a numeric month
- * @param	int	a numeric year
- * @return	int
- */
 if ( ! function_exists('days_in_month'))
 {
+	/**
+	 * Number of days in a month
+	 *
+	 * Takes a month/year as input and returns the number of days
+	 * for the given month/year. Takes leap years into consideration.
+	 *
+	 * @param	int	a numeric month
+	 * @param	int	a numeric year
+	 * @return	int
+	 */
 	function days_in_month($month = 0, $year = '')
 	{
 		if ($month < 1 OR $month > 12)
@@ -278,14 +278,14 @@
 			return 0;
 		}
 
-		if ( ! is_numeric($year) OR strlen($year) != 4)
+		if ( ! is_numeric($year) OR strlen($year) !== 4)
 		{
 			$year = date('Y');
 		}
 
 		if ($month == 2)
 		{
-			if ($year % 400 == 0 OR ($year % 4 == 0 && $year % 100 != 0))
+			if ($year % 400 === 0 OR ($year % 4 === 0 && $year % 100 !== 0))
 			{
 				return 29;
 			}
@@ -298,58 +298,58 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Converts a local Unix timestamp to GMT
- *
- * @param	int	Unix timestamp
- * @return	int
- */
 if ( ! function_exists('local_to_gmt'))
 {
+	/**
+	 * Converts a local Unix timestamp to GMT
+	 *
+	 * @param	int	Unix timestamp
+	 * @return	int
+	 */
 	function local_to_gmt($time = '')
 	{
-		if ($time == '')
+		if ($time === '')
 		{
 			$time = time();
 		}
 
 		return mktime(
-			gmdate("H", $time),
-			gmdate("i", $time),
-			gmdate("s", $time),
-			gmdate("m", $time),
-			gmdate("d", $time),
-			gmdate("Y", $time)
+			gmdate('H', $time),
+			gmdate('i', $time),
+			gmdate('s', $time),
+			gmdate('m', $time),
+			gmdate('d', $time),
+			gmdate('Y', $time)
 		);
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Converts GMT time to a localized value
- *
- * Takes a Unix timestamp (in GMT) as input, and returns
- * at the local value based on the timezone and DST setting
- * submitted
- *
- * @param	int	Unix timestamp
- * @param	string	timezone
- * @param	bool	whether DST is active
- * @return	int
- */
 if ( ! function_exists('gmt_to_local'))
 {
+	/**
+	 * Converts GMT time to a localized value
+	 *
+	 * Takes a Unix timestamp (in GMT) as input, and returns
+	 * at the local value based on the timezone and DST setting
+	 * submitted
+	 *
+	 * @param	int	Unix timestamp
+	 * @param	string	timezone
+	 * @param	bool	whether DST is active
+	 * @return	int
+	 */
 	function gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE)
 	{
-		if ($time == '')
+		if ($time === '')
 		{
 			return now();
 		}
 
 		$time += timezones($timezone) * 3600;
 
-		if ($dst == TRUE)
+		if ($dst === TRUE)
 		{
 			$time += 3600;
 		}
@@ -360,14 +360,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Converts a MySQL Timestamp to Unix
- *
- * @param	int	Unix timestamp
- * @return	int
- */
 if ( ! function_exists('mysql_to_unix'))
 {
+	/**
+	 * Converts a MySQL Timestamp to Unix
+	 *
+	 * @param	int	Unix timestamp
+	 * @return	int
+	 */
 	function mysql_to_unix($time = '')
 	{
 		// We'll remove certain characters for backward compatibility
@@ -392,23 +392,23 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Unix to "Human"
- *
- * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM
- *
- * @param	int	Unix timestamp
- * @param	bool	whether to show seconds
- * @param	string	format: us or euro
- * @return	string
- */
 if ( ! function_exists('unix_to_human'))
 {
+	/**
+	 * Unix to "Human"
+	 *
+	 * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM
+	 *
+	 * @param	int	Unix timestamp
+	 * @param	bool	whether to show seconds
+	 * @param	string	format: us or euro
+	 * @return	string
+	 */
 	function unix_to_human($time = '', $seconds = FALSE, $fmt = 'us')
 	{
 		$r  = date('Y', $time).'-'.date('m', $time).'-'.date('d', $time).' ';
 
-		if ($fmt == 'us')
+		if ($fmt === 'us')
 		{
 			$r .= date('h', $time).':'.date('i', $time);
 		}
@@ -422,7 +422,7 @@
 			$r .= ':'.date('s', $time);
 		}
 
-		if ($fmt == 'us')
+		if ($fmt === 'us')
 		{
 			$r .= ' '.date('A', $time);
 		}
@@ -433,25 +433,24 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Convert "human" date to GMT
- *
- * Reverses the above process
- *
- * @param	string	format: us or euro
- * @return	int
- */
 if ( ! function_exists('human_to_unix'))
 {
+	/**
+	 * Convert "human" date to GMT
+	 *
+	 * Reverses the above process
+	 *
+	 * @param	string	format: us or euro
+	 * @return	int
+	 */
 	function human_to_unix($datestr = '')
 	{
-		if ($datestr == '')
+		if ($datestr === '')
 		{
 			return FALSE;
 		}
 
-		$datestr = trim($datestr);
-		$datestr = preg_replace("/\040+/", ' ', $datestr);
+		$datestr = preg_replace('/\040+/', ' ', trim($datestr));
 
 		if ( ! preg_match('/^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i', $datestr))
 		{
@@ -460,20 +459,20 @@
 
 		$split = explode(' ', $datestr);
 
-		$ex = explode("-", $split['0']);
+		$ex = explode('-', $split['0']);
 
-		$year  = (strlen($ex['0']) == 2) ? '20'.$ex['0'] : $ex['0'];
-		$month = (strlen($ex['1']) == 1) ? '0'.$ex['1']  : $ex['1'];
-		$day   = (strlen($ex['2']) == 1) ? '0'.$ex['2']  : $ex['2'];
+		$year  = (strlen($ex[0]) === 2) ? '20'.$ex[0] : $ex[0];
+		$month = (strlen($ex[1]) === 1) ? '0'.$ex[1]  : $ex[1];
+		$day   = (strlen($ex[2]) === 1) ? '0'.$ex[2]  : $ex[2];
 
-		$ex = explode(":", $split['1']);
+		$ex = explode(':', $split['1']);
 
-		$hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0'];
-		$min  = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1'];
+		$hour = (strlen($ex[0]) === 1) ? '0'.$ex[0] : $ex[0];
+		$min  = (strlen($ex[1]) === 1) ? '0'.$ex[1] : $ex[1];
 
-		if (isset($ex['2']) && preg_match('/[0-9]{1,2}/', $ex['2']))
+		if (isset($ex[2]) && preg_match('/[0-9]{1,2}/', $ex[2]))
 		{
-			$sec  = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2'];
+			$sec = (strlen($ex[2]) === 1) ? '0'.$ex[2] : $ex[2];
 		}
 		else
 		{
@@ -481,13 +480,13 @@
 			$sec = '00';
 		}
 
-		if (isset($split['2']))
+		if (isset($split[2]))
 		{
-			$ampm = strtolower($split['2']);
+			$ampm = strtolower($split[2]);
 
 			if (substr($ampm, 0, 1) === 'p' && $hour < 12)
 			{
-				$hour = $hour + 12;
+				$hour += 12;
 			}
 
 			if (substr($ampm, 0, 1) === 'a' && $hour == 12)
@@ -495,7 +494,7 @@
 				$hour =  '00';
 			}
 
-			if (strlen($hour) == 1)
+			if (strlen($hour) === 1)
 			{
 				$hour = '0'.$hour;
 			}
@@ -507,16 +506,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Turns many "reasonably-date-like" strings into something
- * that is actually useful. This only works for dates after unix epoch.
- *
- * @param	string	The terribly formatted date-like string
- * @param	string	Date format to return (same as php date function)
- * @return	string
- */
 if ( ! function_exists('nice_date'))
 {
+	/**
+	 * Turns many "reasonably-date-like" strings into something
+	 * that is actually useful. This only works for dates after unix epoch.
+	 *
+	 * @param	string	The terribly formatted date-like string
+	 * @param	string	Date format to return (same as php date function)
+	 * @return	string
+	 */
 	function nice_date($bad_date = '', $format = FALSE)
 	{
 		if (empty($bad_date))
@@ -527,7 +526,7 @@
 		// Date like: YYYYMM
 		if (preg_match('/^\d{6}$/', $bad_date))
 		{
-			if (in_array(substr($bad_date, 0, 2),array('19', '20')))
+			if (in_array(substr($bad_date, 0, 2), array('19', '20')))
 			{
 				$year  = substr($bad_date, 0, 4);
 				$month = substr($bad_date, 4, 2);
@@ -538,32 +537,32 @@
 				$year   = substr($bad_date, 2, 4);
 			}
 
-			return date($format, strtotime($year . '-' . $month . '-01'));
+			return date($format, strtotime($year.'-'.$month.'-01'));
 		}
 
 		// Date Like: YYYYMMDD
-		if (preg_match('/^\d{8}$/',$bad_date))
+		if (preg_match('/^\d{8}$/', $bad_date))
 		{
 			$month = substr($bad_date, 0, 2);
 			$day   = substr($bad_date, 2, 2);
 			$year  = substr($bad_date, 4, 4);
 
-			return date($format, strtotime($month . '/01/' . $year));
+			return date($format, strtotime($month.'/01/'.$year));
 		}
 
 		// Date Like: MM-DD-YYYY __or__ M-D-YYYY (or anything in between)
-		if (preg_match('/^\d{1,2}-\d{1,2}-\d{4}$/',$bad_date))
+		if (preg_match('/^\d{1,2}-\d{1,2}-\d{4}$/', $bad_date))
 		{
 			list($m, $d, $y) = explode('-', $bad_date);
-			return date($format, strtotime("{$y}-{$m}-{$d}"));
+			return date($format, strtotime($y.'-'.$m.'-'.$d));
 		}
 
 		// Any other kind of string, when converted into UNIX time,
 		// produces "0 seconds after epoc..." is probably bad...
 		// return "Invalid Date".
-		if (date('U', strtotime($bad_date)) == '0')
+		if (date('U', strtotime($bad_date)) === '0')
 		{
-			return "Invalid Date";
+			return 'Invalid Date';
 		}
 
 		// It's probably a valid-ish date format already
@@ -573,28 +572,28 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Timezone Menu
- *
- * Generates a drop-down menu of timezones.
- *
- * @param	string	timezone
- * @param	string	classname
- * @param	string	menu name
- * @return	string
- */
 if ( ! function_exists('timezone_menu'))
 {
-	function timezone_menu($default = 'UTC', $class = "", $name = 'timezones')
+	/**
+	 * Timezone Menu
+	 *
+	 * Generates a drop-down menu of timezones.
+	 *
+	 * @param	string	timezone
+	 * @param	string	classname
+	 * @param	string	menu name
+	 * @return	string
+	 */
+	function timezone_menu($default = 'UTC', $class = '', $name = 'timezones')
 	{
 		$CI =& get_instance();
 		$CI->lang->load('date');
 
-		$default = ($default == 'GMT') ? 'UTC' : $default;
+		$default = ($default === 'GMT') ? 'UTC' : $default;
 
 		$menu = '<select name="'.$name.'"';
 
-		if ($class != '')
+		if ($class !== '')
 		{
 			$menu .= ' class="'.$class.'"';
 		}
@@ -603,29 +602,27 @@
 
 		foreach (timezones() as $key => $val)
 		{
-			$selected = ($default == $key) ? " selected='selected'" : '';
-			$menu .= "<option value='{$key}'{$selected}>".$CI->lang->line($key)."</option>\n";
+			$selected = ($default === $key) ? ' selected="selected"' : '';
+			$menu .= '<option value="'.$key.'"'.$selected.'>'.$CI->lang->line($key)."</option>\n";
 		}
 
-		$menu .= "</select>";
-
-		return $menu;
+		return $menu.'</select>';
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Timezones
- *
- * Returns an array of timezones. This is a helper function
- * for various other ones in this library
- *
- * @param	string	timezone
- * @return	string
- */
 if ( ! function_exists('timezones'))
 {
+	/**
+	 * Timezones
+	 *
+	 * Returns an array of timezones. This is a helper function
+	 * for various other ones in this library
+	 *
+	 * @param	string	timezone
+	 * @return	string
+	 */
 	function timezones($tz = '')
 	{
 		// Note: Don't change the order of these even though
@@ -674,12 +671,12 @@
 			'UP14'		=> +14
 		);
 
-		if ($tz == '')
+		if ($tz === '')
 		{
 			return $zones;
 		}
 
-		$tz = ($tz == 'GMT') ? 'UTC' : $tz;
+		$tz = ($tz === 'GMT') ? 'UTC' : $tz;
 
 		return isset($zones[$tz]) ? $zones[$tz] : 0;
 	}
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
index 4044ace..e7d3b5e 100644
--- a/system/helpers/directory_helper.php
+++ b/system/helpers/directory_helper.php
@@ -37,19 +37,20 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Create a Directory Map
- *
- * Reads the specified directory and builds an array
- * representation of it. Sub-folders contained with the
- * directory will be mapped as well.
- *
- * @param	string	path to source
- * @param	int	depth of directories to traverse (0 = fully recursive, 1 = current dir, etc)
- * @return	array
- */
 if ( ! function_exists('directory_map'))
 {
+	/**
+	 * Create a Directory Map
+	 *
+	 * Reads the specified directory and builds an array
+	 * representation of it. Sub-folders contained with the
+	 * directory will be mapped as well.
+	 *
+	 * @param	string	path to source
+	 * @param	int	depth of directories to traverse (0 = fully recursive, 1 = current dir, etc)
+	 * @param	bool	whether to show hidden files
+	 * @return	array
+	 */
 	function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE)
 	{
 		if ($fp = @opendir($source_dir))
@@ -61,7 +62,7 @@
 			while (FALSE !== ($file = readdir($fp)))
 			{
 				// Remove '.', '..', and hidden files [optional]
-				if ( ! trim($file, '.') OR ($hidden == FALSE && $file[0] === '.'))
+				if ( ! trim($file, '.') OR ($hidden === FALSE && $file[0] === '.'))
 				{
 					continue;
 				}
diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php
index 19192a1..5efbc49 100644
--- a/system/helpers/download_helper.php
+++ b/system/helpers/download_helper.php
@@ -37,21 +37,21 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Force Download
- *
- * Generates headers that force a download to happen
- *
- * @param	string	filename
- * @param	mixed	the data to be downloaded
- * @param	bool	wether to try and send the actual file MIME type
- * @return	void
- */
 if ( ! function_exists('force_download'))
 {
+	/**
+	 * Force Download
+	 *
+	 * Generates headers that force a download to happen
+	 *
+	 * @param	string	filename
+	 * @param	mixed	the data to be downloaded
+	 * @param	bool	wether to try and send the actual file MIME type
+	 * @return	void
+	 */
 	function force_download($filename = '', $data = '', $set_mime = FALSE)
 	{
-		if ($filename == '' OR $data == '')
+		if ($filename === '' OR $data === '')
 		{
 			return FALSE;
 		}
@@ -73,14 +73,7 @@
 			}
 
 			// Load the mime types
-			if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
-			{
-				include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
-			}
-			elseif (is_file(APPPATH.'config/mimes.php'))
-			{
-				include(APPPATH.'config/mimes.php');
-			}
+			$mimes =& get_mimes();
 
 			// Only change the default MIME if we can find one
 			if (isset($mimes[$extension]))
@@ -101,6 +94,9 @@
 			$filename = implode('.', $x);
 		}
 
+		// Clean output buffer
+		ob_clean();
+
 		// Generate the server headers
 		header('Content-Type: '.$mime);
 		header('Content-Disposition: attachment; filename="'.$filename.'"');
diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php
index 497625c..0516e93 100644
--- a/system/helpers/email_helper.php
+++ b/system/helpers/email_helper.php
@@ -37,14 +37,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Validate email address
- *
- * @param	string
- * @return	bool
- */
 if ( ! function_exists('valid_email'))
 {
+	/**
+	 * Validate email address
+	 *
+	 * @param	string
+	 * @return	bool
+	 */
 	function valid_email($address)
 	{
 		return (bool) preg_match('/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix', $address);
@@ -53,16 +53,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Send an email
- *
- * @param	string
- * @param	string
- * @param	string
- * @return	bool
- */
 if ( ! function_exists('send_email'))
 {
+	/**
+	 * Send an email
+	 *
+	 * @param	string
+	 * @param	string
+	 * @param	string
+	 * @return	bool
+	 */
 	function send_email($recipient, $subject = 'Test email', $message = 'Hello World')
 	{
 		return mail($recipient, $subject, $message);
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 6e8a4de..be616f6 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -37,62 +37,40 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Read File
- *
- * Opens the file specfied in the path and returns it as a string.
- *
- * @param	string	path to file
- * @return	string
- */
 if ( ! function_exists('read_file'))
 {
+	/**
+	 * Read File
+	 *
+	 * Opens the file specfied in the path and returns it as a string.
+	 *
+	 * This function is DEPRECATED and should be removed in
+	 * CodeIgniter 3.1+. Use file_get_contents() instead.
+	 *
+	 * @param	string	path to file
+	 * @return	string
+	 */
 	function read_file($file)
 	{
-		if ( ! file_exists($file))
-		{
-			return FALSE;
-		}
-
-		if (function_exists('file_get_contents'))
-		{
-			return file_get_contents($file);
-		}
-
-		if ( ! $fp = @fopen($file, FOPEN_READ))
-		{
-			return FALSE;
-		}
-
-		flock($fp, LOCK_SH);
-
-		$data = '';
-		if (filesize($file) > 0)
-		{
-			$data =& fread($fp, filesize($file));
-		}
-
-		flock($fp, LOCK_UN);
-		fclose($fp);
-
-		return $data;
+		return @file_get_contents($file);
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Write File
- *
- * Writes data to the file specified in the path.
- * Creates a new file if non-existent.
- *
- * @param	string	path to file
- * @param	string	file data
- * @return	bool
- */
 if ( ! function_exists('write_file'))
 {
+	/**
+	 * Write File
+	 *
+	 * Writes data to the file specified in the path.
+	 * Creates a new file if non-existent.
+	 *
+	 * @param	string	path to file
+	 * @param	string	file data
+	 * @param	int
+	 * @return	bool
+	 */
 	function write_file($path, $data, $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE)
 	{
 		if ( ! $fp = @fopen($path, $mode))
@@ -111,21 +89,23 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Delete Files
- *
- * Deletes all files contained in the supplied directory path.
- * Files must be writable or owned by the system in order to be deleted.
- * If the second parameter is set to TRUE, any directories contained
- * within the supplied base directory will be nuked as well.
- *
- * @param	string	path to file
- * @param	bool	whether to delete any directories found in the path
- * @return	bool
- */
 if ( ! function_exists('delete_files'))
 {
-	function delete_files($path, $del_dir = FALSE, $level = 0)
+	/**
+	 * Delete Files
+	 *
+	 * Deletes all files contained in the supplied directory path.
+	 * Files must be writable or owned by the system in order to be deleted.
+	 * If the second parameter is set to TRUE, any directories contained
+	 * within the supplied base directory will be nuked as well.
+	 *
+	 * @param	string	path to file
+	 * @param	bool	whether to delete any directories found in the path
+	 * @param	int
+	 * @param	bool	whether to skip deleting .htaccess and index page files
+	 * @return	bool
+	 */
+	function delete_files($path, $del_dir = FALSE, $level = 0, $htdocs = FALSE)
 	{
 		// Trim the trailing slash
 		$path = rtrim($path, DIRECTORY_SEPARATOR);
@@ -141,9 +121,9 @@
 			{
 				if (is_dir($path.DIRECTORY_SEPARATOR.$filename) && $filename[0] !== '.')
 				{
-					delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1);
+					delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1, $htdocs);
 				}
-				else
+				elseif ($htdocs === TRUE && ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename))
 				{
 					@unlink($path.DIRECTORY_SEPARATOR.$filename);
 				}
@@ -151,7 +131,7 @@
 		}
 		@closedir($current_dir);
 
-		if ($del_dir == TRUE && $level > 0)
+		if ($del_dir === TRUE && $level > 0)
 		{
 			return @rmdir($path);
 		}
@@ -162,19 +142,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Get Filenames
- *
- * Reads the specified directory and builds an array containing the filenames.
- * Any sub-folders contained within the specified path are read as well.
- *
- * @param	string	path to source
- * @param	bool	whether to include the path as part of the filename
- * @param	bool	internal variable to determine recursion status - do not use in calls
- * @return	array
- */
 if ( ! function_exists('get_filenames'))
 {
+	/**
+	 * Get Filenames
+	 *
+	 * Reads the specified directory and builds an array containing the filenames.
+	 * Any sub-folders contained within the specified path are read as well.
+	 *
+	 * @param	string	path to source
+	 * @param	bool	whether to include the path as part of the filename
+	 * @param	bool	internal variable to determine recursion status - do not use in calls
+	 * @return	array
+	 */
 	function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)
 	{
 		static $_filedata = array();
@@ -196,7 +176,7 @@
 				}
 				elseif ($file[0] !== '.')
 				{
-					$_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;
+					$_filedata[] = ($include_path === TRUE) ? $source_dir.$file : $file;
 				}
 			}
 			closedir($fp);
@@ -210,21 +190,21 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Get Directory File Information
- *
- * Reads the specified directory and builds an array containing the filenames,
- * filesize, dates, and permissions
- *
- * Any sub-folders contained within the specified path are read as well.
- *
- * @param	string	path to source
- * @param	bool	Look only at the top level directory specified?
- * @param	bool	internal variable to determine recursion status - do not use in calls
- * @return	array
- */
 if ( ! function_exists('get_dir_file_info'))
 {
+	/**
+	 * Get Directory File Information
+	 *
+	 * Reads the specified directory and builds an array containing the filenames,
+	 * filesize, dates, and permissions
+	 *
+	 * Any sub-folders contained within the specified path are read as well.
+	 *
+	 * @param	string	path to source
+	 * @param	bool	Look only at the top level directory specified?
+	 * @param	bool	internal variable to determine recursion status - do not use in calls
+	 * @return	array
+	 */
 	function get_dir_file_info($source_dir, $top_level_only = TRUE, $_recursion = FALSE)
 	{
 		static $_filedata = array();
@@ -263,20 +243,20 @@
 
 // --------------------------------------------------------------------
 
-/**
-* Get File Info
-*
-* Given a file and path, returns the name, path, size, date modified
-* Second parameter allows you to explicitly declare what information you want returned
-* Options are: name, server_path, size, date, readable, writable, executable, fileperms
-* Returns FALSE if the file cannot be found.
-*
-* @param	string	path to file
-* @param	mixed	array or comma separated string of information returned
-* @return	array
-*/
 if ( ! function_exists('get_file_info'))
 {
+	/**
+	 * Get File Info
+	 *
+	 * Given a file and path, returns the name, path, size, date modified
+	 * Second parameter allows you to explicitly declare what information you want returned
+	 * Options are: name, server_path, size, date, readable, writable, executable, fileperms
+	 * Returns FALSE if the file cannot be found.
+	 *
+	 * @param	string	path to file
+	 * @param	mixed	array or comma separated string of information returned
+	 * @return	array
+	 */
 	function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date'))
 	{
 
@@ -328,54 +308,41 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Get Mime by Extension
- *
- * Translates a file extension into a mime type based on config/mimes.php.
- * Returns FALSE if it can't determine the type, or open the mime config file
- *
- * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience
- * It should NOT be trusted, and should certainly NOT be used for security
- *
- * @param	string	path to file
- * @return	mixed
- */
 if ( ! function_exists('get_mime_by_extension'))
 {
+	/**
+	 * Get Mime by Extension
+	 *
+	 * Translates a file extension into a mime type based on config/mimes.php.
+	 * Returns FALSE if it can't determine the type, or open the mime config file
+	 *
+	 * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience
+	 * It should NOT be trusted, and should certainly NOT be used for security
+	 *
+	 * @param	string	path to file
+	 * @return	mixed
+	 */
 	function get_mime_by_extension($file)
 	{
 		$extension = strtolower(substr(strrchr($file, '.'), 1));
 
-		global $mimes;
+		static $mimes;
 
 		if ( ! is_array($mimes))
 		{
-			if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
-			{
-				include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
-			}
-			elseif (is_file(APPPATH.'config/mimes.php'))
-			{
-				include(APPPATH.'config/mimes.php');
-			}
+			$mimes =& get_mimes();
 
-			if ( ! is_array($mimes))
+			if (empty($mimes))
 			{
 				return FALSE;
 			}
 		}
 
-		if (array_key_exists($extension, $mimes))
+		if (isset($mimes[$extension]))
 		{
-			if (is_array($mimes[$extension]))
-			{
-				// Multiple mime types, just give the first one
-				return current($mimes[$extension]);
-			}
-			else
-			{
-				return $mimes[$extension];
-			}
+			return is_array($mimes[$extension])
+				? current($mimes[$extension]) // Multiple mime types, just give the first one
+				: $mimes[$extension];
 		}
 
 		return FALSE;
@@ -384,17 +351,17 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Symbolic Permissions
- *
- * Takes a numeric value representing a file's permissions and returns
- * standard symbolic notation representing that value
- *
- * @param	int
- * @return	string
- */
 if ( ! function_exists('symbolic_permissions'))
 {
+	/**
+	 * Symbolic Permissions
+	 *
+	 * Takes a numeric value representing a file's permissions and returns
+	 * standard symbolic notation representing that value
+	 *
+	 * @param	int
+	 * @return	string
+	 */
 	function symbolic_permissions($perms)
 	{
 		if (($perms & 0xC000) === 0xC000)
@@ -451,17 +418,17 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Octal Permissions
- *
- * Takes a numeric value representing a file's permissions and returns
- * a three character string representing the file's octal permissions
- *
- * @param	int
- * @return	string
- */
 if ( ! function_exists('octal_permissions'))
 {
+	/**
+	 * Octal Permissions
+	 *
+	 * Takes a numeric value representing a file's permissions and returns
+	 * a three character string representing the file's octal permissions
+	 *
+	 * @param	int
+	 * @return	string
+	 */
 	function octal_permissions($perms)
 	{
 		return substr(sprintf('%o', $perms), -3);
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index e5b4876..9846343 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -36,23 +36,23 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Form Declaration
- *
- * Creates the opening portion of the form.
- *
- * @param	string	the URI segments of the form destination
- * @param	array	a key/value pair of attributes
- * @param	array	a key/value pair hidden data
- * @return	string
- */
 if ( ! function_exists('form_open'))
 {
+	/**
+	 * Form Declaration
+	 *
+	 * Creates the opening portion of the form.
+	 *
+	 * @param	string	the URI segments of the form destination
+	 * @param	array	a key/value pair of attributes
+	 * @param	array	a key/value pair hidden data
+	 * @return	string
+	 */
 	function form_open($action = '', $attributes = '', $hidden = array())
 	{
 		$CI =& get_instance();
 
-		if ($attributes == '')
+		if ($attributes === '')
 		{
 			$attributes = 'method="post"';
 		}
@@ -85,18 +85,18 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Form Declaration - Multipart type
- *
- * Creates the opening portion of the form, but with "multipart/form-data".
- *
- * @param	string	the URI segments of the form destination
- * @param	array	a key/value pair of attributes
- * @param	array	a key/value pair hidden data
- * @return	string
- */
 if ( ! function_exists('form_open_multipart'))
 {
+	/**
+	 * Form Declaration - Multipart type
+	 *
+	 * Creates the opening portion of the form, but with "multipart/form-data".
+	 *
+	 * @param	string	the URI segments of the form destination
+	 * @param	array	a key/value pair of attributes
+	 * @param	array	a key/value pair hidden data
+	 * @return	string
+	 */
 	function form_open_multipart($action = '', $attributes = array(), $hidden = array())
 	{
 		if (is_string($attributes))
@@ -114,18 +114,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Hidden Input Field
- *
- * Generates hidden fields. You can pass a simple key/value string or
- * an associative array with multiple values.
- *
- * @param	mixed
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_hidden'))
 {
+	/**
+	 * Hidden Input Field
+	 *
+	 * Generates hidden fields. You can pass a simple key/value string or
+	 * an associative array with multiple values.
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	function form_hidden($name, $value = '', $recursing = FALSE)
 	{
 		static $form;
@@ -163,16 +164,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Text Input Field
- *
- * @param	mixed
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_input'))
 {
+	/**
+	 * Text Input Field
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_input($data = '', $value = '', $extra = '')
 	{
 		$defaults = array('type' => 'text', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value);
@@ -183,18 +184,18 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Password Field
- *
- * Identical to the input function but adds the "password" type
- *
- * @param	mixed
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_password'))
 {
+	/**
+	 * Password Field
+	 *
+	 * Identical to the input function but adds the "password" type
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_password($data = '', $value = '', $extra = '')
 	{
 		if ( ! is_array($data))
@@ -209,18 +210,18 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Upload Field
- *
- * Identical to the input function but adds the "file" type
- *
- * @param	mixed
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_upload'))
 {
+	/**
+	 * Upload Field
+	 *
+	 * Identical to the input function but adds the "file" type
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_upload($data = '', $value = '', $extra = '')
 	{
 		if ( ! is_array($data))
@@ -235,16 +236,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Textarea field
- *
- * @param	mixed
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_textarea'))
 {
+	/**
+	 * Textarea field
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_textarea($data = '', $value = '', $extra = '')
 	{
 		$defaults = array('name' => ( ! is_array($data) ? $data : ''), 'cols' => '40', 'rows' => '10');
@@ -266,17 +267,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Multi-select menu
- *
- * @param	string
- * @param	array
- * @param	mixed
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_multiselect'))
 {
+	/**
+	 * Multi-select menu
+	 *
+	 * @param	string
+	 * @param	array
+	 * @param	mixed
+	 * @param	string
+	 * @return	string
+	 */
 	function form_multiselect($name = '', $options = array(), $selected = array(), $extra = '')
 	{
 		if ( ! strpos($extra, 'multiple'))
@@ -290,17 +291,17 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Drop-down Menu
- *
- * @param	string
- * @param	array
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_dropdown'))
 {
+	/**
+	 * Drop-down Menu
+	 *
+	 * @param	string
+	 * @param	array
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '')
 	{
 		// If name is really an array then we'll call the function again using the array
@@ -324,7 +325,10 @@
 			$selected = array($_POST[$name]);
 		}
 
-		if ($extra != '') $extra = ' '.$extra;
+		if ($extra != '')
+		{
+			$extra = ' '.$extra;
+		}
 
 		$multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : '';
 
@@ -358,17 +362,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Checkbox Field
- *
- * @param	mixed
- * @param	string
- * @param	bool
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_checkbox'))
 {
+	/**
+	 * Checkbox Field
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	bool
+	 * @param	string
+	 * @return	string
+	 */
 	function form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '')
 	{
 		$defaults = array('type' => 'checkbox', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value);
@@ -402,17 +406,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Radio Button
- *
- * @param	mixed
- * @param	string
- * @param	bool
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_radio'))
 {
+	/**
+	 * Radio Button
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	bool
+	 * @param	string
+	 * @return	string
+	 */
 	function form_radio($data = '', $value = '', $checked = FALSE, $extra = '')
 	{
 		if ( ! is_array($data))
@@ -427,16 +431,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Submit Button
- *
- * @param	mixed
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_submit'))
 {
+	/**
+	 * Submit Button
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_submit($data = '', $value = '', $extra = '')
 	{
 		$defaults = array('type' => 'submit', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value);
@@ -446,16 +450,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Reset Button
- *
- * @param	mixed
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_reset'))
 {
+	/**
+	 * Reset Button
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_reset($data = '', $value = '', $extra = '')
 	{
 		$defaults = array('type' => 'reset', 'name' => ( ! is_array($data) ? $data : ''), 'value' => $value);
@@ -465,16 +469,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Form Button
- *
- * @param	mixed
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_button'))
 {
+	/**
+	 * Form Button
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_button($data = '', $content = '', $extra = '')
 	{
 		$defaults = array('name' => ( ! is_array($data) ? $data : ''), 'type' => 'button');
@@ -490,22 +494,22 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Form Label Tag
- *
- * @param	string	The text to appear onscreen
- * @param	string	The id the label applies to
- * @param	string	Additional attributes
- * @return	string
- */
 if ( ! function_exists('form_label'))
 {
+	/**
+	 * Form Label Tag
+	 *
+	 * @param	string	The text to appear onscreen
+	 * @param	string	The id the label applies to
+	 * @param	string	Additional attributes
+	 * @return	string
+	 */
 	function form_label($label_text = '', $id = '', $attributes = array())
 	{
 
 		$label = '<label';
 
-		if ($id != '')
+		if ($id !== '')
 		{
 			$label .= ' for="'.$id.'"';
 		}
@@ -523,22 +527,23 @@
 }
 
 // ------------------------------------------------------------------------
-/**
- * Fieldset Tag
- *
- * Used to produce <fieldset><legend>text</legend>.  To close fieldset
- * use form_fieldset_close()
- *
- * @param	string	The legend text
- * @param	string	Additional attributes
- * @return	string
- */
+
 if ( ! function_exists('form_fieldset'))
 {
+	/**
+	 * Fieldset Tag
+	 *
+	 * Used to produce <fieldset><legend>text</legend>.  To close fieldset
+	 * use form_fieldset_close()
+	 *
+	 * @param	string	The legend text
+	 * @param	string	Additional attributes
+	 * @return	string
+	 */
 	function form_fieldset($legend_text = '', $attributes = array())
 	{
 		$fieldset = '<fieldset'._attributes_to_string($attributes, FALSE).">\n";
-		if ($legend_text != '')
+		if ($legend_text !== '')
 		{
 			return $fieldset.'<legend>'.$legend_text."</legend>\n";
 		}
@@ -549,14 +554,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Fieldset Close Tag
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_fieldset_close'))
 {
+	/**
+	 * Fieldset Close Tag
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function form_fieldset_close($extra = '')
 	{
 		return '</fieldset>'.$extra;
@@ -565,14 +570,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Form Close Tag
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_close'))
 {
+	/**
+	 * Form Close Tag
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function form_close($extra = '')
 	{
 		return '</form>'.$extra;
@@ -581,16 +586,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Form Prep
- *
- * Formats text so that it can be safely placed in a form field in the event it has HTML tags.
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('form_prep'))
 {
+	/**
+	 * Form Prep
+	 *
+	 * Formats text so that it can be safely placed in a form field in the event it has HTML tags.
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_prep($str = '', $field_name = '')
 	{
 		static $prepped_fields = array();
@@ -620,7 +626,7 @@
 			return $str;
 		}
 
-		if ($field_name != '')
+		if ($field_name !== '')
 		{
 			$prepped_fields[$field_name] = $field_name;
 		}
@@ -631,18 +637,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Form Value
- *
- * Grabs a value from the POST array for the specified field so you can
- * re-populate an input field or textarea. If Form Validation
- * is active it retrieves the info from the validation class
- *
- * @param	string
- * @return	mixed
- */
 if ( ! function_exists('set_value'))
 {
+	/**
+	 * Form Value
+	 *
+	 * Grabs a value from the POST array for the specified field so you can
+	 * re-populate an input field or textarea. If Form Validation
+	 * is active it retrieves the info from the validation class
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	mixed
+	 */
 	function set_value($field = '', $default = '')
 	{
 		if (FALSE === ($OBJ =& _get_validation_object()))
@@ -661,19 +668,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Set Select
- *
- * Let's you set the selected value of a <select> menu via data in the POST array.
- * If Form Validation is active it retrieves the info from the validation class
- *
- * @param	string
- * @param	string
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('set_select'))
 {
+	/**
+	 * Set Select
+	 *
+	 * Let's you set the selected value of a <select> menu via data in the POST array.
+	 * If Form Validation is active it retrieves the info from the validation class
+	 *
+	 * @param	string
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	function set_select($field = '', $value = '', $default = FALSE)
 	{
 		$OBJ =& _get_validation_object();
@@ -682,7 +689,7 @@
 		{
 			if ( ! isset($_POST[$field]))
 			{
-				if (count($_POST) === 0 && $default == TRUE)
+				if (count($_POST) === 0 && $default === TRUE)
 				{
 					return ' selected="selected"';
 				}
@@ -698,7 +705,7 @@
 					return '';
 				}
 			}
-			elseif (($field == '' OR $value == '') OR ($field != $value))
+			elseif (($field == '' OR $value == '') OR $field !== $value)
 			{
 				return '';
 			}
@@ -712,19 +719,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Set Checkbox
- *
- * Let's you set the selected value of a checkbox via the value in the POST array.
- * If Form Validation is active it retrieves the info from the validation class
- *
- * @param	string
- * @param	string
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('set_checkbox'))
 {
+	/**
+	 * Set Checkbox
+	 *
+	 * Let's you set the selected value of a checkbox via the value in the POST array.
+	 * If Form Validation is active it retrieves the info from the validation class
+	 *
+	 * @param	string
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	function set_checkbox($field = '', $value = '', $default = FALSE)
 	{
 		$OBJ =& _get_validation_object();
@@ -733,7 +740,7 @@
 		{
 			if ( ! isset($_POST[$field]))
 			{
-				if (count($_POST) === 0 && $default == TRUE)
+				if (count($_POST) === 0 && $default === TRUE)
 				{
 					return ' checked="checked"';
 				}
@@ -749,7 +756,7 @@
 					return '';
 				}
 			}
-			elseif (($field == '' OR $value == '') OR ($field != $value))
+			elseif (($field == '' OR $value == '') OR $field !== $value)
 			{
 				return '';
 			}
@@ -763,19 +770,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Set Radio
- *
- * Let's you set the selected value of a radio field via info in the POST array.
- * If Form Validation is active it retrieves the info from the validation class
- *
- * @param	string
- * @param	string
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('set_radio'))
 {
+	/**
+	 * Set Radio
+	 *
+	 * Let's you set the selected value of a radio field via info in the POST array.
+	 * If Form Validation is active it retrieves the info from the validation class
+	 *
+	 * @param	string
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	function set_radio($field = '', $value = '', $default = FALSE)
 	{
 		$OBJ =& _get_validation_object();
@@ -784,7 +791,7 @@
 		{
 			if ( ! isset($_POST[$field]))
 			{
-				if (count($_POST) === 0 && $default == TRUE)
+				if (count($_POST) === 0 && $default === TRUE)
 				{
 					return ' checked="checked"';
 				}
@@ -802,7 +809,7 @@
 			}
 			else
 			{
-				if (($field == '' OR $value == '') OR ($field != $value))
+				if (($field == '' OR $value == '') OR $field !== $value)
 				{
 					return '';
 				}
@@ -817,19 +824,20 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Form Error
- *
- * Returns the error for a specific form field. This is a helper for the
- * form validation class.
- *
- * @param	string
- * @param	string
- * @param	string
- * @return	string
- */
+
 if ( ! function_exists('form_error'))
 {
+	/**
+	 * Form Error
+	 *
+	 * Returns the error for a specific form field. This is a helper for the
+	 * form validation class.
+	 *
+	 * @param	string
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function form_error($field = '', $prefix = '', $suffix = '')
 	{
 		if (FALSE === ($OBJ =& _get_validation_object()))
@@ -843,18 +851,18 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Validation Error String
- *
- * Returns all the errors associated with a form submission. This is a helper
- * function for the form validation class.
- *
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('validation_errors'))
 {
+	/**
+	 * Validation Error String
+	 *
+	 * Returns all the errors associated with a form submission. This is a helper
+	 * function for the form validation class.
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function validation_errors($prefix = '', $suffix = '')
 	{
 		if (FALSE === ($OBJ =& _get_validation_object()))
@@ -868,17 +876,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Parse the form attributes
- *
- * Helper function used by some of the form helpers
- *
- * @param	array
- * @param	array
- * @return	string
- */
 if ( ! function_exists('_parse_form_attributes'))
 {
+	/**
+	 * Parse the form attributes
+	 *
+	 * Helper function used by some of the form helpers
+	 *
+	 * @param	array
+	 * @param	array
+	 * @return	string
+	 */
 	function _parse_form_attributes($attributes, $default)
 	{
 		if (is_array($attributes))
@@ -902,7 +910,7 @@
 
 		foreach ($default as $key => $val)
 		{
-			if ($key == 'value')
+			if ($key === 'value')
 			{
 				$val = form_prep($val, $default['name']);
 			}
@@ -916,27 +924,27 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Attributes To String
- *
- * Helper function used by some of the form helpers
- *
- * @param	mixed
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('_attributes_to_string'))
 {
+	/**
+	 * Attributes To String
+	 *
+	 * Helper function used by some of the form helpers
+	 *
+	 * @param	mixed
+	 * @param	bool
+	 * @return	string
+	 */
 	function _attributes_to_string($attributes, $formtag = FALSE)
 	{
 		if (is_string($attributes) && strlen($attributes) > 0)
 		{
-			if ($formtag == TRUE && strpos($attributes, 'method=') === FALSE)
+			if ($formtag === TRUE && strpos($attributes, 'method=') === FALSE)
 			{
 				$attributes .= ' method="post"';
 			}
 
-			if ($formtag == TRUE && strpos($attributes, 'accept-charset=') === FALSE)
+			if ($formtag === TRUE && strpos($attributes, 'accept-charset=') === FALSE)
 			{
 				$attributes .= ' accept-charset="'.strtolower(config_item('charset')).'"';
 			}
@@ -975,16 +983,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Validation Object
- *
- * Determines what the form validation class was instantiated as, fetches
- * the object and returns it.
- *
- * @return	mixed
- */
 if ( ! function_exists('_get_validation_object'))
 {
+	/**
+	 * Validation Object
+	 *
+	 * Determines what the form validation class was instantiated as, fetches
+	 * the object and returns it.
+	 *
+	 * @return	mixed
+	 */
 	function &_get_validation_object()
 	{
 		$CI =& get_instance();
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index 0417bd2..68ce702 100644
--- a/system/helpers/html_helper.php
+++ b/system/helpers/html_helper.php
@@ -37,36 +37,37 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Heading
- *
- * Generates an HTML heading tag.
- *
- * @param	string	content
- * @param	int	heading level
- * @return	string
- */
 if ( ! function_exists('heading'))
 {
+	/**
+	 * Heading
+	 *
+	 * Generates an HTML heading tag.
+	 *
+	 * @param	string	content
+	 * @param	int	heading level
+	 * @param	string
+	 * @return	string
+	 */
 	function heading($data = '', $h = '1', $attributes = '')
 	{
-		return '<h'.$h.($attributes != '' ? ' ' : '').$attributes.'>'.$data.'</h'.$h.'>';
+		return '<h'.$h.($attributes !== '' ? ' ' : '').$attributes.'>'.$data.'</h'.$h.'>';
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Unordered List
- *
- * Generates an HTML unordered list from an single or multi-dimensional array.
- *
- * @param	array
- * @param	mixed
- * @return	string
- */
 if ( ! function_exists('ul'))
 {
+	/**
+	 * Unordered List
+	 *
+	 * Generates an HTML unordered list from an single or multi-dimensional array.
+	 *
+	 * @param	array
+	 * @param	mixed
+	 * @return	string
+	 */
 	function ul($list, $attributes = '')
 	{
 		return _list('ul', $list, $attributes);
@@ -75,17 +76,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Ordered List
- *
- * Generates an HTML ordered list from an single or multi-dimensional array.
- *
- * @param	array
- * @param	mixed
- * @return	string
- */
 if ( ! function_exists('ol'))
 {
+	/**
+	 * Ordered List
+	 *
+	 * Generates an HTML ordered list from an single or multi-dimensional array.
+	 *
+	 * @param	array
+	 * @param	mixed
+	 * @return	string
+	 */
 	function ol($list, $attributes = '')
 	{
 		return _list('ol', $list, $attributes);
@@ -94,19 +95,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Generates the list
- *
- * Generates an HTML ordered list from an single or multi-dimensional array.
- *
- * @param	string
- * @param	mixed
- * @param	mixed
- * @param	int
- * @return	string
- */
 if ( ! function_exists('_list'))
 {
+	/**
+	 * Generates the list
+	 *
+	 * Generates an HTML ordered list from an single or multi-dimensional array.
+	 *
+	 * @param	string
+	 * @param	mixed
+	 * @param	mixed
+	 * @param	int
+	 * @return	string
+	 */
 	function _list($type = 'ul', $list, $attributes = '', $depth = 0)
 	{
 		// If an array wasn't submitted there's nothing to do...
@@ -165,14 +166,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Generates HTML BR tags based on number supplied
- *
- * @param	int
- * @return	string
- */
 if ( ! function_exists('br'))
 {
+	/**
+	 * Generates HTML BR tags based on number supplied
+	 *
+	 * @param	int
+	 * @return	string
+	 */
 	function br($num = 1)
 	{
 		return str_repeat('<br />', $num);
@@ -181,17 +182,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Image
- *
- * Generates an <img /> element
- *
- * @param	mixed
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('img'))
 {
+	/**
+	 * Image
+	 *
+	 * Generates an <img /> element
+	 *
+	 * @param	mixed
+	 * @param	bool
+	 * @return	string
+	 */
 	function img($src = '', $index_page = FALSE)
 	{
 		if ( ! is_array($src) )
@@ -234,20 +235,20 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Doctype
- *
- * Generates a page document type declaration
- *
- * Valid options are xhtml-11, xhtml-strict, xhtml-trans, xhtml-frame,
- * html4-strict, html4-trans, and html4-frame. Values are saved in the
- * doctypes config file.
- *
- * @param	string	type	The doctype to be generated
- * @return	string
- */
 if ( ! function_exists('doctype'))
 {
+	/**
+	 * Doctype
+	 *
+	 * Generates a page document type declaration
+	 *
+	 * Valid options are xhtml-11, xhtml-strict, xhtml-trans, xhtml-frame,
+	 * html4-strict, html4-trans, and html4-frame. Values are saved in the
+	 * doctypes config file.
+	 *
+	 * @param	string	type	The doctype to be generated
+	 * @return	string
+	 */
 	function doctype($type = 'xhtml1-strict')
 	{
 		global $_doctypes;
@@ -275,21 +276,21 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Link
- *
- * Generates link to a CSS file
- *
- * @param	mixed	stylesheet hrefs or an array
- * @param	string	rel
- * @param	string	type
- * @param	string	title
- * @param	string	media
- * @param	bool	should index_page be added to the css path
- * @return	string
- */
 if ( ! function_exists('link_tag'))
 {
+	/**
+	 * Link
+	 *
+	 * Generates link to a CSS file
+	 *
+	 * @param	mixed	stylesheet hrefs or an array
+	 * @param	string	rel
+	 * @param	string	type
+	 * @param	string	title
+	 * @param	string	media
+	 * @param	bool	should index_page be added to the css path
+	 * @return	string
+	 */
 	function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE)
 	{
 		$CI =& get_instance();
@@ -333,12 +334,12 @@
 
 			$link .= 'rel="'.$rel.'" type="'.$type.'" ';
 
-			if ($media != '')
+			if ($media !== '')
 			{
 				$link .= 'media="'.$media.'" ';
 			}
 
-			if ($title != '')
+			if ($title !== '')
 			{
 				$link .= 'title="'.$title.'" ';
 			}
@@ -350,17 +351,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Generates meta tags from an array of key/values
- *
- * @param	array
- * @param	string
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('meta'))
 {
+	/**
+	 * Generates meta tags from an array of key/values
+	 *
+	 * @param	array
+	 * @param	string
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function meta($name = '', $content = '', $type = 'name', $newline = "\n")
 	{
 		// Since we allow the data to be passes as a string, a simple array
@@ -378,10 +379,10 @@
 		$str = '';
 		foreach ($name as $meta)
 		{
-			$type		= ( ! isset($meta['type']) OR $meta['type'] == 'name') ? 'name' : 'http-equiv';
-			$name		= ( ! isset($meta['name']))		? ''	: $meta['name'];
-			$content	= ( ! isset($meta['content']))	? ''	: $meta['content'];
-			$newline	= ( ! isset($meta['newline']))	? "\n"	: $meta['newline'];
+			$type		= ( ! isset($meta['type']) OR $meta['type'] === 'name') ? 'name' : 'http-equiv';
+			$name		= isset($meta['name'])					? $meta['name'] : '';
+			$content	= isset($meta['content'])				? $meta['content'] : '';
+			$newline	= isset($meta['newline'])				? $meta['newline'] : "\n";
 
 			$str .= '<meta '.$type.'="'.$name.'" content="'.$content.'" />'.$newline;
 		}
@@ -392,14 +393,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Generates non-breaking space entities based on number supplied
- *
- * @param	int
- * @return	string
- */
 if ( ! function_exists('nbs'))
 {
+	/**
+	 * Generates non-breaking space entities based on number supplied
+	 *
+	 * @param	int
+	 * @return	string
+	 */
 	function nbs($num = 1)
 	{
 		return str_repeat('&nbsp;', $num);
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
index feeaf57..647d840 100644
--- a/system/helpers/inflector_helper.php
+++ b/system/helpers/inflector_helper.php
@@ -37,16 +37,16 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Singular
- *
- * Takes a plural word and makes it singular
- *
- * @param	string
- * @return	str
- */
 if ( ! function_exists('singular'))
 {
+	/**
+	 * Singular
+	 *
+	 * Takes a plural word and makes it singular
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function singular($str)
 	{
 		$result = strval($str);
@@ -101,17 +101,17 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Plural
- *
- * Takes a singular word and makes it plural
- *
- * @param	string
- * @param	bool
- * @return	str
- */
 if ( ! function_exists('plural'))
 {
+	/**
+	 * Plural
+	 *
+	 * Takes a singular word and makes it plural
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	function plural($str, $force = FALSE)
 	{
 		$result = strval($str);
@@ -158,16 +158,16 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Camelize
- *
- * Takes multiple words separated by spaces or underscores and camelizes them
- *
- * @param	string
- * @return	str
- */
 if ( ! function_exists('camelize'))
 {
+	/**
+	 * Camelize
+	 *
+	 * Takes multiple words separated by spaces or underscores and camelizes them
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function camelize($str)
 	{
 		return strtolower($str[0]).substr(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $str))), 1);
@@ -176,16 +176,16 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Underscore
- *
- * Takes multiple words separated by spaces and underscores them
- *
- * @param	string
- * @return	str
- */
 if ( ! function_exists('underscore'))
 {
+	/**
+	 * Underscore
+	 *
+	 * Takes multiple words separated by spaces and underscores them
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function underscore($str)
 	{
 		return preg_replace('/[\s]+/', '_', strtolower(trim($str)));
@@ -194,31 +194,33 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Humanize
- *
- * Takes multiple words separated by the separator and changes them to spaces
- *
- * @param	string	$str
- * @param 	string	$separator
- * @return	str
- */
 if ( ! function_exists('humanize'))
 {
+	/**
+	 * Humanize
+	 *
+	 * Takes multiple words separated by the separator and changes them to spaces
+	 *
+	 * @param	string	$str
+	 * @param 	string	$separator
+	 * @return	string
+	 */
 	function humanize($str, $separator = '_')
 	{
 		return ucwords(preg_replace('/['.$separator.']+/', ' ', strtolower(trim($str))));
 	}
 }
 
-/**
- * Checks if the given word has a plural version.
- *
- * @param	string	the word to check
- * @return	bool	if the word is countable
- */
+// --------------------------------------------------------------------
+
 if ( ! function_exists('is_countable'))
 {
+	/**
+	 * Checks if the given word has a plural version.
+	 *
+	 * @param	string	the word to check
+	 * @return	bool	if the word is countable
+	 */
 	function is_countable($word)
 	{
 		return ! in_array(strtolower(strval($word)),
diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php
index b31c971..bd567ed 100644
--- a/system/helpers/language_helper.php
+++ b/system/helpers/language_helper.php
@@ -37,23 +37,23 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Lang
- *
- * Fetches a language variable and optionally outputs a form label
- *
- * @param	string	the language line
- * @param	string	the id of the form element
- * @return	string
- */
 if ( ! function_exists('lang'))
 {
+	/**
+	 * Lang
+	 *
+	 * Fetches a language variable and optionally outputs a form label
+	 *
+	 * @param	string	the language line
+	 * @param	string	the id of the form element
+	 * @return	string
+	 */
 	function lang($line, $id = '')
 	{
 		$CI =& get_instance();
 		$line = $CI->lang->line($line);
 
-		if ($id != '')
+		if ($id !== '')
 		{
 			$line = '<label for="'.$id.'">'.$line.'</label>';
 		}
diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php
index 40da6e7..e49f2f7 100644
--- a/system/helpers/number_helper.php
+++ b/system/helpers/number_helper.php
@@ -37,14 +37,15 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Formats a numbers as bytes, based on size, and adds the appropriate suffix
- *
- * @param	mixed	// will be cast as int
- * @return	string
- */
 if ( ! function_exists('byte_format'))
 {
+	/**
+	 * Formats a numbers as bytes, based on size, and adds the appropriate suffix
+	 *
+	 * @param	mixed	will be cast as int
+	 * @param	int
+	 * @return	string
+	 */
 	function byte_format($num, $precision = 1)
 	{
 		$CI =& get_instance();
diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php
index 6ee9907..fec4a1a 100644
--- a/system/helpers/path_helper.php
+++ b/system/helpers/path_helper.php
@@ -37,15 +37,15 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Set Realpath
- *
- * @param	string
- * @param	bool	checks to see if the path exists
- * @return	string
- */
 if ( ! function_exists('set_realpath'))
 {
+	/**
+	 * Set Realpath
+	 *
+	 * @param	string
+	 * @param	bool	checks to see if the path exists
+	 * @return	string
+	 */
 	function set_realpath($path, $check_existance = FALSE)
 	{
 		// Security check to make sure the path is NOT a URL. No remote file inclusion!
@@ -55,7 +55,7 @@
 		}
 
 		// Resolve the path
-		if (function_exists('realpath') && @realpath($path) !== FALSE)
+		if (@realpath($path) !== FALSE)
 		{
 			$path = realpath($path);
 		}
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
index d6f134c..3e6e914 100644
--- a/system/helpers/security_helper.php
+++ b/system/helpers/security_helper.php
@@ -37,15 +37,15 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * XSS Filtering
- *
- * @param	string
- * @param	bool	whether or not the content is an image file
- * @return	string
- */
 if ( ! function_exists('xss_clean'))
 {
+	/**
+	 * XSS Filtering
+	 *
+	 * @param	string
+	 * @param	bool	whether or not the content is an image file
+	 * @return	string
+	 */
 	function xss_clean($str, $is_image = FALSE)
 	{
 		$CI =& get_instance();
@@ -55,14 +55,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Sanitize Filename
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('sanitize_filename'))
 {
+	/**
+	 * Sanitize Filename
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function sanitize_filename($filename)
 	{
 		$CI =& get_instance();
@@ -72,14 +72,18 @@
 
 // --------------------------------------------------------------------
 
-/**
- * Hash encode a string
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('do_hash'))
 {
+	/**
+	 * Hash encode a string
+	 *
+	 * This function is DEPRECATED and should be removed in
+	 * CodeIgniter 3.1+. Use hash() instead.
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function do_hash($str, $type = 'sha1')
 	{
 		if ( ! in_array(strtolower($type), hash_algos()))
@@ -93,14 +97,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Strip Image Tags
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('strip_image_tags'))
 {
+	/**
+	 * Strip Image Tags
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function strip_image_tags($str)
 	{
 		return preg_replace(array('#<img\s+.*?src\s*=\s*["\'](.+?)["\'].*?\>#', '#<img\s+.*?src\s*=\s*(.+?).*?\>#'), '\\1', $str);
@@ -109,14 +113,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Convert PHP tags to entities
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('encode_php_tags'))
 {
+	/**
+	 * Convert PHP tags to entities
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function encode_php_tags($str)
 	{
 		return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
index 8dba74e..b6b2afc 100644
--- a/system/helpers/smiley_helper.php
+++ b/system/helpers/smiley_helper.php
@@ -37,125 +37,112 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Smiley Javascript
- *
- * Returns the javascript required for the smiley insertion.  Optionally takes
- * an array of aliases to loosely couple the smiley array to the view.
- *
- * @param	mixed	alias name or array of alias->field_id pairs
- * @param	string	field_id if alias name was passed in
- * @return	array
- */
 if ( ! function_exists('smiley_js'))
 {
+	/**
+	 * Smiley Javascript
+	 *
+	 * Returns the javascript required for the smiley insertion.  Optionally takes
+	 * an array of aliases to loosely couple the smiley array to the view.
+	 *
+	 * @param	mixed	alias name or array of alias->field_id pairs
+	 * @param	string	field_id if alias name was passed in
+	 * @param	bool
+	 * @return	array
+	 */
 	function smiley_js($alias = '', $field_id = '', $inline = TRUE)
 	{
 		static $do_setup = TRUE;
-
 		$r = '';
 
-		if ($alias != '' && ! is_array($alias))
+		if ($alias !== '' && ! is_array($alias))
 		{
 			$alias = array($alias => $field_id);
 		}
 
 		if ($do_setup === TRUE)
 		{
-				$do_setup = FALSE;
+			$do_setup = FALSE;
+			$m = array();
 
-				$m = array();
-
-				if (is_array($alias))
-				{
-					foreach ($alias as $name => $id)
-					{
-						$m[] = '"'.$name.'" : "'.$id.'"';
-					}
-				}
-
-				$m = '{'.implode(',', $m).'}';
-
-				$r .= <<<EOF
-				var smiley_map = {$m};
-
-				function insert_smiley(smiley, field_id) {
-					var el = document.getElementById(field_id), newStart;
-
-					if ( ! el && smiley_map[field_id]) {
-						el = document.getElementById(smiley_map[field_id]);
-
-						if ( ! el)
-							return false;
-					}
-
-					el.focus();
-					smiley = " " + smiley;
-
-					if ('selectionStart' in el) {
-						newStart = el.selectionStart + smiley.length;
-
-						el.value = el.value.substr(0, el.selectionStart) +
-										smiley +
-										el.value.substr(el.selectionEnd, el.value.length);
-						el.setSelectionRange(newStart, newStart);
-					}
-					else if (document.selection) {
-						document.selection.createRange().text = smiley;
-					}
-				}
-EOF;
-		}
-		else
-		{
 			if (is_array($alias))
 			{
 				foreach ($alias as $name => $id)
 				{
-					$r .= 'smiley_map["'.$name.'"] = "'.$id.'";'."\n";
+					$m[] = '"'.$name.'" : "'.$id.'"';
 				}
 			}
+
+			$m = '{'.implode(',', $m).'}';
+
+			$r .= <<<EOF
+			var smiley_map = {$m};
+
+			function insert_smiley(smiley, field_id) {
+				var el = document.getElementById(field_id), newStart;
+
+				if ( ! el && smiley_map[field_id]) {
+					el = document.getElementById(smiley_map[field_id]);
+
+					if ( ! el)
+						return false;
+				}
+
+				el.focus();
+				smiley = " " + smiley;
+
+				if ('selectionStart' in el) {
+					newStart = el.selectionStart + smiley.length;
+
+					el.value = el.value.substr(0, el.selectionStart) +
+									smiley +
+									el.value.substr(el.selectionEnd, el.value.length);
+					el.setSelectionRange(newStart, newStart);
+				}
+				else if (document.selection) {
+					document.selection.createRange().text = smiley;
+				}
+			}
+EOF;
+		}
+		elseif (is_array($alias))
+		{
+			foreach ($alias as $name => $id)
+			{
+				$r .= 'smiley_map["'.$name.'"] = "'.$id."\";\n";
+			}
 		}
 
-		if ($inline)
-		{
-			return '<script type="text/javascript" charset="utf-8">/*<![CDATA[ */'.$r.'// ]]></script>';
-		}
-		else
-		{
-			return $r;
-		}
+		return ($inline) ? '<script type="text/javascript" charset="utf-8">/*<![CDATA[ */'.$r.'// ]]></script>' : $r;
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Get Clickable Smileys
- *
- * Returns an array of image tag links that can be clicked to be inserted
- * into a form field.
- *
- * @param	string	the URL to the folder containing the smiley images
- * @return	array
- */
+
 if ( ! function_exists('get_clickable_smileys'))
 {
+	/**
+	 * Get Clickable Smileys
+	 *
+	 * Returns an array of image tag links that can be clicked to be inserted
+	 * into a form field.
+	 *
+	 * @param	string	the URL to the folder containing the smiley images
+	 * @param	array
+	 * @param	array
+	 * @return	array
+	 */
 	function get_clickable_smileys($image_url, $alias = '', $smileys = NULL)
 	{
 		// For backward compatibility with js_insert_smiley
-
 		if (is_array($alias))
 		{
 			$smileys = $alias;
 		}
-
-		if ( ! is_array($smileys))
+		elseif (FALSE === ($smileys = _get_smiley_array()))
 		{
-			if (FALSE === ($smileys = _get_smiley_array()))
-			{
-				return $smileys;
-			}
+			return $smileys;
 		}
 
 		// Add a trailing slash to the file path if needed
@@ -165,7 +152,7 @@
 		foreach ($smileys as $key => $val)
 		{
 			// Keep duplicates from being used, which can happen if the
-			// mapping array contains multiple identical replacements.  For example:
+			// mapping array contains multiple identical replacements. For example:
 			// :-) and :) might be replaced with the same image so both smileys
 			// will be in the array.
 			if (isset($used[$smileys[$key][0]]))
@@ -173,8 +160,7 @@
 				continue;
 			}
 
-			$link[] = "<a href=\"javascript:void(0);\" onclick=\"insert_smiley('".$key."', '".$alias."')\"><img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" /></a>";
-
+			$link[] = '<a href="javascript:void(0);" onclick="insert_smiley(\''.$key.'\', \''.$alias.'\')"><img src="'.$image_url.$smileys[$key][0].'" alt="'.$smileys[$key][3].'" style="width: '.$smileys[$key][1].'; height: '.$smileys[$key][2].'; border: 0;" /></a>';
 			$used[$smileys[$key][0]] = TRUE;
 		}
 
@@ -184,38 +170,31 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Parse Smileys
- *
- * Takes a string as input and swaps any contained smileys for the actual image
- *
- * @param	string	the text to be parsed
- * @param	string	the URL to the folder containing the smiley images
- * @return	string
- */
 if ( ! function_exists('parse_smileys'))
 {
+	/**
+	 * Parse Smileys
+	 *
+	 * Takes a string as input and swaps any contained smileys for the actual image
+	 *
+	 * @param	string	the text to be parsed
+	 * @param	string	the URL to the folder containing the smiley images
+	 * @param	array
+	 * @return	string
+	 */
 	function parse_smileys($str = '', $image_url = '', $smileys = NULL)
 	{
-		if ($image_url == '')
+		if ($image_url === '' OR ( ! is_array($smileys) && FALSE === ($smileys = _get_smiley_array())))
 		{
 			return $str;
 		}
 
-		if ( ! is_array($smileys))
-		{
-			if (FALSE === ($smileys = _get_smiley_array()))
-			{
-				return $str;
-			}
-		}
-
 		// Add a trailing slash to the file path if needed
-		$image_url = preg_replace("/(.+?)\/*$/", "\\1/",  $image_url);
+		$image_url = rtrim($image_url, '/').'/';
 
 		foreach ($smileys as $key => $val)
 		{
-			$str = str_replace($key, "<img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" />", $str);
+			$str = str_replace($key, '<img src="'.$image_url.$smileys[$key][0].'" alt="'.$smileys[$key][3].'" style="width: '.$smileys[$key][1].'; height: '.$smileys[$key][2].'; border: 0;" />', $str);
 		}
 
 		return $str;
@@ -224,15 +203,15 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Get Smiley Array
- *
- * Fetches the config/smiley.php file
- *
- * @return	mixed
- */
 if ( ! function_exists('_get_smiley_array'))
 {
+	/**
+	 * Get Smiley Array
+	 *
+	 * Fetches the config/smiley.php file
+	 *
+	 * @return	mixed
+	 */
 	function _get_smiley_array()
 	{
 		if (defined('ENVIRONMENT') && file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys.php'))
@@ -244,40 +223,7 @@
 			include(APPPATH.'config/smileys.php');
 		}
 
-		if (isset($smileys) && is_array($smileys))
-		{
-			return $smileys;
-		}
-
-		return FALSE;
-	}
-}
-
-// ------------------------------------------------------------------------
-
-/**
- * JS Insert Smiley
- *
- * Generates the javascript function needed to insert smileys into a form field
- *
- * DEPRECATED as of version 1.7.2, use smiley_js instead
- *
- * @param	string	form name
- * @param	string	field name
- * @return	string
- */
-if ( ! function_exists('js_insert_smiley'))
-{
-	function js_insert_smiley($form_name = '', $form_field = '')
-	{
-		return <<<EOF
-<script type="text/javascript">
-	function insert_smiley(smiley)
-	{
-		document.{$form_name}.{$form_field}.value += " " + smiley;
-	}
-</script>
-EOF;
+		return (isset($smileys) && is_array($smileys)) ? $smileys : FALSE;
 	}
 }
 
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
index aed35c1..4eee2a2 100644
--- a/system/helpers/string_helper.php
+++ b/system/helpers/string_helper.php
@@ -37,22 +37,22 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Trim Slashes
- *
- * Removes any leading/trailing slashes from a string:
- *
- * /this/that/theother/
- *
- * becomes:
- *
- * this/that/theother
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('trim_slashes'))
 {
+	/**
+	 * Trim Slashes
+	 *
+	 * Removes any leading/trailing slashes from a string:
+	 *
+	 * /this/that/theother/
+	 *
+	 * becomes:
+	 *
+	 * this/that/theother
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function trim_slashes($str)
 	{
 		return trim($str, '/');
@@ -61,28 +61,26 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Strip Slashes
- *
- * Removes slashes contained in a string or in an array
- *
- * @param	mixed	string or array
- * @return	mixed	string or array
- */
 if ( ! function_exists('strip_slashes'))
 {
+	/**
+	 * Strip Slashes
+	 *
+	 * Removes slashes contained in a string or in an array
+	 *
+	 * @param	mixed	string or array
+	 * @return	mixed	string or array
+	 */
 	function strip_slashes($str)
 	{
-		if (is_array($str))
+		if ( ! is_array($str))
 		{
-			foreach ($str as $key => $val)
-			{
-				$str[$key] = strip_slashes($val);
-			}
+			return stripslashes($str);
 		}
-		else
+
+		foreach ($str as $key => $val)
 		{
-			$str = stripslashes($str);
+			$str[$key] = strip_slashes($val);
 		}
 
 		return $str;
@@ -91,16 +89,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Strip Quotes
- *
- * Removes single and double quotes from a string
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('strip_quotes'))
 {
+	/**
+	 * Strip Quotes
+	 *
+	 * Removes single and double quotes from a string
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function strip_quotes($str)
 	{
 		return str_replace(array('"', "'"), '', $str);
@@ -109,16 +107,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Quotes to Entities
- *
- * Converts single and double quotes to entities
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('quotes_to_entities'))
 {
+	/**
+	 * Quotes to Entities
+	 *
+	 * Converts single and double quotes to entities
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function quotes_to_entities($str)
 	{
 		return str_replace(array("\'","\"","'",'"'), array("&#39;","&quot;","&#39;","&quot;"), $str);
@@ -127,23 +125,23 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Reduce Double Slashes
- *
- * Converts double slashes in a string to a single slash,
- * except those found in http://
- *
- * http://www.some-site.com//index.php
- *
- * becomes:
- *
- * http://www.some-site.com/index.php
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('reduce_double_slashes'))
 {
+	/**
+	 * Reduce Double Slashes
+	 *
+	 * Converts double slashes in a string to a single slash,
+	 * except those found in http://
+	 *
+	 * http://www.some-site.com//index.php
+	 *
+	 * becomes:
+	 *
+	 * http://www.some-site.com/index.php
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function reduce_double_slashes($str)
 	{
 		return preg_replace('#(^|[^:])//+#', '\\1/', $str);
@@ -152,131 +150,116 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Reduce Multiples
- *
- * Reduces multiple instances of a particular character.  Example:
- *
- * Fred, Bill,, Joe, Jimmy
- *
- * becomes:
- *
- * Fred, Bill, Joe, Jimmy
- *
- * @param	string
- * @param	string	the character you wish to reduce
- * @param	bool	TRUE/FALSE - whether to trim the character from the beginning/end
- * @return	string
- */
 if ( ! function_exists('reduce_multiples'))
 {
+	/**
+	 * Reduce Multiples
+	 *
+	 * Reduces multiple instances of a particular character.  Example:
+	 *
+	 * Fred, Bill,, Joe, Jimmy
+	 *
+	 * becomes:
+	 *
+	 * Fred, Bill, Joe, Jimmy
+	 *
+	 * @param	string
+	 * @param	string	the character you wish to reduce
+	 * @param	bool	TRUE/FALSE - whether to trim the character from the beginning/end
+	 * @return	string
+	 */
 	function reduce_multiples($str, $character = ',', $trim = FALSE)
 	{
 		$str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str);
-
-		if ($trim === TRUE)
-		{
-			return trim($str, $character);
-		}
-
-		return $str;
+		return ($trim === TRUE) ? trim($str, $character) : $str;
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Create a Random String
- *
- * Useful for generating passwords or hashes.
- *
- * @param	string	type of random string.  basic, alpha, alunum, numeric, nozero, unique, md5, encrypt and sha1
- * @param	int	number of characters
- * @return	string
- */
 if ( ! function_exists('random_string'))
 {
+	/**
+	 * Create a Random String
+	 *
+	 * Useful for generating passwords or hashes.
+	 *
+	 * @param	string	type of random string.  basic, alpha, alunum, numeric, nozero, unique, md5, encrypt and sha1
+	 * @param	int	number of characters
+	 * @return	string
+	 */
 	function random_string($type = 'alnum', $len = 8)
 	{
-		switch($type)
+		switch ($type)
 		{
-			case 'basic'	: return mt_rand();
-				break;
-			case 'alnum'	:
-			case 'numeric'	:
-			case 'nozero'	:
-			case 'alpha'	:
-
-					switch ($type)
-					{
-						case 'alpha'	:	$pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-							break;
-						case 'alnum'	:	$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-							break;
-						case 'numeric'	:	$pool = '0123456789';
-							break;
-						case 'nozero'	:	$pool = '123456789';
-							break;
-					}
-
-					$str = substr(str_shuffle(str_repeat($pool, ceil($len/strlen($pool)))),0,$len);
-
-					return $str;
-				break;
-			case 'unique'	:
-			case 'md5'		:
-
-						return md5(uniqid(mt_rand()));
-				break;
-			case 'encrypt'	:
-			case 'sha1'	:
-
-						$CI =& get_instance();
-						$CI->load->helper('security');
-
-						return do_hash(uniqid(mt_rand(), TRUE), 'sha1');
-				break;
+			case 'basic':
+				return mt_rand();
+			case 'alnum':
+			case 'numeric':
+			case 'nozero':
+			case 'alpha':
+				switch ($type)
+				{
+					case 'alpha':
+						$pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+						break;
+					case 'alnum':
+						$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+						break;
+					case 'numeric':
+						$pool = '0123456789';
+						break;
+					case 'nozero':
+						$pool = '123456789';
+						break;
+				}
+				return substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
+			case 'unique':
+			case 'md5':
+				return md5(uniqid(mt_rand()));
+			case 'encrypt':
+			case 'sha1':
+				return sha1(uniqid(mt_rand(), TRUE));
 		}
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Add's _1 to a string or increment the ending number to allow _2, _3, etc
- *
- * @param	string	required
- * @param	string	What should the duplicate number be appended with
- * @param	string	Which number should be used for the first dupe increment
- * @return	string
- */
 if ( ! function_exists('increment_string'))
 {
+	/**
+	 * Add's _1 to a string or increment the ending number to allow _2, _3, etc
+	 *
+	 * @param	string	required
+	 * @param	string	What should the duplicate number be appended with
+	 * @param	string	Which number should be used for the first dupe increment
+	 * @return	string
+	 */
 	function increment_string($str, $separator = '_', $first = 1)
 	{
 		preg_match('/(.+)'.$separator.'([0-9]+)$/', $str, $match);
-
 		return isset($match[2]) ? $match[1].$separator.($match[2] + 1) : $str.$separator.$first;
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Alternator
- *
- * Allows strings to be alternated. See docs...
- *
- * @param	string (as many parameters as needed)
- * @return	string
- */
 if ( ! function_exists('alternator'))
 {
-	function alternator()
+	/**
+	 * Alternator
+	 *
+	 * Allows strings to be alternated. See docs...
+	 *
+	 * @param	string (as many parameters as needed)
+	 * @return	string
+	 */
+	function alternator($args)
 	{
 		static $i;
 
-		if (func_num_args() == 0)
+		if (func_num_args() === 0)
 		{
 			$i = 0;
 			return '';
@@ -288,15 +271,15 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Repeater function
- *
- * @param	string
- * @param	int	number of repeats
- * @return	string
- */
 if ( ! function_exists('repeater'))
 {
+	/**
+	 * Repeater function
+	 *
+	 * @param	string
+	 * @param	int	number of repeats
+	 * @return	string
+	 */
 	function repeater($data, $num = 1)
 	{
 		return ($num > 0) ? str_repeat($data, $num) : '';
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
index cc501c3..8a1f01b 100644
--- a/system/helpers/text_helper.php
+++ b/system/helpers/text_helper.php
@@ -37,28 +37,28 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Word Limiter
- *
- * Limits a string to X number of words.
- *
- * @param	string
- * @param	int
- * @param	string	the end character. Usually an ellipsis
- * @return	string
- */
 if ( ! function_exists('word_limiter'))
 {
+	/**
+	 * Word Limiter
+	 *
+	 * Limits a string to X number of words.
+	 *
+	 * @param	string
+	 * @param	int
+	 * @param	string	the end character. Usually an ellipsis
+	 * @return	string
+	 */
 	function word_limiter($str, $limit = 100, $end_char = '&#8230;')
 	{
-		if (trim($str) == '')
+		if (trim($str) === '')
 		{
 			return $str;
 		}
 
 		preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);
 
-		if (strlen($str) == strlen($matches[0]))
+		if (strlen($str) === strlen($matches[0]))
 		{
 			$end_char = '';
 		}
@@ -69,19 +69,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Character Limiter
- *
- * Limits the string based on the character count.  Preserves complete words
- * so the character count may not be exactly as specified.
- *
- * @param	string
- * @param	int
- * @param	string	the end character. Usually an ellipsis
- * @return	string
- */
 if ( ! function_exists('character_limiter'))
 {
+	/**
+	 * Character Limiter
+	 *
+	 * Limits the string based on the character count.  Preserves complete words
+	 * so the character count may not be exactly as specified.
+	 *
+	 * @param	string
+	 * @param	int
+	 * @param	string	the end character. Usually an ellipsis
+	 * @return	string
+	 */
 	function character_limiter($str, $n = 500, $end_char = '&#8230;')
 	{
 		if (strlen($str) < $n)
@@ -89,14 +89,14 @@
 			return $str;
 		}
 
-		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
+		$str = preg_replace('/\s+/', ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
 
 		if (strlen($str) <= $n)
 		{
 			return $str;
 		}
 
-		$out = "";
+		$out = '';
 		foreach (explode(' ', trim($str)) as $val)
 		{
 			$out .= $val.' ';
@@ -104,7 +104,7 @@
 			if (strlen($out) >= $n)
 			{
 				$out = trim($out);
-				return (strlen($out) == strlen($str)) ? $out : $out.$end_char;
+				return (strlen($out) === strlen($str)) ? $out : $out.$end_char;
 			}
 		}
 	}
@@ -112,16 +112,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * High ASCII to Entities
- *
- * Converts High ascii text and MS Word special characters to character entities
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('ascii_to_entities'))
 {
+	/**
+	 * High ASCII to Entities
+	 *
+	 * Converts High ascii text and MS Word special characters to character entities
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function ascii_to_entities($str)
 	{
 		$count	= 1;
@@ -138,7 +138,7 @@
 					If the $temp array has a value but we have moved on, then it seems only
 					fair that we output that entity and restart $temp before continuing. -Paul
 				*/
-				if (count($temp) == 1)
+				if (count($temp) === 1)
 				{
 					$out  .= '&#'.array_shift($temp).';';
 					$count = 1;
@@ -148,16 +148,18 @@
 			}
 			else
 			{
-				if (count($temp) == 0)
+				if (count($temp) === 0)
 				{
 					$count = ($ordinal < 224) ? 2 : 3;
 				}
 
 				$temp[] = $ordinal;
 
-				if (count($temp) == $count)
+				if (count($temp) === $count)
 				{
-					$number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64);
+					$number = ($count === 3)
+							? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64)
+							: (($temp[0] % 32) * 64) + ($temp[1] % 64);
 
 					$out .= '&#'.$number.';';
 					$count = 1;
@@ -172,25 +174,24 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Entities to ASCII
- *
- * Converts character entities back to ASCII
- *
- * @param	string
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('entities_to_ascii'))
 {
+	/**
+	 * Entities to ASCII
+	 *
+	 * Converts character entities back to ASCII
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	function entities_to_ascii($str, $all = TRUE)
 	{
 		if (preg_match_all('/\&#(\d+)\;/', $str, $matches))
 		{
-			for ($i = 0, $s = count($matches['0']); $i < $s; $i++)
+			for ($i = 0, $s = count($matches[0]); $i < $s; $i++)
 			{
-				$digits = $matches['1'][$i];
-
+				$digits = $matches[1][$i];
 				$out = '';
 
 				if ($digits < 128)
@@ -200,25 +201,24 @@
 				}
 				elseif ($digits < 2048)
 				{
-					$out .= chr(192 + (($digits - ($digits % 64)) / 64));
-					$out .= chr(128 + ($digits % 64));
+					$out .= chr(192 + (($digits - ($digits % 64)) / 64)).chr(128 + ($digits % 64));
 				}
 				else
 				{
-					$out .= chr(224 + (($digits - ($digits % 4096)) / 4096));
-					$out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));
-					$out .= chr(128 + ($digits % 64));
+					$out .= chr(224 + (($digits - ($digits % 4096)) / 4096))
+						.chr(128 + ((($digits % 4096) - ($digits % 64)) / 64))
+						.chr(128 + ($digits % 64));
 				}
 
-				$str = str_replace($matches['0'][$i], $out, $str);
+				$str = str_replace($matches[0][$i], $out, $str);
 			}
 		}
 
 		if ($all)
 		{
-			$str = str_replace(array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;", "&#45;"),
-								array("&","<",">","\"", "'", "-"),
-								$str);
+			return str_replace(array('&amp;', '&lt;', '&gt;', '&quot;', '&apos;', '&#45;'),
+						array('&', '<', '>', '"', "'", '-'),
+						$str);
 		}
 
 		return $str;
@@ -227,20 +227,20 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Word Censoring Function
- *
- * Supply a string and an array of disallowed words and any
- * matched words will be converted to #### or to the replacement
- * word you've submitted.
- *
- * @param	string	the text string
- * @param	string	the array of censoered words
- * @param	string	the optional replacement value
- * @return	string
- */
 if ( ! function_exists('word_censor'))
 {
+	/**
+	 * Word Censoring Function
+	 *
+	 * Supply a string and an array of disallowed words and any
+	 * matched words will be converted to #### or to the replacement
+	 * word you've submitted.
+	 *
+	 * @param	string	the text string
+	 * @param	string	the array of censoered words
+	 * @param	string	the optional replacement value
+	 * @return	string
+	 */
 	function word_censor($str, $censored, $replacement = '')
 	{
 		if ( ! is_array($censored))
@@ -258,7 +258,7 @@
 
 		foreach ($censored as $badword)
 		{
-			if ($replacement != '')
+			if ($replacement !== '')
 			{
 				$str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/i", "\\1{$replacement}\\3", $str);
 			}
@@ -274,39 +274,45 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Code Highlighter
- *
- * Colorizes code strings
- *
- * @param	string	the text string
- * @return	string
- */
 if ( ! function_exists('highlight_code'))
 {
+	/**
+	 * Code Highlighter
+	 *
+	 * Colorizes code strings
+	 *
+	 * @param	string	the text string
+	 * @return	string
+	 */
 	function highlight_code($str)
 	{
-		// The highlight string function encodes and highlights
-		// brackets so we need them to start raw
-		$str = str_replace(array('&lt;', '&gt;'), array('<', '>'), $str);
-
-		// Replace any existing PHP tags to temporary markers so they don't accidentally
-		// break the string out of PHP, and thus, thwart the highlighting.
-		$str = str_replace(array('<?', '?>', '<%', '%>', '\\', '</script>'),
-					array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
+		/* The highlight string function encodes and highlights
+		 * brackets so we need them to start raw.
+		 *
+		 * Also replace any existing PHP tags to temporary markers
+		 * so they don't accidentally break the string out of PHP,
+		 * and thus, thwart the highlighting.
+		 */
+		$str = str_replace(array('&lt;', '&gt;', '<?', '?>', '<%', '%>', '\\', '</script>'),
+					array('<', '>', 'phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
 					$str);
 
 		// The highlight_string function requires that the text be surrounded
 		// by PHP tags, which we will remove later
-		$str = '<?php '.$str.' ?>'; // <?
-
-		// All the magic happens here, baby!
-		$str = highlight_string($str, TRUE);
+		$str = highlight_string('<?php '.$str.' ?>', TRUE);
 
 		// Remove our artificially added PHP, and the syntax highlighting that came with it
-		$str = preg_replace('/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i', '<span style="color: #$1">', $str);
-		$str = preg_replace('/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is', "$1</span>\n</span>\n</code>", $str);
-		$str = preg_replace('/<span style="color: #[A-Z0-9]+"\><\/span>/i', '', $str);
+		$str = preg_replace(array(
+						'/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i',
+						'/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is',
+						'/<span style="color: #[A-Z0-9]+"\><\/span>/i'
+					),
+					array(
+						'<span style="color: #$1">',
+						"$1</span>\n</span>\n</code>",
+						''
+					),
+					$str);
 
 		// Replace our markers back to PHP tags.
 		return str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
@@ -317,29 +323,29 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Phrase Highlighter
- *
- * Highlights a phrase within a text string
- *
- * @param	string	the text string
- * @param	string	the phrase you'd like to highlight
- * @param	string	the openging tag to precede the phrase with
- * @param	string	the closing tag to end the phrase with
- * @return	string
- */
 if ( ! function_exists('highlight_phrase'))
 {
+	/**
+	 * Phrase Highlighter
+	 *
+	 * Highlights a phrase within a text string
+	 *
+	 * @param	string	the text string
+	 * @param	string	the phrase you'd like to highlight
+	 * @param	string	the openging tag to precede the phrase with
+	 * @param	string	the closing tag to end the phrase with
+	 * @return	string
+	 */
 	function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')
 	{
-		if ($str == '')
+		if ($str === '')
 		{
 			return '';
 		}
 
-		if ($phrase != '')
+		if ($phrase !== '')
 		{
-			return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
+			return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open.'\\1'.$tag_close, $str);
 		}
 
 		return $str;
@@ -348,28 +354,33 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Convert Accented Foreign Characters to ASCII
- *
- * @param	string	the text string
- * @return	string
- */
 if ( ! function_exists('convert_accented_characters'))
 {
+	/**
+	 * Convert Accented Foreign Characters to ASCII
+	 *
+	 * @param	string	the text string
+	 * @return	string
+	 */
 	function convert_accented_characters($str)
 	{
-		if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php'))
-		{
-			include(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php');
-		}
-		elseif (is_file(APPPATH.'config/foreign_chars.php'))
-		{
-			include(APPPATH.'config/foreign_chars.php');
-		}
+		global $foreign_characters;
 
-		if ( ! isset($foreign_characters))
+		if ( ! isset($foreign_characters) OR ! is_array($foreign_characters))
 		{
-			return $str;
+			if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php'))
+			{
+				include(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php');
+			}
+			elseif (is_file(APPPATH.'config/foreign_chars.php'))
+			{
+				include(APPPATH.'config/foreign_chars.php');
+			}
+
+			if ( ! isset($foreign_characters) OR ! is_array($foreign_characters))
+			{
+				return $str;
+			}
 		}
 
 		return preg_replace(array_keys($foreign_characters), array_values($foreign_characters), $str);
@@ -381,7 +392,7 @@
 /**
  * Word Wrap
  *
- * Wraps text at the specified character.  Maintains the integrity of words.
+ * Wraps text at the specified character. Maintains the integrity of words.
  * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
  * will URLs.
  *
@@ -391,14 +402,16 @@
  */
 if ( ! function_exists('word_wrap'))
 {
-	function word_wrap($str, $charlim = '76')
+	function word_wrap($str, $charlim = 76)
 	{
-		// Se the character limit
+		// Set the character limit
 		if ( ! is_numeric($charlim))
+		{
 			$charlim = 76;
+		}
 
 		// Reduce multiple spaces
-		$str = preg_replace("| +|", " ", $str);
+		$str = preg_replace('| +|', ' ', $str);
 
 		// Standardize newlines
 		if (strpos($str, "\r") !== FALSE)
@@ -409,22 +422,22 @@
 		// If the current word is surrounded by {unwrap} tags we'll
 		// strip the entire chunk and replace it with a marker.
 		$unwrap = array();
-		if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
+		if (preg_match_all('|(\{unwrap\}.+?\{/unwrap\})|s', $str, $matches))
 		{
-			for ($i = 0; $i < count($matches['0']); $i++)
+			for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
 			{
-				$unwrap[] = $matches['1'][$i];
-				$str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
+				$unwrap[] = $matches[1][$i];
+				$str = str_replace($matches[1][$i], '{{unwrapped'.$i.'}}', $str);
 			}
 		}
 
 		// Use PHP's native 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.
+		// too long get left alone. In the next step we'll deal with them.
 		$str = wordwrap($str, $charlim, "\n", FALSE);
 
 		// Split the string into individual lines of text and cycle through them
-		$output = "";
+		$output = '';
 		foreach (explode("\n", $str) as $line)
 		{
 			// Is the line within the allowed character count?
@@ -439,28 +452,26 @@
 			while ((strlen($line)) > $charlim)
 			{
 				// If the over-length word is a URL we won't wrap it
-				if (preg_match("!\[url.+\]|://|wwww.!", $line))
+				if (preg_match('!\[url.+\]|://|wwww.!', $line))
 				{
 					break;
 				}
 
 				// Trim the word down
-				$temp .= substr($line, 0, $charlim-1);
-				$line = substr($line, $charlim-1);
+				$temp .= substr($line, 0, $charlim - 1);
+				$line = substr($line, $charlim - 1);
 			}
 
 			// If $temp contains data it means we had to split up an over-length
 			// word into smaller chunks so we'll add it back to our current line
-			if ($temp != '')
+			if ($temp !== '')
 			{
-				$output .= $temp."\n".$line;
+				$output .= $temp."\n".$line."\n";
 			}
 			else
 			{
-				$output .= $line;
+				$output .= $line."\n";
 			}
-
-			$output .= "\n";
 		}
 
 		// Put our markers back
@@ -468,32 +479,30 @@
 		{
 			foreach ($unwrap as $key => $val)
 			{
-				$output = str_replace("{{unwrapped".$key."}}", $val, $output);
+				$output = str_replace('{{unwrapped'.$key.'}}', $val, $output);
 			}
 		}
 
-		// Remove the unwrap tags
-		$output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);
-
-		return $output;
+		// Remove the unwrap tags and return
+		return str_replace(array('{unwrap}', '{/unwrap}'), '', $output);
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Ellipsize String
- *
- * This function will strip tags from a string, split it at its max_length and ellipsize
- *
- * @param	string	string to ellipsize
- * @param	int	max length of string
- * @param	mixed	int (1|0) or float, .5, .2, etc for position to split
- * @param	string	ellipsis ; Default '...'
- * @return	string	ellipsized string
- */
 if ( ! function_exists('ellipsize'))
 {
+	/**
+	 * Ellipsize String
+	 *
+	 * This function will strip tags from a string, split it at its max_length and ellipsize
+	 *
+	 * @param	string	string to ellipsize
+	 * @param	int	max length of string
+	 * @param	mixed	int (1|0) or float, .5, .2, etc for position to split
+	 * @param	string	ellipsis ; Default '...'
+	 * @return	string	ellipsized string
+	 */
 	function ellipsize($str, $max_length, $position = 1, $ellipsis = '&hellip;')
 	{
 		// Strip tags
@@ -506,7 +515,6 @@
 		}
 
 		$beg = substr($str, 0, floor($max_length * $position));
-
 		$position = ($position > 1) ? 1 : $position;
 
 		if ($position === 1)
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
index 7a3db5d..af9d16a 100644
--- a/system/helpers/typography_helper.php
+++ b/system/helpers/typography_helper.php
@@ -37,14 +37,14 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Convert newlines to HTML line breaks except within PRE tags
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('nl2br_except_pre'))
 {
+	/**
+	 * Convert newlines to HTML line breaks except within PRE tags
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function nl2br_except_pre($str)
 	{
 		$CI =& get_instance();
@@ -55,16 +55,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Auto Typography Wrapper Function
- *
- * @param	string
- * @param	bool	whether to allow javascript event handlers
- * @param	bool	whether to reduce multiple instances of double newlines to two
- * @return	string
- */
 if ( ! function_exists('auto_typography'))
 {
+	/**
+	 * Auto Typography Wrapper Function
+	 *
+	 * @param	string
+	 * @param	bool	whether to allow javascript event handlers
+	 * @param	bool	whether to reduce multiple instances of double newlines to two
+	 * @return	string
+	 */
 	function auto_typography($str, $strip_js_event_handlers = TRUE, $reduce_linebreaks = FALSE)
 	{
 		$CI =& get_instance();
@@ -73,20 +73,19 @@
 	}
 }
 
-
 // --------------------------------------------------------------------
 
-/**
- * HTML Entities Decode
- *
- * This function is a replacement for html_entity_decode()
- *
- * @param	string
- * @param	string
- * @return	string
- */
 if ( ! function_exists('entity_decode'))
 {
+	/**
+	 * HTML Entities Decode
+	 *
+	 * This function is a replacement for html_entity_decode()
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	string
+	 */
 	function entity_decode($str, $charset = NULL)
 	{
 		global $SEC;
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
index 5576c27..2bd41b0 100644
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -37,17 +37,17 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Site URL
- *
- * Create a local URL based on your basepath. Segments can be passed via the
- * first parameter either as a string or an array.
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('site_url'))
 {
+	/**
+	 * Site URL
+	 *
+	 * Create a local URL based on your basepath. Segments can be passed via the
+	 * first parameter either as a string or an array.
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function site_url($uri = '')
 	{
 		$CI =& get_instance();
@@ -57,18 +57,18 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Base URL
- *
- * Create a local URL based on your basepath.
- * Segments can be passed in as a string or an array, same as site_url
- * or a URL to a file can be passed in, e.g. to an image file.
- *
- * @param	string
- * @return	string
- */
 if ( ! function_exists('base_url'))
 {
+	/**
+	 * Base URL
+	 *
+	 * Create a local URL based on your basepath.
+	 * Segments can be passed in as a string or an array, same as site_url
+	 * or a URL to a file can be passed in, e.g. to an image file.
+	 *
+	 * @param	string
+	 * @return	string
+	 */
 	function base_url($uri = '')
 	{
 		$CI =& get_instance();
@@ -78,16 +78,16 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Current URL
- *
- * Returns the full URL (including segments) of the page where this
- * function is placed
- *
- * @return	string
- */
 if ( ! function_exists('current_url'))
 {
+	/**
+	 * Current URL
+	 *
+	 * Returns the full URL (including segments) of the page where this
+	 * function is placed
+	 *
+	 * @return	string
+	 */
 	function current_url()
 	{
 		$CI =& get_instance();
@@ -96,15 +96,16 @@
 }
 
 // ------------------------------------------------------------------------
-/**
- * URL String
- *
- * Returns the URI segments.
- *
- * @return	string
- */
+
 if ( ! function_exists('uri_string'))
 {
+	/**
+	 * URL String
+	 *
+	 * Returns the URI segments.
+	 *
+	 * @return	string
+	 */
 	function uri_string()
 	{
 		$CI =& get_instance();
@@ -114,15 +115,15 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Index page
- *
- * Returns the "index_page" from your config file
- *
- * @return	string
- */
 if ( ! function_exists('index_page'))
 {
+	/**
+	 * Index page
+	 *
+	 * Returns the "index_page" from your config file
+	 *
+	 * @return	string
+	 */
 	function index_page()
 	{
 		$CI =& get_instance();
@@ -132,18 +133,18 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Anchor Link
- *
- * Creates an anchor based on the local URL.
- *
- * @param	string	the URL
- * @param	string	the link title
- * @param	mixed	any attributes
- * @return	string
- */
 if ( ! function_exists('anchor'))
 {
+	/**
+	 * Anchor Link
+	 *
+	 * Creates an anchor based on the local URL.
+	 *
+	 * @param	string	the URL
+	 * @param	string	the link title
+	 * @param	mixed	any attributes
+	 * @return	string
+	 */
 	function anchor($uri = '', $title = '', $attributes = '')
 	{
 		$title = (string) $title;
@@ -157,12 +158,12 @@
 			$site_url = site_url($uri);
 		}
 
-		if ($title == '')
+		if ($title === '')
 		{
 			$title = $site_url;
 		}
 
-		if ($attributes != '')
+		if ($attributes !== '')
 		{
 			$attributes = _parse_attributes($attributes);
 		}
@@ -173,32 +174,32 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Anchor Link - Pop-up version
- *
- * Creates an anchor based on the local URL. The link
- * opens a new window based on the attributes specified.
- *
- * @param	string	the URL
- * @param	string	the link title
- * @param	mixed	any attributes
- * @return	string
- */
 if ( ! function_exists('anchor_popup'))
 {
+	/**
+	 * Anchor Link - Pop-up version
+	 *
+	 * Creates an anchor based on the local URL. The link
+	 * opens a new window based on the attributes specified.
+	 *
+	 * @param	string	the URL
+	 * @param	string	the link title
+	 * @param	mixed	any attributes
+	 * @return	string
+	 */
 	function anchor_popup($uri = '', $title = '', $attributes = FALSE)
 	{
 		$title = (string) $title;
 		$site_url = preg_match('!^\w+://! i', $uri) ? $uri : site_url($uri);
 
-		if ($title == '')
+		if ($title === '')
 		{
 			$title = $site_url;
 		}
 
 		if ($attributes === FALSE)
 		{
-			return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank');\">".$title.'</a>';
+			return '<a href="javascript:void(0);" onclick="window.open(\''.$site_url."', '_blank');\">".$title.'</a>';
 		}
 
 		if ( ! is_array($attributes))
@@ -212,32 +213,32 @@
 			unset($attributes[$key]);
 		}
 
-		if ($attributes != '')
+		if ($attributes !== '')
 		{
 			$attributes = _parse_attributes($attributes);
 		}
 
-		return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank', '"._parse_attributes($atts, TRUE)."');\"".$attributes.'>'.$title.'</a>';
+		return '<a href="javascript:void(0);" onclick="window.open(\''.$site_url."', '_blank', '"._parse_attributes($atts, TRUE)."');\"".$attributes.'>'.$title.'</a>';
 	}
 }
 
 // ------------------------------------------------------------------------
 
-/**
- * Mailto Link
- *
- * @param	string	the email address
- * @param	string	the link title
- * @param	mixed	any attributes
- * @return	string
- */
 if ( ! function_exists('mailto'))
 {
+	/**
+	 * Mailto Link
+	 *
+	 * @param	string	the email address
+	 * @param	string	the link title
+	 * @param	mixed	any attributes
+	 * @return	string
+	 */
 	function mailto($email, $title = '', $attributes = '')
 	{
 		$title = (string) $title;
 
-		if ($title == '')
+		if ($title === '')
 		{
 			$title = $email;
 		}
@@ -248,23 +249,23 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Encoded Mailto Link
- *
- * Create a spam-protected mailto link written in Javascript
- *
- * @param	string	the email address
- * @param	string	the link title
- * @param	mixed	any attributes
- * @return	string
- */
 if ( ! function_exists('safe_mailto'))
 {
+	/**
+	 * Encoded Mailto Link
+	 *
+	 * Create a spam-protected mailto link written in Javascript
+	 *
+	 * @param	string	the email address
+	 * @param	string	the link title
+	 * @param	mixed	any attributes
+	 * @return	string
+	 */
 	function safe_mailto($email, $title = '', $attributes = '')
 	{
 		$title = (string) $title;
 
-		if ($title == '')
+		if ($title === '')
 		{
 			$title = $email;
 		}
@@ -278,7 +279,7 @@
 
 		$x[] = '"';
 
-		if ($attributes != '')
+		if ($attributes !== '')
 		{
 			if (is_array($attributes))
 			{
@@ -344,7 +345,7 @@
 	for ($i = 0, $c = count($x); $i < $c; $i++) { ?>l[<?php echo $i; ?>]='<?php echo $x[$i]; ?>';<?php } ?>
 
 	for (var i = l.length-1; i >= 0; i=i-1){
-	if (l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");
+	if (l[i].substring(0, 1) === '|') document.write("&#"+unescape(l[i].substring(1))+";");
 	else document.write(unescape(l[i]));}
 	//]]>
 	</script><?php
@@ -357,21 +358,21 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Auto-linker
- *
- * Automatically links URL and Email addresses.
- * Note: There's a bit of extra code here to deal with
- * URLs or emails that end in a period. We'll strip these
- * off and add them after the link.
- *
- * @param	string	the string
- * @param	string	the type: email, url, or both
- * @param	bool	whether to create pop-up links
- * @return	string
- */
 if ( ! function_exists('auto_link'))
 {
+	/**
+	 * Auto-linker
+	 *
+	 * Automatically links URL and Email addresses.
+	 * Note: There's a bit of extra code here to deal with
+	 * URLs or emails that end in a period. We'll strip these
+	 * off and add them after the link.
+	 *
+	 * @param	string	the string
+	 * @param	string	the type: email, url, or both
+	 * @param	bool	whether to create pop-up links
+	 * @return	string
+	 */
 	function auto_link($str, $type = 'both', $popup = FALSE)
 	{
 		if ($type !== 'email' && preg_match_all('#(^|\s|\(|\b)((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i', $str, $matches))
@@ -423,19 +424,19 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Prep URL
- *
- * Simply adds the http:// part if no scheme is included
- *
- * @param	string	the URL
- * @return	string
- */
 if ( ! function_exists('prep_url'))
 {
+	/**
+	 * Prep URL
+	 *
+	 * Simply adds the http:// part if no scheme is included
+	 *
+	 * @param	string	the URL
+	 * @return	string
+	 */
 	function prep_url($str = '')
 	{
-		if ($str === 'http://' OR $str == '')
+		if ($str === 'http://' OR $str === '')
 		{
 			return '';
 		}
@@ -453,20 +454,20 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Create URL Title
- *
- * Takes a "title" string as input and creates a
- * human-friendly URL string with a "separator" string
- * as the word separator.
- *
- * @param	string	the string
- * @param	string	the separator
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('url_title'))
 {
+	/**
+	 * Create URL Title
+	 *
+	 * Takes a "title" string as input and creates a
+	 * human-friendly URL string with a "separator" string
+	 * as the word separator.
+	 *
+	 * @param	string	the string
+	 * @param	string	the separator
+	 * @param	bool
+	 * @return	string
+	 */
 	function url_title($str, $separator = '-', $lowercase = FALSE)
 	{
 		if ($separator === 'dash')
@@ -504,19 +505,20 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Header Redirect
- *
- * Header redirect in two flavors
- * For very fine grained control over headers, you could use the Output
- * Library's set_header() function.
- *
- * @param	string	the URL
- * @param	string	the method: location or refresh
- * @return	string
- */
 if ( ! function_exists('redirect'))
 {
+	/**
+	 * Header Redirect
+	 *
+	 * Header redirect in two flavors
+	 * For very fine grained control over headers, you could use the Output
+	 * Library's set_header() function.
+	 *
+	 * @param	string	the URL
+	 * @param	string	the method: location or refresh
+	 * @param	int
+	 * @return	string
+	 */
 	function redirect($uri = '', $method = 'auto', $http_response_code = 302)
 	{
 		if ( ! preg_match('#^https?://#i', $uri))
@@ -545,28 +547,28 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Parse out the attributes
- *
- * Some of the functions use this
- *
- * @param	array
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('_parse_attributes'))
 {
+	/**
+	 * Parse out the attributes
+	 *
+	 * Some of the functions use this
+	 *
+	 * @param	array
+	 * @param	bool
+	 * @return	string
+	 */
 	function _parse_attributes($attributes, $javascript = FALSE)
 	{
 		if (is_string($attributes))
 		{
-			return ($attributes != '') ? ' '.$attributes : '';
+			return ($attributes !== '') ? ' '.$attributes : '';
 		}
 
 		$att = '';
 		foreach ($attributes as $key => $val)
 		{
-			if ($javascript == TRUE)
+			if ($javascript === TRUE)
 			{
 				$att .= $key.'='.$val.',';
 			}
@@ -576,7 +578,7 @@
 			}
 		}
 
-		if ($javascript == TRUE && $att != '')
+		if ($javascript === TRUE && $att !== '')
 		{
 			return substr($att, 0, -1);
 		}
diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php
index 67fd34b..1431777 100644
--- a/system/helpers/xml_helper.php
+++ b/system/helpers/xml_helper.php
@@ -37,15 +37,15 @@
 
 // ------------------------------------------------------------------------
 
-/**
- * Convert Reserved XML characters to Entities
- *
- * @param	string
- * @param	bool
- * @return	string
- */
 if ( ! function_exists('xml_convert'))
 {
+	/**
+	 * Convert Reserved XML characters to Entities
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	string
+	 */
 	function xml_convert($str, $protect_all = FALSE)
 	{
 		$temp = '__TEMP_AMPERSANDS__';
@@ -54,7 +54,7 @@
 		// ampersands won't get messed up
 		$str = preg_replace('/&#(\d+);/', $temp.'\\1;', $str);
 
-		if ($protect_all == TRUE)
+		if ($protect_all === TRUE)
 		{
 			$str = preg_replace('/&(\w+);/', $temp.'\\1;', $str);
 		}
@@ -66,7 +66,7 @@
 		// Decode the temp markers back to entities
 		$str = preg_replace('/'.$temp.'(\d+);/', '&#\\1;', $str);
 
-		if ($protect_all == TRUE)
+		if ($protect_all === TRUE)
 		{
 			return preg_replace('/'.$temp.'(\w+);/', '&\\1;', $str);
 		}
diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php
index 2d477e6..48939d4 100644
--- a/system/language/english/calendar_lang.php
+++ b/system/language/english/calendar_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php
index 5335637..38532b7 100644
--- a/system/language/english/date_lang.php
+++ b/system/language/english/date_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php
index a135d1a..479cbb1 100644
--- a/system/language/english/db_lang.php
+++ b/system/language/english/db_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php
index 23296a2..95a16d1 100644
--- a/system/language/english/email_lang.php
+++ b/system/language/english/email_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index 6cf0b46..eb4624e 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php
index 4e39e43..d00126b 100644
--- a/system/language/english/ftp_lang.php
+++ b/system/language/english/ftp_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php
index 67ca942..67a36e1 100644
--- a/system/language/english/imglib_lang.php
+++ b/system/language/english/imglib_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/migration_lang.php b/system/language/english/migration_lang.php
index 2085cee..9e3e188 100644
--- a/system/language/english/migration_lang.php
+++ b/system/language/english/migration_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/number_lang.php b/system/language/english/number_lang.php
index 0c19ec6..429c647 100644
--- a/system/language/english/number_lang.php
+++ b/system/language/english/number_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
@@ -25,11 +25,11 @@
  * @filesource
  */
 
-$lang['terabyte_abbr'] = "TB";
-$lang['gigabyte_abbr'] = "GB";
-$lang['megabyte_abbr'] = "MB";
-$lang['kilobyte_abbr'] = "KB";
-$lang['bytes'] = "Bytes";
+$lang['terabyte_abbr'] = 'TB';
+$lang['gigabyte_abbr'] = 'GB';
+$lang['megabyte_abbr'] = 'MB';
+$lang['kilobyte_abbr'] = 'KB';
+$lang['bytes'] = 'Bytes';
 
 /* End of file number_lang.php */
 /* Location: ./system/language/english/number_lang.php */
\ No newline at end of file
diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php
index 11d7912..112527f 100644
--- a/system/language/english/profiler_lang.php
+++ b/system/language/english/profiler_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php
index 3a8e144..36e9aca 100644
--- a/system/language/english/unit_test_lang.php
+++ b/system/language/english/unit_test_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php
index 4fa8394..c3cb9c3 100644
--- a/system/language/english/upload_lang.php
+++ b/system/language/english/upload_lang.php
@@ -5,9 +5,9 @@
  * An open source application development framework for PHP 5.2.4 or newer
  *
  * NOTICE OF LICENSE
- * 
+ *
  * Licensed under the Open Software License version 3.0
- * 
+ *
  * This source file is subject to the Open Software License (OSL 3.0) that is
  * bundled with this package in the files license.txt / license.rst.  It is
  * also available through the world wide web at this URL:
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
index f982416..53f9f81 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -36,17 +36,39 @@
  */
 class CI_Cache extends CI_Driver_Library {
 
-	protected $valid_drivers 	= array(
-						'cache_apc',
-						'cache_file',
-						'cache_memcached',
-						'cache_dummy',
-						'cache_wincache'
-					);
+	/**
+	 * Valid cache drivers
+	 *
+	 * @var array
+	 */
+	protected $valid_drivers = array(
+		'cache_apc',
+		'cache_file',
+		'cache_memcached',
+		'cache_dummy',
+		'cache_wincache'
+	);
 
-	protected $_cache_path		= NULL;	// Path of cache files (if file-based cache)
-	protected $_adapter		= 'dummy';
-	protected $_backup_driver;
+	/**
+	 * Path of cache files (if file-based cache)
+	 *
+	 * @var string
+	 */
+	protected $_cache_path = NULL;
+
+	/**
+	 * Reference to the driver
+	 *
+	 * @var mixed
+	 */
+	protected $_adapter = 'dummy';
+
+	/**
+	 * Fallback driver
+	 *
+	 * @param string
+	 */
+	protected $_backup_driver = 'dummy';
 
 	/**
 	 * Constructor
@@ -59,9 +81,9 @@
 	public function __construct($config = array())
 	{
 		$default_config = array(
-				'adapter',
-				'memcached'
-			);
+			'adapter',
+			'memcached'
+		);
 
 		foreach ($default_config as $key)
 		{
@@ -80,6 +102,22 @@
 				$this->_backup_driver = $config['backup'];
 			}
 		}
+
+		// If the specified adapter isn't available, check the backup.
+		if ( ! $this->is_supported($this->_adapter))
+		{
+			if ( ! $this->is_supported($this->_backup_driver))
+			{
+				// Backup isn't supported either. Default to 'Dummy' driver.
+				log_message('error', 'Cache adapter "'.$this->_adapter.'" and backup "'.$this->_backup_driver.'" are both unavailable. Cache is now using "Dummy" adapter.');
+				$this->_adapter = 'dummy';
+			}
+			else
+			{
+				// Backup is supported. Set it to primary.
+				$this->_adapter = $this->_backup_driver;
+			}
+		}
 	}
 
 	// ------------------------------------------------------------------------
@@ -184,26 +222,6 @@
 		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 of file Cache.php */
diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php
index 59ab675..c85034f 100644
--- a/system/libraries/Cache/drivers/Cache_apc.php
+++ b/system/libraries/Cache/drivers/Cache_apc.php
@@ -75,7 +75,7 @@
 	 * Delete from Cache
 	 *
 	 * @param	mixed	unique identifier of the item in the cache
-	 * @param	bool	true on success/false on failure
+	 * @return	bool	true on success/false on failure
 	 */
 	public function delete($id)
 	{
diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php
index e8b791c..3f2b4b9 100644
--- a/system/libraries/Cache/drivers/Cache_dummy.php
+++ b/system/libraries/Cache/drivers/Cache_dummy.php
@@ -70,7 +70,7 @@
 	 * Delete from Cache
 	 *
 	 * @param	mixed	unique identifier of the item in the cache
-	 * @param	bool	TRUE, simulating success
+	 * @return	bool	TRUE, simulating success
 	 */
 	public function delete($id)
 	{
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index dd27aa9..5170de8 100644
--- a/system/libraries/Cache/drivers/Cache_file.php
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -36,14 +36,24 @@
  */
 class CI_Cache_file extends CI_Driver {
 
+	/**
+	 * Directory in which to save cache files
+	 *
+	 * @var string
+	 */
 	protected $_cache_path;
 
+	/**
+	 * Initialize file-based cache
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
 		$CI =& get_instance();
 		$CI->load->helper('file');
 		$path = $CI->config->item('cache_path');
-		$this->_cache_path = ($path == '') ? APPPATH.'cache/' : $path;
+		$this->_cache_path = ($path === '') ? APPPATH.'cache/' : $path;
 	}
 
 	// ------------------------------------------------------------------------
@@ -61,7 +71,7 @@
 			return FALSE;
 		}
 
-		$data = unserialize(read_file($this->_cache_path.$id));
+		$data = unserialize(file_get_contents($this->_cache_path.$id));
 
 		if (time() >  $data['time'] + $data['ttl'])
 		{
@@ -86,10 +96,10 @@
 	public function save($id, $data, $ttl = 60)
 	{
 		$contents = array(
-				'time'		=> time(),
-				'ttl'		=> $ttl,
-				'data'		=> $data
-			);
+			'time'		=> time(),
+			'ttl'		=> $ttl,
+			'data'		=> $data
+		);
 
 		if (write_file($this->_cache_path.$id, serialize($contents)))
 		{
@@ -155,7 +165,7 @@
 			return FALSE;
 		}
 
-		$data = unserialize(read_file($this->_cache_path.$id));
+		$data = unserialize(file_get_contents($this->_cache_path.$id));
 
 		if (is_array($data))
 		{
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index 1028c8f..bf90f61 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -36,15 +36,25 @@
  */
 class CI_Cache_memcached extends CI_Driver {
 
-	protected $_memcached;	// Holds the memcached object
+	/**
+	 * Holds the memcached object
+	 *
+	 * @var object
+	 */
+	protected $_memcached;
 
+	/**
+	 * Memcached configuration
+	 *
+	 * @var array
+	 */
 	protected $_memcache_conf	= array(
-					'default' => array(
-						'default_host'		=> '127.0.0.1',
-						'default_port'		=> 11211,
-						'default_weight'	=> 1
-					)
-				);
+		'default' => array(
+			'default_host'		=> '127.0.0.1',
+			'default_port'		=> 11211,
+			'default_weight'	=> 1
+		)
+	);
 
 	/**
 	 * Fetch from cache
@@ -67,7 +77,7 @@
 	 * @param	string	unique identifier
 	 * @param	mixed	data being cached
 	 * @param	int	time to live
-	 * @return	bool true on success, false on failure
+	 * @return	bool	true on success, false on failure
 	 */
 	public function save($id, $data, $ttl = 60)
 	{
@@ -89,7 +99,7 @@
 	 * Delete from Cache
 	 *
 	 * @param	mixed	key to be deleted.
-	 * @return	bool true on success, false on failure
+	 * @return	bool	true on success, false on failure
 	 */
 	public function delete($id)
 	{
@@ -189,20 +199,20 @@
 		{
 			if ( ! array_key_exists('hostname', $cache_server))
 			{
-				$cache_server['hostname'] = $this->_default_options['default_host'];
+				$cache_server['hostname'] = $this->_memcache_conf['default']['default_host'];
 			}
 
 			if ( ! array_key_exists('port', $cache_server))
 			{
-				$cache_server['port'] = $this->_default_options['default_port'];
+				$cache_server['port'] = $this->_memcache_conf['default']['default_port'];
 			}
 
 			if ( ! array_key_exists('weight', $cache_server))
 			{
-				$cache_server['weight'] = $this->_default_options['default_weight'];
+				$cache_server['weight'] = $this->_memcache_conf['default']['default_weight'];
 			}
 
-			if (get_class($this->_memcached) == 'Memcache')
+			if (get_class($this->_memcached) === 'Memcache')
 			{
 				// Third parameter is persistance and defaults to TRUE.
 				$this->_memcached->addServer(
diff --git a/system/libraries/Cache/drivers/Cache_wincache.php b/system/libraries/Cache/drivers/Cache_wincache.php
index b32e66a..74048d5 100644
--- a/system/libraries/Cache/drivers/Cache_wincache.php
+++ b/system/libraries/Cache/drivers/Cache_wincache.php
@@ -78,7 +78,7 @@
 	 * Delete from Cache
 	 *
 	 * @param	mixed	unique identifier of the item in the cache
-	 * @param	bool	true on success/false on failure
+	 * @return	bool	true on success/false on failure
 	 */
 	public function delete($id)
 	{
diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php
index b6f145d..969a761 100644
--- a/system/libraries/Calendar.php
+++ b/system/libraries/Calendar.php
@@ -38,15 +38,61 @@
  */
 class CI_Calendar {
 
+	/**
+	 * Reference to CodeIgniter instance
+	 *
+	 * @var object
+	 */
 	protected $CI;
-	public $lang;
+
+	/**
+	 * Current local time
+	 *
+	 * @var int
+	 */
 	public $local_time;
+
+	/**
+	 * Calendar layout template
+	 *
+	 * @var string
+	 */
 	public $template		= '';
+
+	/**
+	 * Day of the week to start the calendar on
+	 *
+	 * @var string
+	 */
 	public $start_day		= 'sunday';
+
+	/**
+	 * How to display months
+	 *
+	 * @var string
+	 */
 	public $month_type		= 'long';
+
+	/**
+	 * How to display names of days
+	 *
+	 * @var string
+	 */
 	public $day_type		= 'abr';
-	public $show_next_prev	= FALSE;
-	public $next_prev_url	= '';
+
+	/**
+	 * Whether to show next/prev month links
+	 *
+	 * @var bool
+	 */
+	public $show_next_prev		= FALSE;
+
+	/**
+	 * Url base to use for next/prev month links
+	 *
+	 * @var bool
+	 */
+	public $next_prev_url		= '';
 
 	/**
 	 * Constructor
@@ -109,7 +155,7 @@
 	public function generate($year = '', $month = '', $data = array())
 	{
 		// Set and validate the supplied month/year
-		if ($year == '')
+		if ($year === '')
 		{
 			$year  = date('Y', $this->local_time);
 		}
@@ -122,7 +168,7 @@
 			$year = '20'.$year;
 		}
 
-		if ($month == '')
+		if ($month === '')
 		{
 			$month = date('m', $this->local_time);
 		}
@@ -141,7 +187,7 @@
 
 		// Set the starting day of the week
 		$start_days	= array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6);
-		$start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day];
+		$start_day	= isset($start_days[$this->start_day]) ? $start_days[$this->start_day] : 0;
 
 		// Set the starting day number
 		$local_date = mktime(12, 0, 0, $month, 1, $year);
@@ -168,7 +214,7 @@
 		$out = $this->temp['table_open']."\n\n".$this->temp['heading_row_start']."\n";
 
 		// "previous" month link
-		if ($this->show_next_prev == TRUE)
+		if ($this->show_next_prev === TRUE)
 		{
 			// Add a trailing slash to the  URL if needed
 			$this->next_prev_url = preg_replace('/(.+?)\/*$/', '\\1/',  $this->next_prev_url);
@@ -178,7 +224,7 @@
 		}
 
 		// Heading containing the month/year
-		$colspan = ($this->show_next_prev == TRUE) ? 5 : 7;
+		$colspan = ($this->show_next_prev === TRUE) ? 5 : 7;
 
 		$this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan,
 								str_replace('{heading}', $this->get_month_name($month).'&nbsp;'.$year, $this->temp['heading_title_cell']));
@@ -186,7 +232,7 @@
 		$out .= $this->temp['heading_title_cell']."\n";
 
 		// "next" month link
-		if ($this->show_next_prev == TRUE)
+		if ($this->show_next_prev === TRUE)
 		{
 			$adjusted_date = $this->adjust_date($month + 1, $year);
 			$out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']);
@@ -244,9 +290,7 @@
 			$out .= "\n".$this->temp['cal_row_end']."\n";
 		}
 
-		$out .= "\n".$this->temp['table_close'];
-
-		return $out;
+		return $out .= "\n".$this->temp['table_close'];
 	}
 
 	// --------------------------------------------------------------------
@@ -262,7 +306,7 @@
 	 */
 	public function get_month_name($month)
 	{
-		if ($this->month_type == 'short')
+		if ($this->month_type === 'short')
 		{
 			$month_names = array('01' => 'cal_jan', '02' => 'cal_feb', '03' => 'cal_mar', '04' => 'cal_apr', '05' => 'cal_may', '06' => 'cal_jun', '07' => 'cal_jul', '08' => 'cal_aug', '09' => 'cal_sep', '10' => 'cal_oct', '11' => 'cal_nov', '12' => 'cal_dec');
 		}
@@ -271,14 +315,9 @@
 			$month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_mayl', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december');
 		}
 
-		$month = $month_names[$month];
-
-		if ($this->CI->lang->line($month) === FALSE)
-		{
-			return ucfirst(substr($month, 4));
-		}
-
-		return $this->CI->lang->line($month);
+		return ($this->CI->lang->line($month_names[$month]) === FALSE)
+			? ucfirst(substr($month_names[$month], 4))
+			: $this->CI->lang->line($month_names[$month]);
 	}
 
 	// --------------------------------------------------------------------
@@ -294,16 +333,16 @@
 	 */
 	public function get_day_names($day_type = '')
 	{
-		if ($day_type != '')
+		if ($day_type !== '')
 		{
 			$this->day_type = $day_type;
 		}
 
-		if ($this->day_type == 'long')
+		if ($this->day_type === 'long')
 		{
 			$day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
 		}
-		elseif ($this->day_type == 'short')
+		elseif ($this->day_type === 'short')
 		{
 			$day_names = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
 		}
@@ -382,7 +421,7 @@
 		// Is the year a leap year?
 		if ($month == 2)
 		{
-			if ($year % 400 == 0 OR ($year % 4 == 0 && $year % 100 != 0))
+			if ($year % 400 === 0 OR ($year % 4 === 0 && $year % 100 !== 0))
 			{
 				return 29;
 			}
@@ -402,29 +441,29 @@
 	 */
 	public function default_template()
 	{
-		return  array (
-						'table_open'				=> '<table border="0" cellpadding="4" cellspacing="0">',
-						'heading_row_start'			=> '<tr>',
-						'heading_previous_cell'		=> '<th><a href="{previous_url}">&lt;&lt;</a></th>',
-						'heading_title_cell'		=> '<th colspan="{colspan}">{heading}</th>',
-						'heading_next_cell'			=> '<th><a href="{next_url}">&gt;&gt;</a></th>',
-						'heading_row_end'			=> '</tr>',
-						'week_row_start'			=> '<tr>',
-						'week_day_cell'				=> '<td>{week_day}</td>',
-						'week_row_end'				=> '</tr>',
-						'cal_row_start'				=> '<tr>',
-						'cal_cell_start'			=> '<td>',
-						'cal_cell_start_today'		=> '<td>',
-						'cal_cell_content'			=> '<a href="{content}">{day}</a>',
-						'cal_cell_content_today'	=> '<a href="{content}"><strong>{day}</strong></a>',
-						'cal_cell_no_content'		=> '{day}',
-						'cal_cell_no_content_today'	=> '<strong>{day}</strong>',
-						'cal_cell_blank'			=> '&nbsp;',
-						'cal_cell_end'				=> '</td>',
-						'cal_cell_end_today'		=> '</td>',
-						'cal_row_end'				=> '</tr>',
-						'table_close'				=> '</table>'
-					);
+		return  array(
+			'table_open'				=> '<table border="0" cellpadding="4" cellspacing="0">',
+			'heading_row_start'			=> '<tr>',
+			'heading_previous_cell'		=> '<th><a href="{previous_url}">&lt;&lt;</a></th>',
+			'heading_title_cell'		=> '<th colspan="{colspan}">{heading}</th>',
+			'heading_next_cell'			=> '<th><a href="{next_url}">&gt;&gt;</a></th>',
+			'heading_row_end'			=> '</tr>',
+			'week_row_start'			=> '<tr>',
+			'week_day_cell'				=> '<td>{week_day}</td>',
+			'week_row_end'				=> '</tr>',
+			'cal_row_start'				=> '<tr>',
+			'cal_cell_start'			=> '<td>',
+			'cal_cell_start_today'		=> '<td>',
+			'cal_cell_content'			=> '<a href="{content}">{day}</a>',
+			'cal_cell_content_today'	=> '<a href="{content}"><strong>{day}</strong></a>',
+			'cal_cell_no_content'		=> '{day}',
+			'cal_cell_no_content_today'	=> '<strong>{day}</strong>',
+			'cal_cell_blank'			=> '&nbsp;',
+			'cal_cell_end'				=> '</td>',
+			'cal_cell_end_today'		=> '</td>',
+			'cal_row_end'				=> '</tr>',
+			'table_close'				=> '</table>'
+		);
 	}
 
 	// --------------------------------------------------------------------
@@ -441,7 +480,7 @@
 	{
 		$this->temp = $this->default_template();
 
-		if ($this->template == '')
+		if ($this->template === '')
 		{
 			return;
 		}
diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php
index ca7be55..c442f88 100644
--- a/system/libraries/Cart.php
+++ b/system/libraries/Cart.php
@@ -36,19 +36,54 @@
  */
 class CI_Cart {
 
-	// These are the regular expression rules that we use to validate the product ID and product name
-	public $product_id_rules	= '\.a-z0-9_-'; // alpha-numeric, dashes, underscores, or periods
-	public $product_name_rules	= '\.\:\-_ a-z0-9'; // alpha-numeric, dashes, underscores, colons or periods
-	public $product_name_safe	= TRUE; // only allow safe product names
+	/**
+	 * These are the regular expression rules that we use to validate the product ID and product name
+	 * alpha-numeric, dashes, underscores, or periods
+	 *
+	 * @var string
+	 */
+	public $product_id_rules	= '\.a-z0-9_-';
 
+	/**
+	 * These are the regular expression rules that we use to validate the product ID and product name
+	 * alpha-numeric, dashes, underscores, colons or periods
+	 *
+	 * @var string
+	 */
+	public $product_name_rules	= '\.\:\-_ a-z0-9';
+
+	/**
+	 * only allow safe product names
+	 *
+	 * @var bool
+	 */
+	public $product_name_safe	= TRUE;
+
+	// --------------------------------------------------------------------------
 	// Protected variables. Do not change!
+	// --------------------------------------------------------------------------
+
+	/**
+	 * Reference to CodeIgniter instance
+	 *
+	 * @var object
+	 */
 	protected $CI;
+
+	/**
+	 * Contents of the cart
+	 *
+	 * @var array
+	 */
 	protected $_cart_contents	= array();
 
 	/**
 	 * Shopping Class Constructor
 	 *
 	 * The constructor loads the Session class, used to store the shopping cart contents.
+	 *
+	 * @param	array
+	 * @return	void
 	 */
 	public function __construct($params = array())
 	{
@@ -146,7 +181,7 @@
 		// --------------------------------------------------------------------
 
 		// Does the $items array contain an id, quantity, price, and name?  These are required
-		if ( ! isset($items['id']) OR ! isset($items['qty']) OR ! isset($items['price']) OR ! isset($items['name']))
+		if ( ! isset($items['id'], $items['qty'], $items['price'], $items['name']))
 		{
 			log_message('error', 'The cart array must contain a product ID, quantity, price, and name.');
 			return FALSE;
@@ -210,7 +245,7 @@
 		// This becomes the unique "row ID"
 		if (isset($items['options']) && count($items['options']) > 0)
 		{
-			$rowid = md5($items['id'].implode('', $items['options']));
+			$rowid = md5($items['id'].serialize($items['options']));
 		}
 		else
 		{
@@ -245,7 +280,6 @@
 	 * product ID and quantity for each item.
 	 *
 	 * @param	array
-	 * @param	string
 	 * @return	bool
 	 */
 	public function update($items = array())
@@ -308,7 +342,7 @@
 	protected function _update($items = array())
 	{
 		// Without these array indexes there is nothing we can do
-		if ( ! isset($items['qty']) OR ! isset($items['rowid']) OR ! isset($this->_cart_contents[$items['rowid']]))
+		if ( ! isset($items['qty'], $items['rowid'], $this->_cart_contents[$items['rowid']]))
 		{
 			return FALSE;
 		}
@@ -350,7 +384,7 @@
 		foreach ($this->_cart_contents as $key => $val)
 		{
 			// We make sure the array contains the proper indexes
-			if ( ! is_array($val) OR ! isset($val['price']) OR ! isset($val['qty']))
+			if ( ! is_array($val) OR ! isset($val['price'], $val['qty']))
 			{
 				continue;
 			}
@@ -360,7 +394,7 @@
 			$this->_cart_contents[$key]['subtotal'] = ($this->_cart_contents[$key]['price'] * $this->_cart_contents[$key]['qty']);
 		}
 
-		// Is our cart empty?  If so we delete it from the session
+		// Is our cart empty? If so we delete it from the session
 		if (count($this->_cart_contents) <= 2)
 		{
 			$this->CI->session->unset_userdata('cart_contents');
@@ -396,6 +430,7 @@
 	 *
 	 * Removes an item from the cart
 	 *
+	 * @param	int
 	 * @return	bool
 	 */
 	 public function remove($rowid)
@@ -427,6 +462,7 @@
 	 *
 	 * Returns the entire cart array
 	 *
+	 * @param	bool
 	 * @return	array
 	 */
 	public function contents($newest_first = FALSE)
@@ -449,11 +485,12 @@
 	 * Returns TRUE if the rowid passed to this function correlates to an item
 	 * that has options associated with it.
 	 *
+	 * @param	mixed
 	 * @return	bool
 	 */
 	public function has_options($rowid = '')
 	{
-		return (isset($this->_cart_contents[$rowid]['options']) && count($this->_cart_contents[$rowid]['options']) !== 0) ? TRUE : FALSE;
+		return (isset($this->_cart_contents[$rowid]['options']) && count($this->_cart_contents[$rowid]['options']) !== 0);
 	}
 
 	// --------------------------------------------------------------------
@@ -483,15 +520,7 @@
 	 */
 	public function format_number($n = '')
 	{
-		if ($n == '')
-		{
-			return '';
-		}
-
-		// Remove anything that isn't a number or decimal point.
-		$n = (float) $n;
-
-		return number_format($n, 2, '.', ',');
+		return ($n === '') ? '' : number_format( (float) $n, 2, '.', ',');
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php
index f409f47..d67ee25 100644
--- a/system/libraries/Driver.php
+++ b/system/libraries/Driver.php
@@ -39,11 +39,27 @@
  */
 class CI_Driver_Library {
 
-	protected $valid_drivers	= array();
-	protected static $lib_name;
+	/**
+	 * Array of drivers that are available to use with the driver class
+	 *
+	 * @var array
+	 */
+	protected $valid_drivers = array();
 
-	// The first time a child is used it won't exist, so we instantiate it
-	// subsequents calls will go straight to the proper child.
+	/**
+	 * Name of the current class - usually the driver class
+	 *
+	 * @var string
+	 */
+	protected $lib_name;
+
+	/**
+	 * The first time a child is used it won't exist, so we instantiate it
+	 * subsequents calls will go straight to the proper child.
+	 *
+	 * @param	mixed	$child
+	 * @return	mixed
+	 */
 	public function __get($child)
 	{
 		if ( ! isset($this->lib_name))
@@ -100,6 +116,8 @@
 
 }
 
+// --------------------------------------------------------------------------
+
 /**
  * CodeIgniter Driver Class
  *
@@ -114,11 +132,32 @@
  */
 class CI_Driver {
 
+	/**
+	 * Instance of the parent class
+	 *
+	 * @var object
+	 */
 	protected $_parent;
 
+	/**
+	 * List of methods in the parent class
+	 *
+	 * @var array
+	 */
 	protected $_methods = array();
+
+	/**
+	 * List of properties in the parent class
+	 *
+	 * @var array
+	 */
 	protected $_properties = array();
 
+	/**
+	 * Array of methods and properties for the parent class(es)
+	 *
+	 * @var array
+	 */
 	protected static $_reflections = array();
 
 	/**
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 8f383c9..c70144f 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -93,6 +93,8 @@
 	 * Constructor - Sets Email Preferences
 	 *
 	 * The constructor can be passed an array of config values
+	 *
+	 * @return	void
 	 */
 	public function __construct($config = array())
 	{
@@ -102,7 +104,7 @@
 		}
 		else
 		{
-			$this->_smtp_auth = ! ($this->smtp_user == '' && $this->smtp_pass == '');
+			$this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === '');
 			$this->_safe_mode = (bool) @ini_get('safe_mode');
 		}
 
@@ -137,7 +139,7 @@
 		}
 		$this->clear();
 
-		$this->_smtp_auth = ! ($this->smtp_user == '' && $this->smtp_pass == '');
+		$this->_smtp_auth = ! ($this->smtp_user === '' && $this->smtp_pass === '');
 		$this->_safe_mode = (bool) @ini_get('safe_mode');
 
 		return $this;
@@ -164,8 +166,8 @@
 		$this->_headers		= array();
 		$this->_debug_msg	= array();
 
-		$this->_set_header('User-Agent', $this->useragent);
-		$this->_set_header('Date', $this->_set_date());
+		$this->set_header('User-Agent', $this->useragent);
+		$this->set_header('Date', $this->_set_date());
 
 		if ($clear_attachments !== FALSE)
 		{
@@ -199,7 +201,7 @@
 		}
 
 		// prepare the display name
-		if ($name != '')
+		if ($name !== '')
 		{
 			// only use Q encoding if there are characters that would require it
 			if ( ! preg_match('/[\200-\377]/', $name))
@@ -213,8 +215,8 @@
 			}
 		}
 
-		$this->_set_header('From', $name.' <'.$from.'>');
-		$this->_set_header('Return-Path', '<'.$from.'>');
+		$this->set_header('From', $name.' <'.$from.'>');
+		$this->set_header('Return-Path', '<'.$from.'>');
 
 		return $this;
 	}
@@ -240,7 +242,7 @@
 			$this->validate_email($this->_str_to_array($replyto));
 		}
 
-		if ($name == '')
+		if ($name === '')
 		{
 			$name = $replyto;
 		}
@@ -250,7 +252,7 @@
 			$name = '"'.$name.'"';
 		}
 
-		$this->_set_header('Reply-To', $name.' <'.$replyto.'>');
+		$this->set_header('Reply-To', $name.' <'.$replyto.'>');
 		$this->_replyto_flag = TRUE;
 
 		return $this;
@@ -276,7 +278,7 @@
 
 		if ($this->_get_protocol() !== 'mail')
 		{
-			$this->_set_header('To', implode(', ', $to));
+			$this->set_header('To', implode(', ', $to));
 		}
 
 		switch ($this->_get_protocol())
@@ -303,15 +305,14 @@
 	 */
 	public function cc($cc)
 	{
-		$cc = $this->_str_to_array($cc);
-		$cc = $this->clean_email($cc);
+		$cc = $this->clean_email($this->_str_to_array($cc));
 
 		if ($this->validate)
 		{
 			$this->validate_email($cc);
 		}
 
-		$this->_set_header('Cc', implode(', ', $cc));
+		$this->set_header('Cc', implode(', ', $cc));
 
 		if ($this->_get_protocol() === 'smtp')
 		{
@@ -332,14 +333,13 @@
 	 */
 	public function bcc($bcc, $limit = '')
 	{
-		if ($limit != '' && is_numeric($limit))
+		if ($limit !== '' && is_numeric($limit))
 		{
 			$this->bcc_batch_mode = TRUE;
 			$this->bcc_batch_size = $limit;
 		}
 
-		$bcc = $this->_str_to_array($bcc);
-		$bcc = $this->clean_email($bcc);
+		$bcc = $this->clean_email($this->_str_to_array($bcc));
 
 		if ($this->validate)
 		{
@@ -352,7 +352,7 @@
 		}
 		else
 		{
-			$this->_set_header('Bcc', implode(', ', $bcc));
+			$this->set_header('Bcc', implode(', ', $bcc));
 		}
 
 		return $this;
@@ -369,7 +369,7 @@
 	public function subject($subject)
 	{
 		$subject = $this->_prep_q_encoding($subject);
-		$this->_set_header('Subject', $subject);
+		$this->set_header('Subject', $subject);
 		return $this;
 	}
 
@@ -407,11 +407,11 @@
 	 * @param	string
 	 * @return	object
 	 */
-	public function attach($filename, $disposition = '', $newname = NULL)
+	public function attach($filename, $disposition = '', $newname = NULL, $mime = '')
 	{
 		$this->_attach_name[] = array($filename, $newname);
-		$this->_attach_type[] = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION));
 		$this->_attach_disp[] = empty($disposition) ? 'attachment' : $disposition; // Can also be 'inline'  Not sure if it matters
+		$this->_attach_type[] = $mime;
 		return $this;
 	}
 
@@ -424,7 +424,7 @@
 	 * @param	string
 	 * @return	void
 	 */
-	protected function _set_header($header, $value)
+	public function set_header($header, $value)
 	{
 		$this->_headers[$header] = $value;
 	}
@@ -441,15 +441,11 @@
 	{
 		if ( ! is_array($email))
 		{
-			if (strpos($email, ',') !== FALSE)
-			{
-				$email = preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY);
-			}
-			else
-			{
-				$email = (array) trim($email);
-			}
+			return (strpos($email, ',') !== FALSE)
+				? preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY)
+				: (array) trim($email);
 		}
+
 		return $email;
 	}
 
@@ -477,7 +473,7 @@
 	 */
 	public function set_mailtype($type = 'text')
 	{
-		$this->mailtype = ($type == 'html') ? 'html' : 'text';
+		$this->mailtype = ($type === 'html') ? 'html' : 'text';
 		return $this;
 	}
 
@@ -574,7 +570,7 @@
 	protected function _get_message_id()
 	{
 		$from = str_replace(array('>', '<'), '', $this->_headers['Return-Path']);
-		return  '<'.uniqid('').strstr($from, '@').'>';
+		return '<'.uniqid('').strstr($from, '@').'>';
 	}
 
 	// --------------------------------------------------------------------
@@ -590,7 +586,7 @@
 		$this->protocol = strtolower($this->protocol);
 		in_array($this->protocol, $this->_protocols, TRUE) OR $this->protocol = 'mail';
 
-		if ($return == TRUE)
+		if ($return === TRUE)
 		{
 			return $this->protocol;
 		}
@@ -616,7 +612,7 @@
 			}
 		}
 
-		if ($return == TRUE)
+		if ($return === TRUE)
 		{
 			return $this->_encoding;
 		}
@@ -631,13 +627,9 @@
 	 */
 	protected function _get_content_type()
 	{
-		if ($this->mailtype === 'html' && count($this->_attach_name) === 0)
+		if ($this->mailtype === 'html')
 		{
-			return 'html';
-		}
-		elseif	($this->mailtype === 'html' && count($this->_attach_name) > 0)
-		{
-			return 'html-attach';
+			return (count($this->_attach_name) === 0) ? 'html' : 'html-attach';
 		}
 		elseif	($this->mailtype === 'text' && count($this->_attach_name) > 0)
 		{
@@ -731,7 +723,7 @@
 	{
 		if ( ! is_array($email))
 		{
-			return (preg_match('/\<(.*)\>/', $email, $match)) ? $match[1] : $email;
+			return preg_match('/\<(.*)\>/', $email, $match) ? $match[1] : $email;
 		}
 
 		$clean_email = array();
@@ -758,12 +750,12 @@
 	 */
 	protected function _get_alt_message()
 	{
-		if ($this->alt_message != '')
+		if ($this->alt_message !== '')
 		{
 			return $this->word_wrap($this->alt_message, '76');
 		}
 
-		$body = (preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match)) ? $match[1] : $this->_body;
+		$body = preg_match('/\<body.*?\>(.*)\<\/body\>/si', $this->_body, $match) ? $match[1] : $this->_body;
 		$body = str_replace("\t", '', preg_replace('#<!--(.*)--\>#', '', trim(strip_tags($body))));
 
 		for ($i = 20; $i >= 3; $i--)
@@ -786,13 +778,13 @@
 	public function word_wrap($str, $charlim = '')
 	{
 		// Se the character limit
-		if ($charlim == '')
+		if ($charlim === '')
 		{
-			$charlim = ($this->wrapchars == "") ? 76 : $this->wrapchars;
+			$charlim = ($this->wrapchars === '') ? 76 : $this->wrapchars;
 		}
 
 		// Reduce multiple spaces
-		$str = preg_replace("| +|", " ", $str);
+		$str = preg_replace('| +|', ' ', $str);
 
 		// Standardize newlines
 		if (strpos($str, "\r") !== FALSE)
@@ -803,22 +795,22 @@
 		// If the current word is surrounded by {unwrap} tags we'll
 		// strip the entire chunk and replace it with a marker.
 		$unwrap = array();
-		if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
+		if (preg_match_all('|(\{unwrap\}.+?\{/unwrap\})|s', $str, $matches))
 		{
 			for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
 			{
 				$unwrap[] = $matches[1][$i];
-				$str = str_replace($matches[1][$i], "{{unwrapped".$i."}}", $str);
+				$str = str_replace($matches[1][$i], '{{unwrapped'.$i.'}}', $str);
 			}
 		}
 
 		// 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.
+		// too long get left alone. In the next step we'll deal with them.
 		$str = wordwrap($str, $charlim, "\n", FALSE);
 
 		// Split the string into individual lines of text and cycle through them
-		$output = "";
+		$output = '';
 		foreach (explode("\n", $str) as $line)
 		{
 			// Is the line within the allowed character count?
@@ -833,7 +825,7 @@
 			do
 			{
 				// If the over-length word is a URL we won't wrap it
-				if (preg_match("!\[url.+\]|://|wwww.!", $line))
+				if (preg_match('!\[url.+\]|://|wwww.!', $line))
 				{
 					break;
 				}
@@ -846,7 +838,7 @@
 
 			// If $temp contains data it means we had to split up an over-length
 			// word into smaller chunks so we'll add it back to our current line
-			if ($temp != '')
+			if ($temp !== '')
 			{
 				$output .= $temp.$this->newline;
 			}
@@ -859,7 +851,7 @@
 		{
 			foreach ($unwrap as $key => $val)
 			{
-				$output = str_replace("{{unwrapped".$key."}}", $val, $output);
+				$output = str_replace('{{unwrapped'.$key.'}}', $val, $output);
 			}
 		}
 
@@ -875,11 +867,11 @@
 	 */
 	protected function _build_headers()
 	{
-		$this->_set_header('X-Sender', $this->clean_email($this->_headers['From']));
-		$this->_set_header('X-Mailer', $this->useragent);
-		$this->_set_header('X-Priority', $this->_priorities[$this->priority - 1]);
-		$this->_set_header('Message-ID', $this->_get_message_id());
-		$this->_set_header('Mime-Version', '1.0');
+		$this->set_header('X-Sender', $this->clean_email($this->_headers['From']));
+		$this->set_header('X-Mailer', $this->useragent);
+		$this->set_header('X-Priority', $this->_priorities[$this->priority - 1]);
+		$this->set_header('Message-ID', $this->_get_message_id());
+		$this->set_header('Mime-Version', '1.0');
 	}
 
 	// --------------------------------------------------------------------
@@ -898,15 +890,15 @@
 		}
 
 		reset($this->_headers);
-		$this->_header_str = "";
+		$this->_header_str = '';
 
 		foreach ($this->_headers as $key => $val)
 		{
 			$val = trim($val);
 
-			if ($val != "")
+			if ($val !== '')
 			{
-				$this->_header_str .= $key.": ".$val.$this->newline;
+				$this->_header_str .= $key.': '.$val.$this->newline;
 			}
 		}
 
@@ -940,8 +932,8 @@
 		{
 			case 'plain' :
 
-				$hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline
-					. "Content-Transfer-Encoding: " . $this->_get_encoding();
+				$hdr .= 'Content-Type: text/plain; charset='.$this->charset.$this->newline
+					.'Content-Transfer-Encoding: '.$this->_get_encoding();
 
 				if ($this->_get_protocol() === 'mail')
 				{
@@ -959,25 +951,25 @@
 
 				if ($this->send_multipart === FALSE)
 				{
-					$hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline
-						. "Content-Transfer-Encoding: quoted-printable";
+					$hdr .= 'Content-Type: text/html; charset='.$this->charset.$this->newline
+						.'Content-Transfer-Encoding: quoted-printable';
 				}
 				else
 				{
-					$hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline . $this->newline;
+					$hdr .= 'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'.$this->newline.$this->newline;
 
-					$body .= $this->_get_mime_message() . $this->newline . $this->newline
-						. "--" . $this->_alt_boundary . $this->newline
+					$body .= $this->_get_mime_message().$this->newline.$this->newline
+						.'--'.$this->_alt_boundary.$this->newline
 
-						. "Content-Type: text/plain; charset=" . $this->charset . $this->newline
-						. "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline
-						. $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline
+						.'Content-Type: text/plain; charset='.$this->charset.$this->newline
+						.'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline
+						.$this->_get_alt_message().$this->newline.$this->newline.'--'.$this->_alt_boundary.$this->newline
 
-						. "Content-Type: text/html; charset=" . $this->charset . $this->newline
-						. "Content-Transfer-Encoding: quoted-printable" . $this->newline . $this->newline;
+						.'Content-Type: text/html; charset='.$this->charset.$this->newline
+						.'Content-Transfer-Encoding: quoted-printable'.$this->newline.$this->newline;
 				}
 
-				$this->_finalbody = $body . $this->_prep_quoted_printable($this->_body) . $this->newline . $this->newline;
+				$this->_finalbody = $body.$this->_prep_quoted_printable($this->_body).$this->newline.$this->newline;
 
 
 				if ($this->_get_protocol() === 'mail')
@@ -986,59 +978,59 @@
 				}
 				else
 				{
-					$this->_finalbody = $hdr . $this->_finalbody;
+					$this->_finalbody = $hdr.$this->_finalbody;
 				}
 
 
 				if ($this->send_multipart !== FALSE)
 				{
-					$this->_finalbody .= "--" . $this->_alt_boundary . "--";
+					$this->_finalbody .= '--'.$this->_alt_boundary.'--';
 				}
 
 				return;
 
 			case 'plain-attach' :
 
-				$hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline . $this->newline;
+				$hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'.$this->newline.$this->newline;
 
 				if ($this->_get_protocol() === 'mail')
 				{
 					$this->_header_str .= $hdr;
 				}
 
-				$body .= $this->_get_mime_message() . $this->newline . $this->newline
-					. "--" . $this->_atc_boundary . $this->newline
+				$body .= $this->_get_mime_message().$this->newline.$this->newline
+					.'--'.$this->_atc_boundary.$this->newline
 
-					. "Content-Type: text/plain; charset=" . $this->charset . $this->newline
-					. "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline
+					.'Content-Type: text/plain; charset='.$this->charset.$this->newline
+					.'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline
 
-					. $this->_body . $this->newline . $this->newline;
+					.$this->_body.$this->newline.$this->newline;
 
 			break;
 			case 'html-attach' :
 
-				$hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline . $this->newline;
+				$hdr .= 'Content-Type: multipart/'.$this->multipart.'; boundary="'.$this->_atc_boundary.'"'.$this->newline.$this->newline;
 
 				if ($this->_get_protocol() === 'mail')
 				{
 					$this->_header_str .= $hdr;
 				}
 
-				$body .= $this->_get_mime_message() . $this->newline . $this->newline
-					. "--" . $this->_atc_boundary . $this->newline
+				$body .= $this->_get_mime_message().$this->newline.$this->newline
+					.'--'.$this->_atc_boundary.$this->newline
 
-					. "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline
-					. "--" . $this->_alt_boundary . $this->newline
+					.'Content-Type: multipart/alternative; boundary="'.$this->_alt_boundary.'"'.$this->newline.$this->newline
+					.'--'.$this->_alt_boundary.$this->newline
 
-					. "Content-Type: text/plain; charset=" . $this->charset . $this->newline
-					. "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline
-					. $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline
+					.'Content-Type: text/plain; charset='.$this->charset.$this->newline
+					.'Content-Transfer-Encoding: '.$this->_get_encoding().$this->newline.$this->newline
+					.$this->_get_alt_message().$this->newline.$this->newline.'--'.$this->_alt_boundary.$this->newline
 
-					. "Content-Type: text/html; charset=" . $this->charset . $this->newline
-					. "Content-Transfer-Encoding: quoted-printable" . $this->newline . $this->newline
+					.'Content-Type: text/html; charset='.$this->charset.$this->newline
+					.'Content-Transfer-Encoding: quoted-printable'.$this->newline.$this->newline
 
-					. $this->_prep_quoted_printable($this->_body) . $this->newline . $this->newline
-					. "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline;
+					.$this->_prep_quoted_printable($this->_body).$this->newline.$this->newline
+					.'--'.$this->_alt_boundary.'--'.$this->newline.$this->newline;
 
 			break;
 		}
@@ -1047,35 +1039,46 @@
 		for ($i = 0, $c = count($this->_attach_name), $z = 0; $i < $c; $i++)
 		{
 			$filename = $this->_attach_name[$i][0];
-			$basename = (is_null($this->_attach_name[$i][1])) ? basename($filename) : $this->_attach_name[$i][1];
+			$basename = is_null($this->_attach_name[$i][1]) ? basename($filename) : $this->_attach_name[$i][1];
 			$ctype = $this->_attach_type[$i];
+			$file_content = '';
 
-			if ( ! file_exists($filename))
+			if ($this->_attach_type[$i] === '')
 			{
-				$this->_set_error_message('lang:email_attachment_missing', $filename);
-				return FALSE;
+				if ( ! file_exists($filename))
+				{
+					$this->_set_error_message('lang:email_attachment_missing', $filename);
+					return FALSE;
+				}
+
+				$file = filesize($filename) +1;
+
+				if ( ! $fp = fopen($filename, FOPEN_READ))
+				{
+					$this->_set_error_message('lang:email_attachment_unreadable', $filename);
+					return FALSE;
+				}
+
+				$ctype = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION));
+				$file_content = fread($fp, $file);
+				fclose($fp);
+			}
+			else
+			{
+				$file_content =& $this->_attach_content[$i];
 			}
 
-			$attachment[$z++] = "--".$this->_atc_boundary.$this->newline
-				. "Content-type: ".$ctype."; "
-				. "name=\"".$basename."\"".$this->newline
-				. "Content-Disposition: ".$this->_attach_disp[$i].";".$this->newline
-				. "Content-Transfer-Encoding: base64".$this->newline;
+			$attachment[$z++] = '--'.$this->_atc_boundary.$this->newline
+				.'Content-type: '.$ctype.'; '
+				.'name="'.$basename.'"'.$this->newline
+				.'Content-Disposition: '.$this->_attach_disp[$i].';'.$this->newline
+				.'Content-Transfer-Encoding: base64'.$this->newline;
 
-			$file = filesize($filename) +1;
-
-			if ( ! $fp = fopen($filename, FOPEN_READ))
-			{
-				$this->_set_error_message('lang:email_attachment_unreadable', $filename);
-				return FALSE;
-			}
-
-			$attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));
-			fclose($fp);
+			$attachment[$z++] = chunk_split(base64_encode($file_content));
 		}
 
-		$body .= implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--";
-		$this->_finalbody = ($this->_get_protocol() === 'mail') ? $body : $hdr . $body;
+		$body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--';
+		$this->_finalbody = ($this->_get_protocol() === 'mail') ? $body : $hdr.$body;
 		return;
 	}
 
@@ -1096,13 +1099,13 @@
 		// Set the character limit
 		// Don't allow over 76, as that will make servers and MUAs barf
 		// all over quoted-printable data
-		if ($charlim == '' OR $charlim > 76)
+		if ($charlim === '' OR $charlim > 76)
 		{
 			$charlim = 76;
 		}
 
 		// Reduce multiple spaces & remove nulls
-		$str = preg_replace(array("| +|", '/\x00+/'), array(' ', ''), $str);
+		$str = preg_replace(array('| +|', '/\x00+/'), array(' ', ''), $str);
 
 		// Standardize newlines
 		if (strpos($str, "\r") !== FALSE)
@@ -1223,11 +1226,9 @@
 			$temp .= $char;
 		}
 
-		$str = $output.$temp;
-
 		// wrap each line with the shebang, charset, and transfer encoding
 		// the preceding space on successive lines is required for header "folding"
-		return trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $str));
+		return trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $output.$temp));
 	}
 
 	// --------------------------------------------------------------------
@@ -1239,7 +1240,7 @@
 	 */
 	public function send()
 	{
-		if ($this->_replyto_flag == FALSE)
+		if ($this->_replyto_flag === FALSE)
 		{
 			$this->reply_to($this->_headers['From']);
 		}
@@ -1283,7 +1284,7 @@
 				$set .= ', '.$this->_bcc_array[$i];
 			}
 
-			if ($i == $float)
+			if ($i === $float)
 			{
 				$chunk[] = substr($set, 1);
 				$float += $this->bcc_batch_size;
@@ -1304,7 +1305,7 @@
 
 			if ($this->protocol !== 'smtp')
 			{
-				$this->_set_header('Bcc', implode(', ', $bcc));
+				$this->set_header('Bcc', implode(', ', $bcc));
 			}
 			else
 			{
@@ -1325,7 +1326,7 @@
 	 */
 	protected function _unwrap_specials()
 	{
-		$this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody);
+		$this->_finalbody = preg_replace_callback('/\{unwrap\}(.*?)\{\/unwrap\}/si', array($this, '_remove_nl_callback'), $this->_finalbody);
 	}
 
 	// --------------------------------------------------------------------
@@ -1356,10 +1357,10 @@
 	{
 		$this->_unwrap_specials();
 
-		$method = '_send_with_' . $this->_get_protocol();
+		$method = '_send_with_'.$this->_get_protocol();
 		if ( ! $this->$method())
 		{
-			$this->_set_error_message('lang:email_send_failure_' . ($this->_get_protocol() === 'mail' ? 'phpmail' : $this->_get_protocol()));
+			$this->_set_error_message('lang:email_send_failure_'.($this->_get_protocol() === 'mail' ? 'phpmail' : $this->_get_protocol()));
 			return FALSE;
 		}
 
@@ -1376,7 +1377,7 @@
 	 */
 	protected function _send_with_mail()
 	{
-		if ($this->_safe_mode == TRUE)
+		if ($this->_safe_mode === TRUE)
 		{
 			return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str);
 		}
@@ -1384,7 +1385,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.
-			return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From']));
+			return mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, '-f '.$this->clean_email($this->_headers['From']));
 		}
 	}
 
@@ -1397,7 +1398,7 @@
 	 */
 	protected function _send_with_sendmail()
 	{
-		$fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w');
+		$fp = @popen($this->mailpath.' -oi -f '.$this->clean_email($this->_headers['From']).' -t', 'w');
 
 		if ($fp === FALSE OR $fp === NULL)
 		{
@@ -1429,7 +1430,7 @@
 	 */
 	protected function _send_with_smtp()
 	{
-		if ($this->smtp_host == '')
+		if ($this->smtp_host === '')
 		{
 			$this->_set_error_message('lang:email_no_hostname');
 			return FALSE;
@@ -1451,7 +1452,7 @@
 		{
 			foreach ($this->_cc_array as $val)
 			{
-				if ($val != "")
+				if ($val !== '')
 				{
 					$this->_send_command('to', $val);
 				}
@@ -1462,7 +1463,7 @@
 		{
 			foreach ($this->_bcc_array as $val)
 			{
-				if ($val != "")
+				if ($val !== '')
 				{
 					$this->_send_command('to', $val);
 				}
@@ -1472,7 +1473,7 @@
 		$this->_send_command('data');
 
 		// perform dot transformation on any lines that begin with a dot
-		$this->_send_data($this->_header_str . preg_replace('/^\./m', '..$1', $this->_finalbody));
+		$this->_send_data($this->_header_str.preg_replace('/^\./m', '..$1', $this->_finalbody));
 
 		$this->_send_data('.');
 
@@ -1500,23 +1501,23 @@
 	 */
 	protected function _smtp_connect()
 	{
-		$ssl = ($this->smtp_crypto == 'ssl') ? 'ssl://' : NULL;
+		$ssl = ($this->smtp_crypto === 'ssl') ? 'ssl://' : NULL;
 
 		$this->_smtp_connect = fsockopen($ssl.$this->smtp_host,
-										$this->smtp_port,
-										$errno,
-										$errstr,
-										$this->smtp_timeout);
+							$this->smtp_port,
+							$errno,
+							$errstr,
+							$this->smtp_timeout);
 
 		if ( ! is_resource($this->_smtp_connect))
 		{
-			$this->_set_error_message('lang:email_smtp_error', $errno." ".$errstr);
+			$this->_set_error_message('lang:email_smtp_error', $errno.' '.$errstr);
 			return FALSE;
 		}
 
 		$this->_set_error_message($this->_get_smtp_data());
 
-		if ($this->smtp_crypto == 'tls')
+		if ($this->smtp_crypto === 'tls')
 		{
 			$this->_send_command('hello');
 			$this->_send_command('starttls');
@@ -1548,27 +1549,29 @@
 		{
 			case 'hello' :
 
-					if ($this->_smtp_auth OR $this->_get_encoding() == '8bit')
-						$this->_send_data('EHLO '.$this->_get_hostname());
-					else
-						$this->_send_data('HELO '.$this->_get_hostname());
+						if ($this->_smtp_auth OR $this->_get_encoding() === '8bit')
+						{
+							$this->_send_data('EHLO '.$this->_get_hostname());
+						}
+						else
+						{
+							$this->_send_data('HELO '.$this->_get_hostname());
+						}
 
 						$resp = 250;
 			break;
 			case 'starttls'	:
 
 						$this->_send_data('STARTTLS');
-
 						$resp = 220;
 			break;
 			case 'from' :
 
 						$this->_send_data('MAIL FROM:<'.$data.'>');
-
 						$resp = 250;
 			break;
-			case 'to'	:
-						
+			case 'to' :
+
 						if ($this->dsn)
 						{
 							$this->_send_data('RCPT TO:<'.$data.'> NOTIFY=SUCCESS,DELAY,FAILURE ORCPT=rfc822;'.$data);
@@ -1577,33 +1580,32 @@
 						{
 							$this->_send_data('RCPT TO:<'.$data.'>');
 						}
+
 						$resp = 250;
 			break;
 			case 'data'	:
 
 						$this->_send_data('DATA');
-
 						$resp = 354;
 			break;
 			case 'quit'	:
 
 						$this->_send_data('QUIT');
-
 						$resp = 221;
 			break;
 		}
 
 		$reply = $this->_get_smtp_data();
 
-		$this->_debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";
+		$this->_debug_msg[] = '<pre>'.$cmd.': '.$reply.'</pre>';
 
-		if (substr($reply, 0, 3) != $resp)
+		if (substr($reply, 0, 3) !== $resp)
 		{
 			$this->_set_error_message('lang:email_smtp_error', $reply);
 			return FALSE;
 		}
 
-		if ($cmd == 'quit')
+		if ($cmd === 'quit')
 		{
 			fclose($this->_smtp_connect);
 		}
@@ -1625,7 +1627,7 @@
 			return TRUE;
 		}
 
-		if ($this->smtp_user == '' && $this->smtp_pass == '')
+		if ($this->smtp_user === '' && $this->smtp_pass === '')
 		{
 			$this->_set_error_message('lang:email_no_smtp_unpw');
 			return FALSE;
@@ -1691,13 +1693,13 @@
 	 */
 	protected function _get_smtp_data()
 	{
-		$data = "";
+		$data = '';
 
 		while ($str = fgets($this->_smtp_connect, 512))
 		{
 			$data .= $str;
 
-			if ($str[3] == " ")
+			if ($str[3] === ' ')
 			{
 				break;
 			}
@@ -1796,11 +1798,11 @@
 
 		if (substr($msg, 0, 5) !== 'lang:' OR FALSE === ($line = $CI->lang->line(substr($msg, 5))))
 		{
-			$this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
+			$this->_debug_msg[] = str_replace('%s', $val, $msg).'<br />';
 		}
 		else
 		{
-			$this->_debug_msg[] = str_replace('%s', $val, $line)."<br />";
+			$this->_debug_msg[] = str_replace('%s', $val, $line).'<br />';
 		}
 	}
 
@@ -1814,100 +1816,26 @@
 	 */
 	protected function _mime_types($ext = '')
 	{
-		$mimes = array(
-						'hqx'	=>	'application/mac-binhex40',
-						'cpt'	=>	'application/mac-compactpro',
-						'doc'	=>	'application/msword',
-						'bin'	=>	'application/macbinary',
-						'dms'	=>	'application/octet-stream',
-						'lha'	=>	'application/octet-stream',
-						'lzh'	=>	'application/octet-stream',
-						'exe'	=>	'application/octet-stream',
-						'class'	=>	'application/octet-stream',
-						'psd'	=>	'application/octet-stream',
-						'so'	=>	'application/octet-stream',
-						'sea'	=>	'application/octet-stream',
-						'dll'	=>	'application/octet-stream',
-						'oda'	=>	'application/oda',
-						'pdf'	=>	'application/pdf',
-						'ai'	=>	'application/postscript',
-						'eps'	=>	'application/postscript',
-						'ps'	=>	'application/postscript',
-						'smi'	=>	'application/smil',
-						'smil'	=>	'application/smil',
-						'mif'	=>	'application/vnd.mif',
-						'xls'	=>	'application/vnd.ms-excel',
-						'ppt'	=>	'application/vnd.ms-powerpoint',
-						'wbxml'	=>	'application/vnd.wap.wbxml',
-						'wmlc'	=>	'application/vnd.wap.wmlc',
-						'dcr'	=>	'application/x-director',
-						'dir'	=>	'application/x-director',
-						'dxr'	=>	'application/x-director',
-						'dvi'	=>	'application/x-dvi',
-						'gtar'	=>	'application/x-gtar',
-						'php'	=>	'application/x-httpd-php',
-						'php4'	=>	'application/x-httpd-php',
-						'php3'	=>	'application/x-httpd-php',
-						'phtml'	=>	'application/x-httpd-php',
-						'phps'	=>	'application/x-httpd-php-source',
-						'js'	=>	'application/x-javascript',
-						'swf'	=>	'application/x-shockwave-flash',
-						'sit'	=>	'application/x-stuffit',
-						'tar'	=>	'application/x-tar',
-						'tgz'	=>	'application/x-tar',
-						'xhtml'	=>	'application/xhtml+xml',
-						'xht'	=>	'application/xhtml+xml',
-						'zip'	=>	'application/zip',
-						'mid'	=>	'audio/midi',
-						'midi'	=>	'audio/midi',
-						'mpga'	=>	'audio/mpeg',
-						'mp2'	=>	'audio/mpeg',
-						'mp3'	=>	'audio/mpeg',
-						'aif'	=>	'audio/x-aiff',
-						'aiff'	=>	'audio/x-aiff',
-						'aifc'	=>	'audio/x-aiff',
-						'ram'	=>	'audio/x-pn-realaudio',
-						'rm'	=>	'audio/x-pn-realaudio',
-						'rpm'	=>	'audio/x-pn-realaudio-plugin',
-						'ra'	=>	'audio/x-realaudio',
-						'rv'	=>	'video/vnd.rn-realvideo',
-						'wav'	=>	'audio/x-wav',
-						'bmp'	=>	'image/bmp',
-						'gif'	=>	'image/gif',
-						'jpeg'	=>	'image/jpeg',
-						'jpg'	=>	'image/jpeg',
-						'jpe'	=>	'image/jpeg',
-						'png'	=>	'image/png',
-						'tiff'	=>	'image/tiff',
-						'tif'	=>	'image/tiff',
-						'css'	=>	'text/css',
-						'html'	=>	'text/html',
-						'htm'	=>	'text/html',
-						'shtml'	=>	'text/html',
-						'txt'	=>	'text/plain',
-						'text'	=>	'text/plain',
-						'log'	=>	'text/plain',
-						'rtx'	=>	'text/richtext',
-						'rtf'	=>	'text/rtf',
-						'xml'	=>	'text/xml',
-						'xsl'	=>	'text/xml',
-						'mpeg'	=>	'video/mpeg',
-						'mpg'	=>	'video/mpeg',
-						'mpe'	=>	'video/mpeg',
-						'qt'	=>	'video/quicktime',
-						'mov'	=>	'video/quicktime',
-						'avi'	=>	'video/x-msvideo',
-						'movie'	=>	'video/x-sgi-movie',
-						'doc'	=>	'application/msword',
-						'word'	=>	'application/msword',
-						'xl'	=>	'application/excel',
-						'eml'	=>	'message/rfc822'
-					);
+		static $mimes;
 
-		return isset($mimes[strtolower($ext)]) ? $mimes[strtolower($ext)] : 'application/x-unknown-content-type';
+		$ext = strtolower($ext);
+
+		if ( ! is_array($mimes))
+		{
+			$mimes =& get_mimes();
+		}
+
+		if (isset($mimes[$ext]))
+		{
+			return is_array($mimes[$ext])
+				? current($mimes[$ext])
+				: $mimes[$ext];
+		}
+
+		return 'application/x-unknown-content-type';
 	}
 
 }
 
 /* End of file Email.php */
-/* Location: ./system/libraries/Email.php */
+/* Location: ./system/libraries/Email.php */
\ No newline at end of file
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index b29eb47..ce5e030 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -38,15 +38,49 @@
  */
 class CI_Encrypt {
 
-	public $encryption_key	= '';
-	protected $_hash_type	= 'sha1';
-	protected $_mcrypt_exists = FALSE;
+	/**
+	 * Reference to the user's encryption key
+	 *
+	 * @var string
+	 */
+	public $encryption_key		= '';
+
+	/**
+	 * Type of hash operation
+	 *
+	 * @var string
+	 */
+	protected $_hash_type		= 'sha1';
+
+	/**
+	 * Flag for the existance of mcrypt
+	 *
+	 * @var bool
+	 */
+	protected $_mcrypt_exists	= FALSE;
+
+	/**
+	 * Current cipher to be used with mcrypt
+	 *
+	 * @var string
+	 */
 	protected $_mcrypt_cipher;
+
+	/**
+	 * Method for encrypting/decrypting data
+	 *
+	 * @var int
+	 */
 	protected $_mcrypt_mode;
 
+	/**
+	 * Initialize Encryption class
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
-		$this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;
+		$this->_mcrypt_exists = function_exists('mcrypt_encrypt');
 		log_message('debug', 'Encrypt Class Initialized');
 	}
 
@@ -63,15 +97,14 @@
 	 */
 	public function get_key($key = '')
 	{
-		if ($key == '')
+		if ($key === '')
 		{
-			if ($this->encryption_key != '')
+			if ($this->encryption_key !== '')
 			{
 				return $this->encryption_key;
 			}
 
-			$CI =& get_instance();
-			$key = $CI->config->item('encryption_key');
+			$key = config_item('encryption_key');
 
 			if ($key === FALSE)
 			{
@@ -349,8 +382,9 @@
 	 *
 	 * Function description
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	string	$data
+	 * @param	string	$key
+	 * @return	string
 	 */
 	protected function _remove_cipher_noise($data, $key)
 	{
@@ -382,8 +416,8 @@
 	/**
 	 * Set the Mcrypt Cipher
 	 *
-	 * @param	constant
-	 * @return	string
+	 * @param	int
+	 * @return	object
 	 */
 	public function set_cipher($cipher)
 	{
@@ -396,8 +430,8 @@
 	/**
 	 * Set the Mcrypt Mode
 	 *
-	 * @param	constant
-	 * @return	string
+	 * @param	int
+	 * @return	object
 	 */
 	public function set_mode($mode)
 	{
@@ -410,11 +444,11 @@
 	/**
 	 * Get Mcrypt cipher Value
 	 *
-	 * @return	string
+	 * @return	int
 	 */
 	protected function _get_cipher()
 	{
-		if ($this->_mcrypt_cipher == '')
+		if ($this->_mcrypt_cipher === NULL)
 		{
 			return $this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;
 		}
@@ -427,11 +461,11 @@
 	/**
 	 * Get Mcrypt Mode Value
 	 *
-	 * @return	string
+	 * @return	int
 	 */
 	protected function _get_mode()
 	{
-		if ($this->_mcrypt_mode == '')
+		if ($this->_mcrypt_mode === NULL)
 		{
 			return $this->_mcrypt_mode = MCRYPT_MODE_CBC;
 		}
@@ -464,7 +498,8 @@
 	{
 		return ($this->_hash_type === 'sha1') ? sha1($str) : md5($str);
 	}
+
 }
 
 /* End of file Encrypt.php */
-/* Location: ./system/libraries/Encrypt.php */
+/* Location: ./system/libraries/Encrypt.php */
\ No newline at end of file
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 3e0c72e..225325d 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Form Validation Class
  *
@@ -38,17 +36,82 @@
  */
 class CI_Form_validation {
 
+	/**
+	 * Reference to the CodeIgniter instance
+	 *
+	 * @var object
+	 */
 	protected $CI;
-	protected $_field_data			= array();
-	protected $_config_rules		= array();
-	protected $_error_array			= array();
-	protected $_error_messages		= array();
-	protected $_error_prefix		= '<p>';
-	protected $_error_suffix		= '</p>';
-	protected $error_string			= '';
-	protected $_safe_form_data		= FALSE;
-	protected $validation_data		= array();
 
+	/**
+	 * Validation data for the current form submission
+	 *
+	 * @var array
+	 */
+	protected $_field_data		= array();
+
+	/**
+	 * Validation rules for the current form
+	 *
+	 * @var array
+	 */
+	protected $_config_rules	= array();
+
+	/**
+	 * Array of validation errors
+	 *
+	 * @var array
+	 */
+	protected $_error_array		= array();
+
+	/**
+	 * Array of custom error messages
+	 *
+	 * @var array
+	 */
+	protected $_error_messages	= array();
+
+	/**
+	 * Start tag for error wrapping
+	 *
+	 * @var string
+	 */
+	protected $_error_prefix	= '<p>';
+
+	/**
+	 * End tag for error wrapping
+	 *
+	 * @var string
+	 */
+	protected $_error_suffix	= '</p>';
+
+	/**
+	 * Custom error message
+	 *
+	 * @var string
+	 */
+	protected $error_string		= '';
+
+	/**
+	 * Whether the form data has been validated as safe
+	 *
+	 * @var bool
+	 */
+	protected $_safe_form_data	= FALSE;
+
+	/**
+	 * Custom data to validate
+	 *
+	 * @var array
+	 */
+	protected $validation_data	= array();
+
+	/**
+	 * Initialize Form_Validation class
+	 *
+	 * @param	array	$rules
+	 * @return	void
+	 */
 	public function __construct($rules = array())
 	{
 		$this->CI =& get_instance();
@@ -64,7 +127,7 @@
 			$this->_error_suffix = $rules['error_suffix'];
 			unset($rules['error_suffix']);
 		}
-		
+
 		// Validation rules can be stored in a config file.
 		$this->_config_rules = $rules;
 
@@ -88,9 +151,10 @@
 	 * This function takes an array of field names and validation
 	 * rules as input, validates the info, and stores it
 	 *
-	 * @param	mixed
-	 * @param	string
-	 * @return	void
+	 * @param	mixed	$field
+	 * @param	string	$label
+	 * @param	mixed	$rules
+	 * @return	object
 	 */
 	public function set_rules($field, $label = '', $rules = '')
 	{
@@ -108,28 +172,29 @@
 			foreach ($field as $row)
 			{
 				// Houston, we have a problem...
-				if ( ! isset($row['field']) OR ! isset($row['rules']))
+				if ( ! isset($row['field'], $row['rules']))
 				{
 					continue;
 				}
 
 				// If the field label wasn't passed we use the field name
-				$label = ( ! isset($row['label'])) ? $row['field'] : $row['label'];
+				$label = isset($row['label']) ? $row['label'] : $row['field'];
 
 				// Here we go!
 				$this->set_rules($row['field'], $label, $row['rules']);
 			}
+
 			return $this;
 		}
 
 		// No fields? Nothing to do...
-		if ( ! is_string($field) OR ! is_string($rules) OR $field == '')
+		if ( ! is_string($field) OR ! is_string($rules) OR $field === '')
 		{
 			return $this;
 		}
 
 		// If the field label wasn't passed we use the field name
-		$label = ($label == '') ? $field : $label;
+		$label = ($label === '') ? $field : $label;
 
 		// Is the field name an array? If it is an array, we break it apart
 		// into its components so that we can fetch the corresponding POST data later
@@ -142,7 +207,7 @@
 
 			for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
 			{
-				if ($matches[1][$i] != '')
+				if ($matches[1][$i] !== '')
 				{
 					$indexes[] = $matches[1][$i];
 				}
@@ -158,13 +223,13 @@
 
 		// 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;
@@ -198,12 +263,12 @@
 	/**
 	 * Set Error Message
 	 *
-	 * Lets users set their own error messages on the fly.  Note:  The key
-	 * name has to match the function name that it corresponds to.
+	 * Lets users set their own error messages on the fly. Note:
+	 * The key name has to match the function name that it corresponds to.
 	 *
+	 * @param	array
 	 * @param	string
-	 * @param	string
-	 * @return	string
+	 * @return	object
 	 */
 	public function set_message($lang, $val = '')
 	{
@@ -213,7 +278,6 @@
 		}
 
 		$this->_error_messages = array_merge($this->_error_messages, $lang);
-
 		return $this;
 	}
 
@@ -226,13 +290,12 @@
 	 *
 	 * @param	string
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_error_delimiters($prefix = '<p>', $suffix = '</p>')
 	{
 		$this->_error_prefix = $prefix;
 		$this->_error_suffix = $suffix;
-
 		return $this;
 	}
 
@@ -244,21 +307,23 @@
 	 * Gets the error message associated with a particular field
 	 *
 	 * @param	string	the field name
-	 * @return	void
+	 * @param	string	the html start tag
+	 * @param 	strign	the html end tag
+	 * @return	string
 	 */
 	public function error($field = '', $prefix = '', $suffix = '')
 	{
-		if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '')
+		if (empty($this->_field_data[$field]['error']))
 		{
 			return '';
 		}
 
-		if ($prefix == '')
+		if ($prefix === '')
 		{
 			$prefix = $this->_error_prefix;
 		}
 
-		if ($suffix == '')
+		if ($suffix === '')
 		{
 			$suffix = $this->_error_suffix;
 		}
@@ -289,7 +354,7 @@
 	 *
 	 * @param	string
 	 * @param	string
-	 * @return	str
+	 * @return	string
 	 */
 	public function error_string($prefix = '', $suffix = '')
 	{
@@ -299,12 +364,12 @@
 			return '';
 		}
 
-		if ($prefix == '')
+		if ($prefix === '')
 		{
 			$prefix = $this->_error_prefix;
 		}
 
-		if ($suffix == '')
+		if ($suffix === '')
 		{
 			$suffix = $this->_error_suffix;
 		}
@@ -313,7 +378,7 @@
 		$str = '';
 		foreach ($this->_error_array as $val)
 		{
-			if ($val != '')
+			if ($val !== '')
 			{
 				$str .= $prefix.$val.$suffix."\n";
 			}
@@ -329,12 +394,13 @@
 	 *
 	 * This function does all the work.
 	 *
+	 * @param	string	$group
 	 * @return	bool
 	 */
 	public function run($group = '')
 	{
 		// Do we even have any data to process?  Mm?
-		$validation_array = ( ! empty($this->validation_data)) ? $this->validation_data : $_POST;
+		$validation_array = empty($this->validation_data) ? $_POST : $this->validation_data;
 		if (count($validation_array) === 0)
 		{
 			return FALSE;
@@ -351,9 +417,9 @@
 			}
 
 			// Is there a validation rule for the particular URI being accessed?
-			$uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
+			$uri = ($group === '') ? trim($this->CI->uri->ruri_string(), '/') : $group;
 
-			if ($uri != '' AND isset($this->_config_rules[$uri]))
+			if ($uri !== '' && isset($this->_config_rules[$uri]))
 			{
 				$this->set_rules($this->_config_rules[$uri]);
 			}
@@ -362,10 +428,10 @@
 				$this->set_rules($this->_config_rules);
 			}
 
-			// We're we able to set the rules correctly?
+			// Were we able to set the rules correctly?
 			if (count($this->_field_data) === 0)
 			{
-				log_message('debug', "Unable to find validation rules");
+				log_message('debug', 'Unable to find validation rules');
 				return FALSE;
 			}
 		}
@@ -379,17 +445,13 @@
 		{
 			// Fetch the data from the corresponding $_POST or validation array and cache it in the _field_data array.
 			// Depending on whether the field name is an array or a string will determine where we get it from.
-
 			if ($row['is_array'] === TRUE)
 			{
 				$this->_field_data[$field]['postdata'] = $this->_reduce_array($validation_array, $row['keys']);
 			}
-			else
+			elseif (isset($validation_array[$field]) && $validation_array[$field] !== '')
 			{
-				if (isset($validation_array[$field]) AND $validation_array[$field] != "")
-				{
-					$this->_field_data[$field]['postdata'] = $validation_array[$field];
-				}
+				$this->_field_data[$field]['postdata'] = $validation_array[$field];
 			}
 
 			$this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']);
@@ -397,7 +459,6 @@
 
 		// Did we end up with any errors?
 		$total_errors = count($this->_error_array);
-
 		if ($total_errors > 0)
 		{
 			$this->_safe_form_data = TRUE;
@@ -416,7 +477,7 @@
 	 *
 	 * @param	array
 	 * @param	array
-	 * @param	integer
+	 * @param	int
 	 * @return	mixed
 	 */
 	protected function _reduce_array($array, $keys, $i = 0)
@@ -434,7 +495,7 @@
 	/**
 	 * Re-populate the _POST array with our finalized and processed data
 	 *
-	 * @return	null
+	 * @return	void
 	 */
 	protected function _reset_post_array()
 	{
@@ -494,7 +555,7 @@
 	 * @param	array
 	 * @param	array
 	 * @param	mixed
-	 * @param	integer
+	 * @param	int
 	 * @return	mixed
 	 */
 	protected function _execute($row, $rules, $postdata = NULL, $cycles = 0)
@@ -511,17 +572,15 @@
 			return;
 		}
 
-		// --------------------------------------------------------------------
-
 		// If the field is blank, but NOT required, no further tests are necessary
 		$callback = FALSE;
-		if ( ! in_array('required', $rules) AND is_null($postdata))
+		if ( ! in_array('required', $rules) && is_null($postdata))
 		{
 			// Before we bail out, does the rule contain a callback?
-			if (preg_match("/(callback_\w+(\[.*?\])?)/", implode(' ', $rules), $match))
+			if (preg_match('/(callback_\w+(\[.*?\])?)/', implode(' ', $rules), $match))
 			{
 				$callback = TRUE;
-				$rules = (array('1' => $match[1]));
+				$rules = array(1 => $match[1]);
 			}
 			else
 			{
@@ -529,27 +588,22 @@
 			}
 		}
 
-		// --------------------------------------------------------------------
-
 		// Isset Test. Typically this rule will only apply to checkboxes.
-		if (is_null($postdata) AND $callback === FALSE)
+		if (is_null($postdata) && $callback === FALSE)
 		{
 			if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
 			{
 				// Set the message type
-				$type = (in_array('required', $rules)) ? 'required' : 'isset';
+				$type = in_array('required', $rules) ? 'required' : 'isset';
 
-				if ( ! isset($this->_error_messages[$type]))
-				{
-					if (FALSE === ($line = $this->CI->lang->line($type)))
-					{
-						$line = 'The field was not set';
-					}
-				}
-				else
+				if (isset($this->_error_messages[$type]))
 				{
 					$line = $this->_error_messages[$type];
 				}
+				elseif (FALSE === ($line = $this->CI->lang->line($type)))
+				{
+					$line = 'The field was not set';
+				}
 
 				// Build the error message
 				$message = sprintf($line, $this->_translate_fieldname($row['label']));
@@ -569,13 +623,13 @@
 		// --------------------------------------------------------------------
 
 		// Cycle through each rule and run it
-		foreach ($rules As $rule)
+		foreach ($rules as $rule)
 		{
 			$_in_array = FALSE;
 
 			// We set the $postdata variable with the current data in our master array so that
 			// each cycle of the loop is dealing with the processed data from the last cycle
-			if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata']))
+			if ($row['is_array'] === TRUE && is_array($this->_field_data[$row['field']]['postdata']))
 			{
 				// We shouldn't need this safety, but just in case there isn't an array index
 				// associated with this cycle we'll bail out
@@ -592,11 +646,9 @@
 				$postdata = $this->_field_data[$row['field']]['postdata'];
 			}
 
-			// --------------------------------------------------------------------
-
 			// Is the rule a callback?
 			$callback = FALSE;
-			if (substr($rule, 0, 9) == 'callback_')
+			if (strpos($rule, 'callback_') === 0)
 			{
 				$rule = substr($rule, 9);
 				$callback = TRUE;
@@ -605,7 +657,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];
@@ -616,68 +668,69 @@
 			{
 				if ( ! method_exists($this->CI, $rule))
 				{
-					continue;
+					log_message('debug', 'Unable to find callback validation rule: '.$rule);
+					$result = FALSE;
 				}
-
-				// Run the function and grab the result
-				$result = $this->CI->$rule($postdata, $param);
+				else
+				{
+					// Run the function and grab the result
+					$result = $this->CI->$rule($postdata, $param);
+				}
 
 				// Re-assign the result to the master data array
 				if ($_in_array === TRUE)
 				{
-					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
+					$this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
 				}
 				else
 				{
-					$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
+					$this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
 				}
 
 				// If the field isn't required and we just processed a callback we'll move on...
-				if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE)
+				if ( ! in_array('required', $rules, TRUE) && $result !== FALSE)
 				{
 					continue;
 				}
 			}
+			elseif ( ! method_exists($this, $rule))
+			{
+				// If our own wrapper function doesn't exist we see if a native PHP function does.
+				// Users can use any native PHP function call that has one param.
+				if (function_exists($rule))
+				{
+					$result = ($param !== FALSE) ? $rule($postdata, $param) : $rule($postdata);
+
+					if ($_in_array === TRUE)
+					{
+						$this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
+					}
+					else
+					{
+						$this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
+					}
+				}
+				else
+				{
+					log_message('debug', 'Unable to find validation rule: '.$rule);
+					$result = FALSE;
+				}
+			}
 			else
 			{
-				if ( ! method_exists($this, $rule))
-				{
-					// If our own wrapper function doesn't exist we see if a native PHP function does.
-					// Users can use any native PHP function call that has one param.
-					if (function_exists($rule))
-					{
-						$result = $rule($postdata);
-
-						if ($_in_array === TRUE)
-						{
-							$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
-						}
-						else
-						{
-							$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
-						}
-					}
-					else
-					{
-						log_message('debug', "Unable to find validation rule: ".$rule);
-					}
-
-					continue;
-				}
-
 				$result = $this->$rule($postdata, $param);
 
 				if ($_in_array === TRUE)
 				{
-					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
+					$this->_field_data[$row['field']]['postdata'][$cycles] = is_bool($result) ? $postdata : $result;
 				}
 				else
 				{
-					$this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result;
+					$this->_field_data[$row['field']]['postdata'] = is_bool($result) ? $postdata : $result;
 				}
 			}
 
-			// Did the rule test negatively?  If so, grab the error.
+			// Did the rule test negatively? If so, grab the error.
 			if ($result === FALSE)
 			{
 				if ( ! isset($this->_error_messages[$rule]))
@@ -693,7 +746,7 @@
 				}
 
 				// Is the parameter we are inserting into the error message the name
-				// of another field?  If so we need to grab its "field label"
+				// of another field? If so we need to grab its "field label"
 				if (isset($this->_field_data[$param], $this->_field_data[$param]['label']))
 				{
 					$param = $this->_translate_fieldname($this->_field_data[$param]['label']);
@@ -727,7 +780,7 @@
 	{
 		// Do we need to translate the field name?
 		// We look for the prefix lang: to determine this
-		if (substr($fieldname, 0, 5) === 'lang:')
+		if (strpos($fieldname, 'lang:') === 0)
 		{
 			// Grab the variable
 			$line = substr($fieldname, 5);
@@ -781,6 +834,7 @@
 	 *
 	 * @param	string
 	 * @param	string
+	 * @param	bool
 	 * @return	string
 	 */
 	public function set_select($field = '', $value = '', $default = FALSE)
@@ -791,7 +845,6 @@
 		}
 
 		$field = $this->_field_data[$field]['postdata'];
-
 		if (is_array($field))
 		{
 			if ( ! in_array($value, $field))
@@ -799,7 +852,7 @@
 				return '';
 			}
 		}
-		elseif (($field == '' OR $value == '') OR ($field != $value))
+		elseif (($field === '' OR $value === '') OR ($field !== $value))
 		{
 			return '';
 		}
@@ -817,6 +870,7 @@
 	 *
 	 * @param	string
 	 * @param	string
+	 * @param	bool
 	 * @return	string
 	 */
 	public function set_radio($field = '', $value = '', $default = FALSE)
@@ -827,7 +881,6 @@
 		}
 
 		$field = $this->_field_data[$field]['postdata'];
-
 		if (is_array($field))
 		{
 			if ( ! in_array($value, $field))
@@ -835,12 +888,9 @@
 				return '';
 			}
 		}
-		else
+		elseif (($field === '' OR $value === '') OR ($field !== $value))
 		{
-			if (($field == '' OR $value == '') OR ($field != $value))
-			{
-				return '';
-			}
+			return '';
 		}
 
 		return ' checked="checked"';
@@ -856,6 +906,7 @@
 	 *
 	 * @param	string
 	 * @param	string
+	 * @param	bool
 	 * @return	string
 	 */
 	public function set_checkbox($field = '', $value = '', $default = FALSE)
@@ -874,7 +925,7 @@
 	 */
 	public function required($str)
 	{
-		return ( ! is_array($str)) ? (trim($str) !== '') : ( ! empty($str));
+		return is_array($str) ? (bool) count($str) : (trim($str) !== '');
 	}
 
 	// --------------------------------------------------------------------
@@ -883,7 +934,7 @@
 	 * Performs a Regular Expression match test.
 	 *
 	 * @param	string
-	 * @param	regex
+	 * @param	string	regex
 	 * @return	bool
 	 */
 	public function regex_match($str, $regex)
@@ -897,18 +948,14 @@
 	 * Match one field to another
 	 *
 	 * @param	string
-	 * @param	field
+	 * @param	string	field
 	 * @return	bool
 	 */
 	public function matches($str, $field)
 	{
-		$validation_array = ( ! empty($this->validation_data)) ? $this->validation_data : $_POST;
-		if ( ! isset($validation_array[$field]))
-		{
-			return FALSE;
-		}
+		$validation_array = empty($this->validation_data) ? $_POST : $this->validation_data;
 
-		return ($str === $validation_array[$field]);
+		return isset($validation_array[$field]) ? ($str === $validation_array[$field]) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -920,7 +967,7 @@
 	 * in the specified database field.
 	 *
 	 * @param	string
-	 * @param	field
+	 * @param	string	field
 	 * @return	bool
 	 */
 	public function is_unique($str, $field)
@@ -940,7 +987,7 @@
 	 * Minimum Length
 	 *
 	 * @param	string
-	 * @param	value
+	 * @param	int
 	 * @return	bool
 	 */
 	public function min_length($str, $val)
@@ -950,12 +997,9 @@
 			return FALSE;
 		}
 
-		if (MB_ENABLED === TRUE)
-		{
-			return ! (mb_strlen($str) < $val);
-		}
-
-		return ! (strlen($str) < $val);
+		return (MB_ENABLED === TRUE)
+			? ($val <= mb_strlen($str))
+			: ($val <= strlen($str));
 	}
 
 	// --------------------------------------------------------------------
@@ -964,7 +1008,7 @@
 	 * Max Length
 	 *
 	 * @param	string
-	 * @param	value
+	 * @param	int
 	 * @return	bool
 	 */
 	public function max_length($str, $val)
@@ -974,12 +1018,9 @@
 			return FALSE;
 		}
 
-		if (MB_ENABLED === TRUE)
-		{
-			return ! (mb_strlen($str) > $val);
-		}
-
-		return ! (strlen($str) > $val);
+		return (MB_ENABLED === TRUE)
+			? ($val >= mb_strlen($str))
+			: ($val >= strlen($str));
 	}
 
 	// --------------------------------------------------------------------
@@ -988,7 +1029,7 @@
 	 * Exact Length
 	 *
 	 * @param	string
-	 * @param	value
+	 * @param	int
 	 * @return	bool
 	 */
 	public function exact_length($str, $val)
@@ -998,12 +1039,9 @@
 			return FALSE;
 		}
 
-		if (MB_ENABLED === TRUE)
-		{
-			return (mb_strlen($str) == $val);
-		}
-
-		return (strlen($str) == $val);
+		return (MB_ENABLED === TRUE)
+			? (mb_strlen($str) === $val)
+			: (strlen($str) === $val);
 	}
 
 	// --------------------------------------------------------------------
@@ -1114,19 +1152,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Is Numeric
-	 *
-	 * @param	string
-	 * @return	bool
-	 */
-	public function is_numeric($str)
-	{
-		return is_numeric($str);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Integer
 	 *
 	 * @param	string
@@ -1156,15 +1181,12 @@
 	 * Greater than
 	 *
 	 * @param	string
+	 * @param	int
 	 * @return	bool
 	 */
 	public function greater_than($str, $min)
 	{
-		if ( ! is_numeric($str))
-		{
-			return FALSE;
-		}
-		return $str > $min;
+		return is_numeric($str) ? ($str > $min) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1173,15 +1195,12 @@
 	 * Equal to or Greater than
 	 *
 	 * @param	string
+	 * @param	int
 	 * @return	bool
 	 */
 	public function greater_than_equal_to($str, $min)
 	{
-		if ( ! is_numeric($str))
-		{
-			return FALSE;
-		}
-		return $str >= $min;
+		return is_numeric($str) ? ($str >= $min) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1190,15 +1209,12 @@
 	 * Less than
 	 *
 	 * @param	string
+	 * @param	int
 	 * @return	bool
 	 */
 	public function less_than($str, $max)
 	{
-		if ( ! is_numeric($str))
-		{
-			return FALSE;
-		}
-		return $str < $max;
+		return is_numeric($str) ? ($str < $max) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1207,15 +1223,12 @@
 	 * Equal to or Less than
 	 *
 	 * @param	string
+	 * @param	int
 	 * @return	bool
 	 */
 	public function less_than_equal_to($str, $max)
 	{
-		if ( ! is_numeric($str))
-		{
-			return FALSE;
-		}
-		return $str <= $max;
+		return is_numeric($str) ? ($str <= $max) : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1241,7 +1254,7 @@
 	 */
 	public function is_natural_no_zero($str)
 	{
-		return ($str != 0 && preg_match('/^[0-9]+$/', $str));
+		return ($str !== 0 && preg_match('/^[0-9]+$/', $str));
 	}
 
 	// --------------------------------------------------------------------
@@ -1257,7 +1270,7 @@
 	 */
 	public function valid_base64($str)
 	{
-		return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
+		return ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1283,7 +1296,7 @@
 			return $data;
 		}
 
-		if ($this->_safe_form_data == FALSE OR $data === '')
+		if ($this->_safe_form_data === FALSE OR $data === '')
 		{
 			return $data;
 		}
@@ -1301,14 +1314,14 @@
 	 */
 	public function prep_url($str = '')
 	{
-		if ($str == 'http://' OR $str == '')
+		if ($str === 'http://' OR $str === '')
 		{
 			return '';
 		}
 
-		if (substr($str, 0, 7) !== 'http://' && substr($str, 0, 8) !== 'https://')
+		if (strpos($str, 'http://') !== 0 && strpos($str, 'https://') !== 0)
 		{
-			$str = 'http://'.$str;
+			return 'http://'.$str;
 		}
 
 		return $str;
@@ -1375,4 +1388,4 @@
 }
 
 /* End of file Form_validation.php */
-/* Location: ./system/libraries/Form_validation.php */
+/* Location: ./system/libraries/Form_validation.php */
\ No newline at end of file
diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php
index 8aa1650..461e884 100644
--- a/system/libraries/Ftp.php
+++ b/system/libraries/Ftp.php
@@ -44,7 +44,6 @@
 	public $debug		= FALSE;
 	public $conn_id		= FALSE;
 
-
 	public function __construct($config = array())
 	{
 		if (count($config) > 0)
@@ -94,7 +93,7 @@
 
 		if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port)))
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_unable_to_connect');
 			}
@@ -103,7 +102,7 @@
 
 		if ( ! $this->_login())
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_unable_to_login');
 			}
@@ -111,7 +110,7 @@
 		}
 
 		// Set passive mode if needed
-		if ($this->passive == TRUE)
+		if ($this->passive === TRUE)
 		{
 			ftp_pasv($this->conn_id, TRUE);
 		}
@@ -142,7 +141,7 @@
 	{
 		if ( ! is_resource($this->conn_id))
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_no_connection');
 			}
@@ -168,7 +167,7 @@
 	 */
 	public function changedir($path = '', $supress_debug = FALSE)
 	{
-		if ($path == '' OR ! $this->_is_conn())
+		if ($path === '' OR ! $this->_is_conn())
 		{
 			return FALSE;
 		}
@@ -177,7 +176,7 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE && $supress_debug == FALSE)
+			if ($this->debug === TRUE && $supress_debug === FALSE)
 			{
 				$this->_error('ftp_unable_to_changedir');
 			}
@@ -198,7 +197,7 @@
 	 */
 	public function mkdir($path = '', $permissions = NULL)
 	{
-		if ($path == '' OR ! $this->_is_conn())
+		if ($path === '' OR ! $this->_is_conn())
 		{
 			return FALSE;
 		}
@@ -207,7 +206,7 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_unable_to_makdir');
 			}
@@ -261,7 +260,7 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_unable_to_upload');
 			}
@@ -308,7 +307,7 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_unable_to_download');
 			}
@@ -339,9 +338,9 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
-				$this->_error('ftp_unable_to_' . ($move == FALSE ? 'rename' : 'move'));
+				$this->_error('ftp_unable_to_' . ($move === FALSE ? 'rename' : 'move'));
 			}
 			return FALSE;
 		}
@@ -382,7 +381,7 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_unable_to_delete');
 			}
@@ -430,7 +429,7 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_unable_to_delete');
 			}
@@ -460,7 +459,7 @@
 
 		if ($result === FALSE)
 		{
-			if ($this->debug == TRUE)
+			if ($this->debug === TRUE)
 			{
 				$this->_error('ftp_unable_to_chmod');
 			}
@@ -539,7 +538,6 @@
 		return FALSE;
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 86b77bf..4735dfd 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -36,56 +36,336 @@
  */
 class CI_Image_lib {
 
-	public $image_library		= 'gd2';	// Can be:  imagemagick, netpbm, gd, gd2
+	/**
+	 * PHP extension/library to use for image manipulation
+	 * Can be: imagemagick, netpbm, gd, gd2
+	 *
+	 * @var string
+	 */
+	public $image_library		= 'gd2';
+
+	/**
+	 * Path to the graphic library (if applicable)
+	 *
+	 * @var string
+	 */
 	public $library_path		= '';
-	public $dynamic_output		= FALSE;	// Whether to send to browser or write to disk
+
+	/**
+	 * Whether to send to browser or write to disk
+	 *
+	 * @var bool
+	 */
+	public $dynamic_output		= FALSE;
+
+	/**
+	 * Path to original image
+	 *
+	 * @var string
+	 */
 	public $source_image		= '';
-	public $new_image			= '';
-	public $width				= '';
-	public $height				= '';
-	public $quality			= '90';
+
+	/**
+	 * Path to the modified image
+	 *
+	 * @var string
+	 */
+	public $new_image		= '';
+
+	/**
+	 * Image width
+	 *
+	 * @var int
+	 */
+	public $width			= '';
+
+	/**
+	 * Image height
+	 *
+	 * @var int
+	 */
+	public $height			= '';
+
+	/**
+	 * Quality percentage of new image
+	 *
+	 * @var int
+	 */
+	public $quality			= 90;
+
+	/**
+	 * Whether to create a thumbnail
+	 *
+	 * @var bool
+	 */
 	public $create_thumb		= FALSE;
+
+	/**
+	 * String to add to thumbnail version of image
+	 *
+	 * @var string
+	 */
 	public $thumb_marker		= '_thumb';
-	public $maintain_ratio		= TRUE;		// Whether to maintain aspect ratio when resizing or use hard values
-	public $master_dim			= 'auto';	// auto, height, or width.  Determines what to use as the master dimension
+
+	/**
+	 * Whether to maintain aspect ratio when resizing or use hard values
+	 *
+	 * @var bool
+	 */
+	public $maintain_ratio		= TRUE;
+
+	/**
+	 * auto, height, or width.  Determines what to use as the master dimension
+	 *
+	 * @var string
+	 */
+	public $master_dim		= 'auto';
+
+	/**
+	 * Angle at to rotate image
+	 *
+	 * @var string
+	 */
 	public $rotation_angle		= '';
-	public $x_axis				= '';
-	public $y_axis				= '';
 
+	/**
+	 * X Coordinate for manipulation of the current image
+	 *
+	 * @var int
+	 */
+	public $x_axis			= '';
+
+	/**
+	 * Y Coordinate for manipulation of the current image
+	 *
+	 * @var int
+	 */
+	public $y_axis			= '';
+
+	// --------------------------------------------------------------------------
 	// Watermark Vars
-	public $wm_text			= '';			// Watermark text if graphic is not used
-	public $wm_type			= 'text';		// Type of watermarking.  Options:  text/overlay
-	public $wm_x_transp		= 4;
-	public $wm_y_transp		= 4;
-	public $wm_overlay_path	= '';			// Watermark image path
-	public $wm_font_path		= '';			// TT font
-	public $wm_font_size		= 17;			// Font size (different versions of GD will either use points or pixels)
-	public $wm_vrt_alignment	= 'B';			// Vertical alignment:   T M B
-	public $wm_hor_alignment	= 'C';			// Horizontal alignment: L R C
-	public $wm_padding			= 0;			// Padding around text
-	public $wm_hor_offset		= 0;			// Lets you push text to the right
-	public $wm_vrt_offset		= 0;			// Lets you push  text down
-	protected $wm_font_color		= '#ffffff';	// Text color
-	protected $wm_shadow_color		= '';	// Dropshadow color
-	public $wm_shadow_distance	= 2;			// Dropshadow distance
-	public $wm_opacity			= 50;			// Image opacity: 1 - 100  Only works with image
+	// --------------------------------------------------------------------------
 
+	/**
+	 * Watermark text if graphic is not used
+	 *
+	 * @var string
+	 */
+	public $wm_text			= '';
+
+	/**
+	 * Type of watermarking.  Options:  text/overlay
+	 *
+	 * @var string
+	 */
+	public $wm_type			= 'text';
+
+	/**
+	 * Default transparency for watermark
+	 *
+	 * @var int
+	 */
+	public $wm_x_transp		= 4;
+
+	/**
+	 * Default transparency for watermark
+	 *
+	 * @var int
+	 */
+	public $wm_y_transp		= 4;
+
+	/**
+	 * Watermark image path
+	 *
+	 * @var string
+	 */
+	public $wm_overlay_path		= '';
+
+	/**
+	 * TT font
+	 *
+	 * @var string
+	 */
+	public $wm_font_path		= '';
+
+	/**
+	 * Font size (different versions of GD will either use points or pixels)
+	 *
+	 * @var int
+	 */
+	public $wm_font_size		= 17;
+
+	/**
+	 * Vertical alignment:   T M B
+	 *
+	 * @var string
+	 */
+	public $wm_vrt_alignment	= 'B';
+
+	/**
+	 * Horizontal alignment: L R C
+	 *
+	 * @var string
+	 */
+	public $wm_hor_alignment	= 'C';
+
+	/**
+	 * Padding around text
+	 *
+	 * @var int
+	 */
+	public $wm_padding			= 0;
+
+	/**
+	 * Lets you push text to the right
+	 *
+	 * @var int
+	 */
+	public $wm_hor_offset		= 0;
+
+	/**
+	 * Lets you push text down
+	 *
+	 * @var int
+	 */
+	public $wm_vrt_offset		= 0;
+
+	/**
+	 * Text color
+	 *
+	 * @var string
+	 */
+	protected $wm_font_color	= '#ffffff';
+
+	/**
+	 * Dropshadow color
+	 *
+	 * @var string
+	 */
+	protected $wm_shadow_color	= '';
+
+	/**
+	 * Dropshadow distance
+	 *
+	 * @var int
+	 */
+	public $wm_shadow_distance	= 2;
+
+	/**
+	 * Image opacity: 1 - 100  Only works with image
+	 *
+	 * @var int
+	 */
+	public $wm_opacity		= 50;
+
+	// --------------------------------------------------------------------------
 	// Private Vars
+	// --------------------------------------------------------------------------
+
+	/**
+	 * Source image folder
+	 *
+	 * @var string
+	 */
 	public $source_folder		= '';
+
+	/**
+	 * Destination image folder
+	 *
+	 * @var string
+	 */
 	public $dest_folder		= '';
-	public $mime_type			= '';
-	public $orig_width			= '';
+
+	/**
+	 * Image mime-type
+	 *
+	 * @var string
+	 */
+	public $mime_type		= '';
+
+	/**
+	 * Original image width
+	 *
+	 * @var int
+	 */
+	public $orig_width		= '';
+
+	/**
+	 * Original image height
+	 *
+	 * @var int
+	 */
 	public $orig_height		= '';
-	public $image_type			= '';
-	public $size_str			= '';
+
+	/**
+	 * Image format
+	 *
+	 * @var string
+	 */
+	public $image_type		= '';
+
+	/**
+	 * Size of current image
+	 *
+	 * @var string
+	 */
+	public $size_str		= '';
+
+	/**
+	 * Full path to source image
+	 *
+	 * @var string
+	 */
 	public $full_src_path		= '';
+
+	/**
+	 * Full path to destination image
+	 *
+	 * @var string
+	 */
 	public $full_dst_path		= '';
-	public $create_fnc			= 'imagecreatetruecolor';
-	public $copy_fnc			= 'imagecopyresampled';
-	public $error_msg			= array();
+
+	/**
+	 * Name of function to create image
+	 *
+	 * @var string
+	 */
+	public $create_fnc		= 'imagecreatetruecolor';
+
+	/**
+	 * Name of function to copy image
+	 *
+	 * @var string
+	 */
+	public $copy_fnc		= 'imagecopyresampled';
+
+	/**
+	 * Error messages
+	 *
+	 * @var array
+	 */
+	public $error_msg		= array();
+
+	/**
+	 * Whether to have a drop shadow on watermark
+	 *
+	 * @var bool
+	 */
 	protected $wm_use_drop_shadow	= FALSE;
+
+	/**
+	 * Whether to use truetype fonts
+	 *
+	 * @var bool
+	 */
 	public $wm_use_truetype	= FALSE;
 
+	/**
+	 * Initialize Image Library
+	 *
+	 * @param	array	$props
+	 * @return	void
+	 */
 	public function __construct($props = array())
 	{
 		if (count($props) > 0)
@@ -116,7 +396,7 @@
 
 		$this->image_library 		= 'gd2';
 		$this->dynamic_output 		= FALSE;
-		$this->quality 				= '90';
+		$this->quality 				= 90;
 		$this->create_thumb 		= FALSE;
 		$this->thumb_marker 		= '_thumb';
 		$this->maintain_ratio 		= TRUE;
@@ -186,7 +466,7 @@
 		}
 
 		// Is there a source image? If not, there's no reason to continue
-		if ($this->source_image == '')
+		if ($this->source_image === '')
 		{
 			$this->set_error('imglib_source_image_required');
 			return FALSE;
@@ -239,7 +519,7 @@
 		 * it means we are altering the original. We'll
 		 * set the destination filename and path accordingly.
 		 */
-		if ($this->new_image == '')
+		if ($this->new_image === '')
 		{
 			$this->dest_image = $this->source_image;
 			$this->dest_folder = $this->source_folder;
@@ -251,7 +531,7 @@
 		}
 		else
 		{
-			if (strpos($this->new_image, '/') === FALSE AND strpos($this->new_image, '\\') === FALSE)
+			if (strpos($this->new_image, '/') === FALSE && strpos($this->new_image, '\\') === FALSE)
 			{
 				$full_dest_path = str_replace('\\', '/', realpath($this->new_image));
 			}
@@ -282,7 +562,7 @@
 		 * We'll also split the destination image name
 		 * so we can insert the thumbnail marker if needed.
 		 */
-		if ($this->create_thumb === FALSE OR $this->thumb_marker == '')
+		if ($this->create_thumb === FALSE OR $this->thumb_marker === '')
 		{
 			$this->thumb_marker = '';
 		}
@@ -301,7 +581,7 @@
 		 * might not be in correct proportion with the source
 		 * image's width/height. We'll recalculate it here.
 		 */
-		if ($this->maintain_ratio === TRUE && ($this->width != 0 OR $this->height != 0))
+		if ($this->maintain_ratio === TRUE && ($this->width !== 0 OR $this->height !== 0))
 		{
 			$this->image_reproportion();
 		}
@@ -311,12 +591,12 @@
 		 * If the destination width/height was not submitted we
 		 * will use the values from the actual file
 		 */
-		if ($this->width == '')
+		if ($this->width === '')
 		{
 			$this->width = $this->orig_width;
 		}
 
-		if ($this->height == '')
+		if ($this->height === '')
 		{
 			$this->height = $this->orig_height;
 		}
@@ -324,31 +604,31 @@
 		// Set the quality
 		$this->quality = trim(str_replace('%', '', $this->quality));
 
-		if ($this->quality == '' OR $this->quality == 0 OR ! preg_match('/^[0-9]+$/', $this->quality))
+		if ($this->quality === '' OR $this->quality === 0 OR ! preg_match('/^[0-9]+$/', $this->quality))
 		{
 			$this->quality = 90;
 		}
 
 		// Set the x/y coordinates
-		$this->x_axis = ($this->x_axis == '' OR ! preg_match('/^[0-9]+$/', $this->x_axis)) ? 0 : $this->x_axis;
-		$this->y_axis = ($this->y_axis == '' OR ! preg_match('/^[0-9]+$/', $this->y_axis)) ? 0 : $this->y_axis;
+		is_numeric($this->x_axis) OR $this->x_axis = 0;
+		is_numeric($this->y_axis) OR $this->y_axis = 0;
 
 		// Watermark-related Stuff...
-		if ($this->wm_overlay_path != '')
+		if ($this->wm_overlay_path !== '')
 		{
 			$this->wm_overlay_path = str_replace('\\', '/', realpath($this->wm_overlay_path));
 		}
 
-		if ($this->wm_shadow_color != '')
+		if ($this->wm_shadow_color !== '')
 		{
 			$this->wm_use_drop_shadow = TRUE;
 		}
-		elseif ($this->wm_use_drop_shadow == TRUE && $this->wm_shadow_color == '')
+		elseif ($this->wm_use_drop_shadow === TRUE && $this->wm_shadow_color === '')
 		{
 			$this->wm_use_drop_shadow = FALSE;
 		}
 
-		if ($this->wm_font_path != '')
+		if ($this->wm_font_path !== '')
 		{
 			$this->wm_use_truetype = TRUE;
 		}
@@ -403,14 +683,14 @@
 		// Allowed rotation values
 		$degs = array(90, 180, 270, 'vrt', 'hor');
 
-		if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs))
+		if ($this->rotation_angle === '' OR ! in_array($this->rotation_angle, $degs))
 		{
 			$this->set_error('imglib_rotation_angle_required');
 			return FALSE;
 		}
 
 		// Reassign the width and height
-		if ($this->rotation_angle == 90 OR $this->rotation_angle == 270)
+		if ($this->rotation_angle === 90 OR $this->rotation_angle === 270)
 		{
 			$this->width	= $this->orig_height;
 			$this->height	= $this->orig_width;
@@ -449,9 +729,9 @@
 
 		// If the target width/height match the source, AND if the new file name is not equal to the old file name
 		// we'll simply make a copy of the original with the new name... assuming dynamic rendering is off.
-		if ($this->dynamic_output === FALSE && $this->orig_width == $this->width && $this->orig_height == $this->height)
+		if ($this->dynamic_output === FALSE && $this->orig_width === $this->width && $this->orig_height === $this->height)
 		{
-			if ($this->source_image != $this->new_image && @copy($this->full_src_path, $this->full_dst_path))
+			if ($this->source_image !== $this->new_image && @copy($this->full_src_path, $this->full_dst_path))
 			{
 				@chmod($this->full_dst_path, FILE_WRITE_MODE);
 			}
@@ -460,7 +740,7 @@
 		}
 
 		// Let's set up our values based on the action
-		if ($action == 'crop')
+		if ($action === 'crop')
 		{
 			// Reassign the source width/height if cropping
 			$this->orig_width  = $this->width;
@@ -470,7 +750,7 @@
 			if ($this->gd_version() !== FALSE)
 			{
 				$gd_version = str_replace('0', '', $this->gd_version());
-				$v2_override = ($gd_version == 2) ? TRUE : FALSE;
+				$v2_override = ($gd_version === 2);
 			}
 		}
 		else
@@ -492,7 +772,7 @@
 		 * it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment
 		 * below should that ever prove inaccurate.
 		 *
-		 * if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor') && $v2_override == FALSE)
+		 * if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor') && $v2_override === FALSE)
 		 */
 		if ($this->image_library === 'gd2' && function_exists('imagecreatetruecolor'))
 		{
@@ -507,7 +787,7 @@
 
 		$dst_img = $create($this->width, $this->height);
 
-		if ($this->image_type == 3) // png we can actually preserve transparency
+		if ($this->image_type === 3) // png we can actually preserve transparency
 		{
 			imagealphablending($dst_img, FALSE);
 			imagesavealpha($dst_img, TRUE);
@@ -516,7 +796,7 @@
 		$copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height);
 
 		// Show the image
-		if ($this->dynamic_output == TRUE)
+		if ($this->dynamic_output === TRUE)
 		{
 			$this->image_display_gd($dst_img);
 		}
@@ -548,7 +828,7 @@
 	public function image_process_imagemagick($action = 'resize')
 	{
 		//  Do we have a vaild library path?
-		if ($this->library_path == '')
+		if ($this->library_path === '')
 		{
 			$this->set_error('imglib_libpath_invalid');
 			return FALSE;
@@ -562,11 +842,11 @@
 		// Execute the command
 		$cmd = $this->library_path.' -quality '.$this->quality;
 
-		if ($action == 'crop')
+		if ($action === 'crop')
 		{
 			$cmd .= ' -crop '.$this->width.'x'.$this->height.'+'.$this->x_axis.'+'.$this->y_axis.' "'.$this->full_src_path.'" "'.$this->full_dst_path .'" 2>&1';
 		}
-		elseif ($action == 'rotate')
+		elseif ($action === 'rotate')
 		{
 			$angle = ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
 					? '-flop' : '-rotate '.$this->rotation_angle;
@@ -606,7 +886,7 @@
 	 */
 	public function image_process_netpbm($action = 'resize')
 	{
-		if ($this->library_path == '')
+		if ($this->library_path === '')
 		{
 			$this->set_error('imglib_libpath_invalid');
 			return FALSE;
@@ -616,36 +896,36 @@
 		switch ($this->image_type)
 		{
 			case 1 :
-						$cmd_in		= 'giftopnm';
-						$cmd_out	= 'ppmtogif';
+				$cmd_in		= 'giftopnm';
+				$cmd_out	= 'ppmtogif';
 				break;
 			case 2 :
-						$cmd_in		= 'jpegtopnm';
-						$cmd_out	= 'ppmtojpeg';
+				$cmd_in		= 'jpegtopnm';
+				$cmd_out	= 'ppmtojpeg';
 				break;
 			case 3 :
-						$cmd_in		= 'pngtopnm';
-						$cmd_out	= 'ppmtopng';
+				$cmd_in		= 'pngtopnm';
+				$cmd_out	= 'ppmtopng';
 				break;
 		}
 
-		if ($action == 'crop')
+		if ($action === 'crop')
 		{
 			$cmd_inner = 'pnmcut -left '.$this->x_axis.' -top '.$this->y_axis.' -width '.$this->width.' -height '.$this->height;
 		}
-		elseif ($action == 'rotate')
+		elseif ($action === 'rotate')
 		{
 			switch ($this->rotation_angle)
 			{
-				case 90		:	$angle = 'r270';
+				case 90:	$angle = 'r270';
 					break;
-				case 180	:	$angle = 'r180';
+				case 180:	$angle = 'r180';
 					break;
-				case 270	:	$angle = 'r90';
+				case 270:	$angle = 'r90';
 					break;
-				case 'vrt'	:	$angle = 'tb';
+				case 'vrt':	$angle = 'tb';
 					break;
-				case 'hor'	:	$angle = 'lr';
+				case 'hor':	$angle = 'lr';
 					break;
 			}
 
@@ -704,7 +984,7 @@
 		$dst_img = imagerotate($src_img, $this->rotation_angle, $white);
 
 		// Show the image
-		if ($this->dynamic_output == TRUE)
+		if ($this->dynamic_output === TRUE)
 		{
 			$this->image_display_gd($dst_img);
 		}
@@ -778,7 +1058,7 @@
 		}
 
 		// Show the image
-		if ($this->dynamic_output == TRUE)
+		if ($this->dynamic_output === TRUE)
 		{
 			$this->image_display_gd($src_img);
 		}
@@ -804,7 +1084,6 @@
 	 * This is a wrapper function that chooses the type
 	 * of watermarking based on the specified preference.
 	 *
-	 * @param	string
 	 * @return	bool
 	 */
 	public function watermark()
@@ -850,10 +1129,10 @@
 		$this->wm_vrt_alignment = strtoupper($this->wm_vrt_alignment[0]);
 		$this->wm_hor_alignment = strtoupper($this->wm_hor_alignment[0]);
 
-		if ($this->wm_vrt_alignment == 'B')
+		if ($this->wm_vrt_alignment === 'B')
 			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;
 
-		if ($this->wm_hor_alignment == 'R')
+		if ($this->wm_hor_alignment === 'R')
 			$this->wm_hor_offset = $this->wm_hor_offset * -1;
 
 		// Set the base x and y axis values
@@ -881,7 +1160,7 @@
 		}
 
 		//  Build the finalized image
-		if ($wm_img_type == 3 && function_exists('imagealphablending'))
+		if ($wm_img_type === 3 && function_exists('imagealphablending'))
 		{
 			@imagealphablending($src_img, TRUE);
 		}
@@ -904,7 +1183,7 @@
 		}
 
 		// Output the image
-		if ($this->dynamic_output == TRUE)
+		if ($this->dynamic_output === TRUE)
 		{
 			$this->image_display_gd($src_img);
 		}
@@ -933,7 +1212,7 @@
 			return FALSE;
 		}
 
-		if ($this->wm_use_truetype == TRUE && ! file_exists($this->wm_font_path))
+		if ($this->wm_use_truetype === TRUE && ! file_exists($this->wm_font_path))
 		{
 			$this->set_error('imglib_missing_font');
 			return FALSE;
@@ -949,18 +1228,18 @@
 		// invert the offset. Note: The horizontal
 		// offset flips itself automatically
 
-		if ($this->wm_vrt_alignment == 'B')
+		if ($this->wm_vrt_alignment === 'B')
 			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;
 
-		if ($this->wm_hor_alignment == 'R')
+		if ($this->wm_hor_alignment === 'R')
 			$this->wm_hor_offset = $this->wm_hor_offset * -1;
 
 		// Set font width and height
 		// These are calculated differently depending on
 		// whether we are using the true type font or not
-		if ($this->wm_use_truetype == TRUE)
+		if ($this->wm_use_truetype === TRUE)
 		{
-			if ($this->wm_font_size == '')
+			if ($this->wm_font_size === '')
 			{
 				$this->wm_font_size = 17;
 			}
@@ -979,7 +1258,7 @@
 		$x_axis = $this->wm_hor_offset + $this->wm_padding;
 		$y_axis = $this->wm_vrt_offset + $this->wm_padding;
 
-		if ($this->wm_use_drop_shadow == FALSE)
+		if ($this->wm_use_drop_shadow === FALSE)
 			$this->wm_shadow_distance = 0;
 
 		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
@@ -1037,7 +1316,7 @@
 		}
 
 		// Output the final image
-		if ($this->dynamic_output == TRUE)
+		if ($this->dynamic_output === TRUE)
 		{
 			$this->image_display_gd($src_img);
 		}
@@ -1060,14 +1339,15 @@
 	 * based on the type of image being processed
 	 *
 	 * @param	string
+	 * @param	string
 	 * @return	resource
 	 */
 	public function image_create_gd($path = '', $image_type = '')
 	{
-		if ($path == '')
+		if ($path === '')
 			$path = $this->full_src_path;
 
-		if ($image_type == '')
+		if ($image_type === '')
 			$image_type = $this->image_type;
 
 
@@ -1122,49 +1402,49 @@
 	{
 		switch ($this->image_type)
 		{
-			case 1 :
-						if ( ! function_exists('imagegif'))
-						{
-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
-							return FALSE;
-						}
+			case 1:
+				if ( ! function_exists('imagegif'))
+				{
+					$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_gif_not_supported'));
+					return FALSE;
+				}
 
-						if ( ! @imagegif($resource, $this->full_dst_path))
-						{
-							$this->set_error('imglib_save_failed');
-							return FALSE;
-						}
-				break;
-			case 2	:
-						if ( ! function_exists('imagejpeg'))
-						{
-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
-							return FALSE;
-						}
+				if ( ! @imagegif($resource, $this->full_dst_path))
+				{
+					$this->set_error('imglib_save_failed');
+					return FALSE;
+				}
+			break;
+			case 2:
+				if ( ! function_exists('imagejpeg'))
+				{
+					$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_jpg_not_supported'));
+					return FALSE;
+				}
 
-						if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
-						{
-							$this->set_error('imglib_save_failed');
-							return FALSE;
-						}
-				break;
-			case 3	:
-						if ( ! function_exists('imagepng'))
-						{
-							$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
-							return FALSE;
-						}
+				if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality))
+				{
+					$this->set_error('imglib_save_failed');
+					return FALSE;
+				}
+			break;
+			case 3:
+				if ( ! function_exists('imagepng'))
+				{
+					$this->set_error(array('imglib_unsupported_imagecreate', 'imglib_png_not_supported'));
+					return FALSE;
+				}
 
-						if ( ! @imagepng($resource, $this->full_dst_path))
-						{
-							$this->set_error('imglib_save_failed');
-							return FALSE;
-						}
-				break;
-			default		:
-							$this->set_error(array('imglib_unsupported_imagecreate'));
-							return FALSE;
-				break;
+				if ( ! @imagepng($resource, $this->full_dst_path))
+				{
+					$this->set_error('imglib_save_failed');
+					return FALSE;
+				}
+			break;
+			default:
+				$this->set_error(array('imglib_unsupported_imagecreate'));
+				return FALSE;
+			break;
 		}
 
 		return TRUE;
@@ -1187,13 +1467,13 @@
 
 		switch ($this->image_type)
 		{
-			case 1		:	imagegif($resource);
+			case 1	:	imagegif($resource);
 				break;
-			case 2		:	imagejpeg($resource, '', $this->quality);
+			case 2	:	imagejpeg($resource, '', $this->quality);
 				break;
-			case 3		:	imagepng($resource);
+			case 3	:	imagepng($resource);
 				break;
-			default		:	echo 'Unable to display the image';
+			default:	echo 'Unable to display the image';
 				break;
 		}
 	}
@@ -1214,7 +1494,7 @@
 	 */
 	public function image_reproportion()
 	{
-		if (($this->width == 0 && $this->height == 0) OR $this->orig_width == 0 OR $this->orig_height == 0
+		if (($this->width === 0 && $this->height === 0) OR $this->orig_width === 0 OR $this->orig_height === 0
 			OR ( ! preg_match('/^[0-9]+$/', $this->width) && ! preg_match('/^[0-9]+$/', $this->height))
 			OR ! preg_match('/^[0-9]+$/', $this->orig_width) OR ! preg_match('/^[0-9]+$/', $this->orig_height))
 		{
@@ -1261,6 +1541,7 @@
 	 * A helper function that gets info about the file
 	 *
 	 * @param	string
+	 * @param	bool
 	 * @return	mixed
 	 */
 	public function get_image_properties($path = '', $return = FALSE)
@@ -1268,7 +1549,7 @@
 		// For now we require GD but we should
 		// find a way to determine this using IM or NetPBM
 
-		if ($path == '')
+		if ($path === '')
 		{
 			$path = $this->full_src_path;
 		}
@@ -1283,7 +1564,7 @@
 		$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
 		$mime = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg';
 
-		if ($return == TRUE)
+		if ($return === TRUE)
 		{
 			return array(
 					'width' =>	$vals[0],
@@ -1333,20 +1614,22 @@
 
 		foreach ($allowed as $item)
 		{
-			if ( ! isset($vals[$item]) OR $vals[$item] == '')
+			if (empty($vals[$item]))
+			{
 				$vals[$item] = 0;
+			}
 		}
 
-		if ($vals['width'] == 0 OR $vals['height'] == 0)
+		if ($vals['width'] === 0 OR $vals['height'] === 0)
 		{
 			return $vals;
 		}
 
-		if ($vals['new_width'] == 0)
+		if ($vals['new_width'] === 0)
 		{
 			$vals['new_width'] = ceil($vals['width']*$vals['new_height']/$vals['height']);
 		}
-		elseif ($vals['new_height'] == 0)
+		elseif ($vals['new_height'] === 0)
 		{
 			$vals['new_height'] = ceil($vals['new_width']*$vals['height']/$vals['width']);
 		}
@@ -1432,15 +1715,14 @@
 		{
 			foreach ($msg as $val)
 			{
-
-				$msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
+				$msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val);
 				$this->error_msg[] = $msg;
 				log_message('error', $msg);
 			}
 		}
 		else
 		{
-			$msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
+			$msg = ($CI->lang->line($msg) === FALSE) ? $msg : $CI->lang->line($msg);
 			$this->error_msg[] = $msg;
 			log_message('error', $msg);
 		}
@@ -1452,6 +1734,7 @@
 	 * Show error messages
 	 *
 	 * @param	string
+	 * @param	string
 	 * @return	string
 	 */
 	public function display_errors($open = '<p>', $close = '</p>')
@@ -1462,4 +1745,4 @@
 }
 
 /* End of file Image_lib.php */
-/* Location: ./system/libraries/Image_lib.php */
+/* Location: ./system/libraries/Image_lib.php */
\ No newline at end of file
diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php
index 9ba9300..98fec61 100644
--- a/system/libraries/Javascript.php
+++ b/system/libraries/Javascript.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Javascript Class
  *
@@ -46,7 +44,7 @@
 
 		foreach ($defaults as $key => $val)
 		{
-			if (isset($params[$key]) && $params[$key] !== "")
+			if (isset($params[$key]) && $params[$key] !== '')
 			{
 				$defaults[$key] = $params[$key];
 			}
@@ -61,7 +59,7 @@
 		// make js to refer to current library
 		$this->js =& $this->CI->$js_library_driver;
 
-		log_message('debug', "Javascript Class Initialized and loaded.  Driver used: $js_library_driver");
+		log_message('debug', 'Javascript Class Initialized and loaded. Driver used: '.$js_library_driver);
 	}
 
 	// --------------------------------------------------------------------
@@ -107,7 +105,7 @@
 	 *
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
-	 * @param	boolean	whether or not to return false
+	 * @param	bool	whether or not to return false
 	 * @return	string
 	 */
 	public function click($element = 'this', $js = '', $ret_false = TRUE)
@@ -375,7 +373,6 @@
 	// Effects
 	// --------------------------------------------------------------------
 
-
 	/**
 	 * Add Class
 	 *
@@ -618,12 +615,9 @@
 		{
 			$this->_javascript_location = $external_file;
 		}
-		else
+		elseif ($this->CI->config->item('javascript_location') !== '')
 		{
-			if ($this->CI->config->item('javascript_location') != '')
-			{
-				$this->_javascript_location = $this->CI->config->item('javascript_location');
-			}
+			$this->_javascript_location = $this->CI->config->item('javascript_location');
 		}
 
 		if ($relative === TRUE OR strncmp($external_file, 'http://', 7) === 0 OR strncmp($external_file, 'https://', 8) === 0)
@@ -650,13 +644,13 @@
 	 * Outputs a <script> tag
 	 *
 	 * @param	string	The element to attach the event to
-	 * @param	boolean	If a CDATA section should be added
+	 * @param	bool	If a CDATA section should be added
 	 * @return	string
 	 */
 	public function inline($script, $cdata = TRUE)
 	{
 		return $this->_open_script()
-			. ($cdata ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n")
+			. ($cdata ? "\n// <![CDATA[\n".$script."\n// ]]>\n" : "\n".$script."\n")
 			. $this->_close_script();
 	}
 
@@ -673,7 +667,7 @@
 	protected function _open_script($src = '')
 	{
 		return '<script type="text/javascript" charset="'.strtolower($this->CI->config->item('charset')).'"'
-			. ($src == '' ? '>' : ' src="'.$src.'">');
+			.($src === '' ? '>' : ' src="'.$src.'">');
 	}
 
 	// --------------------------------------------------------------------
@@ -688,15 +682,12 @@
 	 */
 	protected function _close_script($extra = "\n")
 	{
-		return "</script>$extra";
+		return '</script>'.$extra;
 	}
 
-
-	// --------------------------------------------------------------------
 	// --------------------------------------------------------------------
 	// AJAX-Y STUFF - still a testbed
 	// --------------------------------------------------------------------
-	// --------------------------------------------------------------------
 
 	/**
 	 * Update
@@ -732,7 +723,7 @@
 		{
 			if (is_object($result))
 			{
-				$json_result = $result->result_array();
+				$json_result = is_callable(array($result, 'result_array')) ? $result->result_array() : (array) $result;
 			}
 			elseif (is_array($result))
 			{
@@ -751,9 +742,9 @@
 		$json = array();
 		$_is_assoc = TRUE;
 
-		if ( ! is_array($json_result) AND empty($json_result))
+		if ( ! is_array($json_result) && empty($json_result))
 		{
-			show_error("Generate JSON Failed - Illegal key, value pair.");
+			show_error('Generate JSON Failed - Illegal key, value pair.');
 		}
 		elseif ($match_array_type)
 		{
@@ -774,7 +765,7 @@
 
 		$json = implode(',', $json);
 
-		return $_is_assoc ? "{".$json."}" : "[".$json."]";
+		return $_is_assoc ? '{'.$json.'}' : '['.$json.']';
 
 	}
 
@@ -785,8 +776,8 @@
 	 *
 	 * Checks for an associative array
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	bool
 	 */
 	protected function _is_associative_array($arr)
 	{
@@ -808,8 +799,8 @@
 	 *
 	 * Ensures a standard json value and escapes values
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	mixed
+	 * @return	string
 	 */
 	protected function _prep_args($result, $is_key = FALSE)
 	{
@@ -831,9 +822,7 @@
 		}
 	}
 
-	// --------------------------------------------------------------------
 }
-// END Javascript Class
 
 /* End of file Javascript.php */
-/* Location: ./system/libraries/Javascript.php */
+/* Location: ./system/libraries/Javascript.php */
\ No newline at end of file
diff --git a/system/libraries/Log.php b/system/libraries/Log.php
index 955277a..baac801 100644
--- a/system/libraries/Log.php
+++ b/system/libraries/Log.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Logging Class
  *
@@ -38,22 +36,65 @@
  */
 class CI_Log {
 
+	/**
+	 * Path to save log files
+	 *
+	 * @var string
+	 */
 	protected $_log_path;
-	protected $_threshold		= 1;
-	protected $_threshold_max	= 0;
-	protected $_threshold_array	= array();
-	protected $_date_fmt		= 'Y-m-d H:i:s';
-	protected $_enabled			= TRUE;
-	protected $_levels			= array('ERROR' => 1, 'DEBUG' => 2,  'INFO' => 3, 'ALL' => 4);
 
 	/**
-	 * Constructor
+	 * Level of logging
+	 *
+	 * @var int
+	 */
+	protected $_threshold		= 1;
+
+	/**
+	 * Highest level of logging
+	 *
+	 * @var int
+	 */
+	protected $_threshold_max	= 0;
+
+	/**
+	 * Array of threshold levels to log
+	 *
+	 * @var array
+	 */
+	protected $_threshold_array	= array();
+
+	/**
+	 * Format of timestamp for log files
+	 *
+	 * @var string
+	 */
+	protected $_date_fmt		= 'Y-m-d H:i:s';
+
+	/**
+	 * Whether or not the logger can write to the log files
+	 *
+	 * @var bool
+	 */
+	protected $_enabled		= TRUE;
+
+	/**
+	 * Predefined logging levels
+	 *
+	 * @var array
+	 */
+	protected $_levels		= array('ERROR' => 1, 'DEBUG' => 2,  'INFO' => 3, 'ALL' => 4);
+
+	/**
+	 * Initialize Logging class
+	 *
+	 * @return	void
 	 */
 	public function __construct()
 	{
 		$config =& get_config();
 
-		$this->_log_path = ($config['log_path'] != '') ? $config['log_path'] : APPPATH.'logs/';
+		$this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/';
 
 		if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path))
 		{
@@ -70,7 +111,7 @@
 			$this->_threshold_array = array_flip($config['log_threshold']);
 		}
 
-		if ($config['log_date_format'] != '')
+		if ($config['log_date_format'] !== '')
 		{
 			$this->_date_fmt = $config['log_date_format'];
 		}
@@ -98,7 +139,7 @@
 		$level = strtoupper($level);
 
 		if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
-			AND ! isset($this->_threshold_array[$this->_levels[$level]]))
+			&& ! isset($this->_threshold_array[$this->_levels[$level]]))
 		{
 			return FALSE;
 		}
@@ -110,7 +151,7 @@
 		if ( ! file_exists($filepath))
 		{
 			$newfile = TRUE;
-			$message .= "<"."?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); ?".">\n\n";
+			$message .= '<'."?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); ?".">\n\n";
 		}
 
 		if ( ! $fp = @fopen($filepath, FOPEN_WRITE_CREATE))
@@ -118,22 +159,22 @@
 			return FALSE;
 		}
 
-		$message .= $level.' '.(($level == 'INFO') ? ' -' : '-').' '.date($this->_date_fmt). ' --> '.$msg."\n";
+		$message .= $level.' '.($level === 'INFO' ? ' -' : '-').' '.date($this->_date_fmt).' --> '.$msg."\n";
 
 		flock($fp, LOCK_EX);
 		fwrite($fp, $message);
 		flock($fp, LOCK_UN);
 		fclose($fp);
 
-		if (isset($newfile) AND $newfile === TRUE)
+		if (isset($newfile) && $newfile === TRUE)
 		{
 			@chmod($filepath, FILE_WRITE_MODE);
 		}
+
 		return TRUE;
 	}
 
 }
-// END Log Class
 
 /* End of file Log.php */
-/* Location: ./system/libraries/Log.php */
+/* Location: ./system/libraries/Log.php */
\ No newline at end of file
diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php
index a18fcb9..4391b23 100644
--- a/system/libraries/Migration.php
+++ b/system/libraries/Migration.php
@@ -39,14 +39,54 @@
  */
 class CI_Migration {
 
+	/**
+	 * Whether the library is enabled
+	 *
+	 * @var bool
+	 */
 	protected $_migration_enabled = FALSE;
+
+	/**
+	 * Path to migration classes
+	 *
+	 * @var string
+	 */
 	protected $_migration_path = NULL;
+
+	/**
+	 * Current migration version
+	 *
+	 * @var mixed
+	 */
 	protected $_migration_version = 0;
+
+	/**
+	 * Database table with migration info
+	 *
+	 * @var string
+	 */
 	protected $_migration_table = 'migrations';
+
+	/**
+	 * Whether to automatically run migrations
+	 *
+	 * @var bool
+	 */
 	protected $_migration_auto_latest = FALSE;
 
+	/**
+	 * Error message
+	 *
+	 * @var string
+	 */
 	protected $_error_string = '';
 
+	/**
+	 * Initialize Migration Class
+	 *
+	 * @param	array
+	 * @return	void
+	 */
 	public function __construct($config = array())
 	{
 		# Only run this constructor on main library load
@@ -57,7 +97,7 @@
 
 		foreach ($config as $key => $val)
 		{
-			$this->{'_' . $key} = $val;
+			$this->{'_'.$key} = $val;
 		}
 
 		log_message('debug', 'Migrations class initialized');
@@ -69,7 +109,7 @@
 		}
 
 		// If not set, set it
-		$this->_migration_path != '' OR $this->_migration_path = APPPATH.'migrations/';
+		$this->_migration_path !== '' OR $this->_migration_path = APPPATH.'migrations/';
 
 		// Add trailing slash if not set
 		$this->_migration_path = rtrim($this->_migration_path, '/').'/';
@@ -139,7 +179,7 @@
 
 		// We now prepare to actually DO the migrations
 		// But first let's make sure that everything is the way it should be
-		for ($i = $start; $i != $stop; $i += $step)
+		for ($i = $start; $i !== $stop; $i += $step)
 		{
 			$f = glob(sprintf($this->_migration_path.'%03d_*.php', $i));
 
@@ -301,7 +341,6 @@
 		}
 
 		sort($files);
-
 		return $files;
 	}
 
@@ -345,6 +384,7 @@
 	{
 		return get_instance()->$var;
 	}
+
 }
 
 /* End of file Migration.php */
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index 0fe73d6..a91159c 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -73,6 +73,7 @@
 	 * Constructor
 	 *
 	 * @param	array	initialization parameters
+	 * @return	void
 	 */
 	public function __construct($params = array())
 	{
@@ -94,17 +95,16 @@
 		{
 			foreach ($params as $key => $val)
 			{
-				if (isset($this->$key))
+				if ($key === 'anchor_class')
+				{
+					$this->anchor_class = ($val !== '') ? 'class="'.$val.'" ' : '';
+				}
+				elseif (isset($this->$key))
 				{
 					$this->$key = $val;
 				}
 			}
 		}
-
-		if ($this->anchor_class != '')
-		{
-			$this->anchor_class = 'class="'.$this->anchor_class.'" ';
-		}
 	}
 
 	// --------------------------------------------------------------------
@@ -117,7 +117,7 @@
 	public function create_links()
 	{
 		// If our item count or per-page total is zero there is no need to continue.
-		if ($this->total_rows == 0 OR $this->per_page == 0)
+		if ($this->total_rows === 0 OR $this->per_page === 0)
 		{
 			return '';
 		}
@@ -138,25 +138,25 @@
 		$CI =& get_instance();
 
 		// See if we are using a prefix or suffix on links
-		if ($this->prefix != '' OR $this->suffix != '')
+		if ($this->prefix !== '' OR $this->suffix !== '')
 		{
 			$this->cur_page = (int) str_replace(array($this->prefix, $this->suffix), '', $CI->uri->segment($this->uri_segment));
 		}
 
 		if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
 		{
-			if ($CI->input->get($this->query_string_segment) != $base_page)
+			if ($CI->input->get($this->query_string_segment) !== $base_page)
 			{
 				$this->cur_page = (int) $CI->input->get($this->query_string_segment);
 			}
 		}
-		elseif ( ! $this->cur_page && $CI->uri->segment($this->uri_segment) != $base_page)
+		elseif ( ! $this->cur_page && $CI->uri->segment($this->uri_segment) !== $base_page)
 		{
 			$this->cur_page = (int) $CI->uri->segment($this->uri_segment);
 		}
 
 		// Set current page to 1 if it's not valid or if using page numbers instead of offset
-		if ( ! is_numeric($this->cur_page) OR ($this->use_page_numbers && $this->cur_page == 0))
+		if ( ! is_numeric($this->cur_page) OR ($this->use_page_numbers && $this->cur_page === 0))
 		{
 			$this->cur_page = $base_page;
 		}
@@ -211,22 +211,22 @@
 		// Render the "First" link
 		if ($this->first_link !== FALSE && $this->cur_page > ($this->num_links + 1))
 		{
-			$first_url = ($this->first_url == '') ? $this->base_url : $this->first_url;
+			$first_url = ($this->first_url === '') ? $this->base_url : $this->first_url;
 			$output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'.$first_url.'">'.$this->first_link.'</a>'.$this->first_tag_close;
 		}
 
 		// Render the "previous" link
-		if  ($this->prev_link !== FALSE && $this->cur_page != 1)
+		if  ($this->prev_link !== FALSE && $this->cur_page !== 1)
 		{
 			$i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page;
 
-			if ($i == $base_page && $this->first_url != '')
+			if ($i === $base_page && $this->first_url !== '')
 			{
 				$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
 			}
 			else
 			{
-				$i = ($i == $base_page) ? '' : $this->prefix.$i.$this->suffix;
+				$i = ($i === $base_page) ? '' : $this->prefix.$i.$this->suffix;
 				$output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close;
 			}
 
@@ -242,21 +242,21 @@
 
 				if ($i >= $base_page)
 				{
-					if ($this->cur_page == $loop)
+					if ($this->cur_page === $loop)
 					{
 						$output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
 					}
 					else
 					{
-						$n = ($i == $base_page) ? '' : $i;
+						$n = ($i === $base_page) ? '' : $i;
 
-						if ($n == '' && $this->first_url != '')
+						if ($n === '' && $this->first_url !== '')
 						{
 							$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$loop.'</a>'.$this->num_tag_close;
 						}
 						else
 						{
-							$n = ($n == '') ? '' : $this->prefix.$n.$this->suffix;
+							$n = ($n === '') ? '' : $this->prefix.$n.$this->suffix;
 
 							$output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close;
 						}
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index d1b5b76..b64c782 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -36,9 +36,25 @@
  */
 class CI_Parser {
 
+	/**
+	 * Left delimeter character for psuedo vars
+	 *
+	 * @var string
+	 */
 	public $l_delim = '{';
+
+	/**
+	 * Right delimeter character for psuedo vars
+	 *
+	 * @var string
+	 */
 	public $r_delim = '}';
-	public $object;
+
+	/**
+	 * Reference to CodeIgniter instance
+	 *
+	 * @var object
+	 */
 	protected $CI;
 
 	/**
@@ -93,24 +109,19 @@
 	 */
 	protected function _parse($template, $data, $return = FALSE)
 	{
-		if ($template == '')
+		if ($template === '')
 		{
 			return FALSE;
 		}
 
 		foreach ($data as $key => $val)
 		{
-			if (is_array($val))
-			{
-				$template = $this->_parse_pair($key, $val, $template);
-			}
-			else
-			{
-				$template = $this->_parse_single($key, (string)$val, $template);
-			}
+			$template = is_array($val)
+					? $this->_parse_pair($key, $val, $template)
+					: $template = $this->_parse_single($key, (string) $val, $template);
 		}
 
-		if ($return == FALSE)
+		if ($return === FALSE)
 		{
 			$this->CI->output->append_output($template);
 		}
@@ -173,14 +184,9 @@
 			$temp = $match[1];
 			foreach ($row as $key => $val)
 			{
-				if ( ! is_array($val))
-				{
-					$temp = $this->_parse_single($key, $val, $temp);
-				}
-				else
-				{
-					$temp = $this->_parse_pair($key, $val, $temp);
-				}
+				$temp = is_array($val)
+						? $this->_parse_pair($key, $val, $temp)
+						: $this->_parse_single($key, $val, $temp);
 			}
 
 			$str .= $temp;
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index d84e5d3..d96088c 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Profiler Class
  *
@@ -44,25 +42,45 @@
  */
 class CI_Profiler {
 
+	/**
+	 * List of profiler sections available to show
+	 *
+	 * @var array
+	 */
 	protected $_available_sections = array(
-										'benchmarks',
-										'get',
-										'memory_usage',
-										'post',
-										'uri_string',
-										'controller_info',
-										'queries',
-										'http_headers',
-										'session_data',
-										'config'
-										);
+		'benchmarks',
+		'get',
+		'memory_usage',
+		'post',
+		'uri_string',
+		'controller_info',
+		'queries',
+		'http_headers',
+		'session_data',
+		'config'
+	);
 
+	/**
+	 * Number of queries to show before making the additional queries togglable
+	 *
+	 * @var int
+	 */
 	protected $_query_toggle_count = 25;
 
+	/**
+	 * Reference to the CodeIgniter singleton
+	 *
+	 * @var object
+	 */
 	protected $CI;
 
-	// --------------------------------------------------------------------
-
+	/**
+	 * Constructor
+	 *
+	 * Initialize Profiler
+	 *
+	 * @param array $config
+	 */
 	public function __construct($config = array())
 	{
 		$this->CI =& get_instance();
@@ -102,7 +120,7 @@
 		{
 			if (in_array($method, $this->_available_sections))
 			{
-				$this->_compile_{$method} = ($enable !== FALSE) ? TRUE : FALSE;
+				$this->_compile_{$method} = ($enable !== FALSE);
 			}
 		}
 	}
@@ -127,7 +145,7 @@
 			// We match the "end" marker so that the list ends
 			// up in the order that it was defined
 			if (preg_match('/(.+?)_end/i', $key, $match)
-				AND isset($this->CI->benchmark->marker[$match[1].'_end'], $this->CI->benchmark->marker[$match[1].'_start']))
+				&& isset($this->CI->benchmark->marker[$match[1].'_end'], $this->CI->benchmark->marker[$match[1].'_start']))
 			{
 				$profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
 			}
@@ -135,18 +153,20 @@
 
 		// Build a table containing the profile data.
 		// Note: At some point we should turn this into a template that can
-		// be modified.  We also might want to make this data available to be logged
+		// be modified. We also might want to make this data available to be logged
 
 		$output = "\n\n"
-			. '<fieldset id="ci_profiler_benchmarks" style="border:1px solid #900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>'
-			. "\n\n\n<table style='width:100%'>\n";
+			.'<fieldset id="ci_profiler_benchmarks" style="border:1px solid #900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks')."&nbsp;&nbsp;</legend>"
+			."\n\n\n<table style=\"width:100%;\">\n";
 
 		foreach ($profile as $key => $val)
 		{
 			$key = ucwords(str_replace(array('_', '-'), ' ', $key));
-			$output .= "<tr><td style='padding:5px;width:50%;color:#000;font-weight:bold;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td style='padding:5px;width:50%;color:#900;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
+			$output .= '<tr><td style="padding:5px;width:50%;color:#000;font-weight:bold;background-color:#ddd;">'
+					.$key.'&nbsp;&nbsp;</td><td style="padding:5px;width:50%;color:#900;font-weight:normal;background-color:#ddd;">'
+					.$val."</td></tr>\n";
 		}
 
 		return $output."</table>\n</fieldset>";
@@ -166,7 +186,7 @@
 		// Let's determine which databases are currently connected to
 		foreach (get_object_vars($this->CI) as $CI_object)
 		{
-			if (is_object($CI_object) && is_subclass_of(get_class($CI_object), 'CI_DB') )
+			if (is_object($CI_object) && is_subclass_of(get_class($CI_object), 'CI_DB'))
 			{
 				$dbs[] = $CI_object;
 			}
@@ -175,13 +195,13 @@
 		if (count($dbs) === 0)
 		{
 			return "\n\n"
-				. '<fieldset id="ci_profiler_queries" style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
-				. "\n"
-				. '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>'
-				. "\n\n\n<table style='border:none; width:100%;'>\n"
-				. '<tr><td style="width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;">'
-				. $this->CI->lang->line('profiler_no_db')
-				. "</td></tr>\n</table>\n</fieldset>";
+				.'<fieldset id="ci_profiler_queries" style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+				."\n"
+				.'<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>'
+				."\n\n\n<table style=\"border:none; width:100%;\">\n"
+				.'<tr><td style="width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;">'
+				.$this->CI->lang->line('profiler_no_db')
+				."</td></tr>\n</table>\n</fieldset>";
 		}
 
 		// Load the text helper so we can highlight the SQL
@@ -191,7 +211,6 @@
 		$highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT&nbsp;JOIN', 'ORDER&nbsp;BY', 'GROUP&nbsp;BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR&nbsp;', 'HAVING', 'OFFSET', 'NOT&nbsp;IN', 'IN', 'LIKE', 'NOT&nbsp;LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')');
 
 		$output  = "\n\n";
-
 		$count = 0;
 
 		foreach ($dbs as $db)
@@ -200,26 +219,28 @@
 
 			$show_hide_js = '(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_queries_db_'.$count.'\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_hide').'\'?\''.$this->CI->lang->line('profiler_section_show').'\':\''.$this->CI->lang->line('profiler_section_hide').'\';">'.$this->CI->lang->line('profiler_section_hide').'</span>)';
 
-			if ($hide_queries != '')
+			if ($hide_queries !== '')
 			{
 				$show_hide_js = '(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_queries_db_'.$count.'\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)';
 			}
 
-			$output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-				. "\n"
-				. '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database').':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').': '.count($db->queries).'&nbsp;&nbsp;'.$show_hide_js.'</legend>'
-				. "\n\n\n<table style='width:100%;{$hide_queries}' id='ci_profiler_queries_db_{$count}'>\n";
+			$output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+				."\n"
+				.'<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_database')
+				.':&nbsp; '.$db->database.'&nbsp;&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries')
+				.': '.count($db->queries).'&nbsp;&nbsp;'.$show_hide_js."</legend>\n\n\n"
+				.'<table style="width:100%;'.$hide_queries.'" id="ci_profiler_queries_db_'.$count."\">\n";
 
 			if (count($db->queries) === 0)
 			{
-				$output .= "<tr><td style='width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";
+				$output .= '<tr><td style="width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;">'
+						.$this->CI->lang->line('profiler_no_queries')."</td></tr>\n";
 			}
 			else
 			{
 				foreach ($db->queries as $key => $val)
 				{
 					$time = number_format($db->query_times[$key], 4);
-
 					$val = highlight_code($val, ENT_QUOTES);
 
 					foreach ($highlight as $bold)
@@ -227,18 +248,18 @@
 						$val = str_replace($bold, '<strong>'.$bold.'</strong>', $val);
 					}
 
-					$output .= "<tr><td style='padding:5px; vertical-align: top;width:1%;color:#900;font-weight:normal;background-color:#ddd;'>".$time."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n";
+					$output .= '<tr><td style="padding:5px;vertical-align:top;width:1%;color:#900;font-weight:normal;background-color:#ddd;">'
+							.$time.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;font-weight:normal;background-color:#ddd;">'
+							.$val."</td></tr>\n";
 				}
 			}
 
 			$output .= "</table>\n</fieldset>";
-
 		}
 
 		return $output;
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
@@ -248,19 +269,18 @@
 	 */
 	protected function _compile_get()
 	{
-		$output  = "\n\n"
-			. '<fieldset id="ci_profiler_get" style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>'
-			. "\n";
+		$output = "\n\n"
+			.'<fieldset id="ci_profiler_get" style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data')."&nbsp;&nbsp;</legend>\n";
 
 		if (count($_GET) === 0)
 		{
-			$output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>";
+			$output .= '<div style="color:#cd6e00;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->lang->line('profiler_no_get').'</div>';
 		}
 		else
 		{
-			$output .= "\n\n<table style='width:100%; border:none'>\n";
+			$output .= "\n\n<table style=\"width:100%;border:none;\">\n";
 
 			foreach ($_GET as $key => $val)
 			{
@@ -269,9 +289,10 @@
 					$key = "'".$key."'";
 				}
 
-				$output .= "<tr><td style='width:50%;color:#000;background-color:#ddd;padding:5px'>&#36;_GET[".$key."]&nbsp;&nbsp; </td><td style='width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;'>"
-					. ((is_array($val) OR is_object($val)) ? "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>" : htmlspecialchars(stripslashes($val)))
-					. "</td></tr>\n";
+				$output .= '<tr><td style="width:50%;color:#000;background-color:#ddd;padding:5px;">&#36;_GET['
+					.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;">'
+					.((is_array($val) OR is_object($val)) ? '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>' : htmlspecialchars(stripslashes($val)))
+					."</td></tr>\n";
 			}
 
 			$output .= "</table>\n";
@@ -290,18 +311,17 @@
 	protected function _compile_post()
 	{
 		$output = "\n\n"
-			. '<fieldset id="ci_profiler_post" style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>'
-			. "\n";
+			.'<fieldset id="ci_profiler_post" style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data')."&nbsp;&nbsp;</legend>\n";
 
-		if (count($_POST) == 0)
+		if (count($_POST) === 0)
 		{
-			$output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>";
+			$output .= '<div style="color:#009900;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->lang->line('profiler_no_post').'</div>';
 		}
 		else
 		{
-			$output .= "\n\n<table style='width:100%'>\n";
+			$output .= "\n\n<table style=\"width:100%;\">\n";
 
 			foreach ($_POST as $key => $val)
 			{
@@ -310,15 +330,18 @@
 					$key = "'".$key."'";
 				}
 
-				$output .= "<tr><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>&#36;_POST[".$key."]&nbsp;&nbsp; </td><td style='width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;'>";
+				$output .= '<tr><td style="width:50%;padding:5px;color:#000;background-color:#ddd;">&#36;_POST['
+					.$key.']&nbsp;&nbsp; </td><td style="width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;">';
+
 				if (is_array($val) OR is_object($val))
 				{
-					$output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, TRUE))) . "</pre>";
+					$output .= '<pre>'.htmlspecialchars(stripslashes(print_r($val, TRUE))).'</pre>';
 				}
 				else
 				{
 					$output .= htmlspecialchars(stripslashes($val));
 				}
+
 				$output .= "</td></tr>\n";
 			}
 
@@ -338,12 +361,12 @@
 	protected function _compile_uri_string()
 	{
 		return "\n\n"
-			. '<fieldset id="ci_profiler_uri_string" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>'
-			. "\n<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>"
-			. ($this->CI->uri->uri_string == '' ? $this->CI->lang->line('profiler_no_uri') : $this->CI->uri->uri_string)
-			. '</div></fieldset>';
+			.'<fieldset id="ci_profiler_uri_string" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string')."&nbsp;&nbsp;</legend>\n"
+			.'<div style="color:#000;font-weight:normal;padding:4px 0 4px 0;">'
+			.($this->CI->uri->uri_string === '' ? $this->CI->lang->line('profiler_no_uri') : $this->CI->uri->uri_string)
+			.'</div></fieldset>';
 	}
 
 	// --------------------------------------------------------------------
@@ -356,11 +379,11 @@
 	protected function _compile_controller_info()
 	{
 		return "\n\n"
-			. '<fieldset id="ci_profiler_controller_info" style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info').'&nbsp;&nbsp;</legend>'
-			. "\n<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class().'/'.$this->CI->router->fetch_method()
-			. '</div></fieldset>';
+			.'<fieldset id="ci_profiler_controller_info" style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info')."&nbsp;&nbsp;</legend>\n"
+			.'<div style="color:#995300;font-weight:normal;padding:4px 0 4px 0;">'.$this->CI->router->fetch_class().'/'.$this->CI->router->fetch_method()
+			.'</div></fieldset>';
 	}
 
 	// --------------------------------------------------------------------
@@ -375,12 +398,12 @@
 	protected function _compile_memory_usage()
 	{
 		return "\n\n"
-			. '<fieldset id="ci_profiler_memory_usage" style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>'
-			. "\n<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>"
-			. ((function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '') ? number_format($usage).' bytes' : $this->CI->lang->line('profiler_no_memory'))
-			. '</div></fieldset>';
+			.'<fieldset id="ci_profiler_memory_usage" style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage')."&nbsp;&nbsp;</legend>\n"
+			.'<div style="color:#5a0099;font-weight:normal;padding:4px 0 4px 0;">'
+			.(($usage = memory_get_usage()) != '' ? number_format($usage).' bytes' : $this->CI->lang->line('profiler_no_memory'))
+			.'</div></fieldset>';
 	}
 
 	// --------------------------------------------------------------------
@@ -395,15 +418,17 @@
 	protected function _compile_http_headers()
 	{
 		$output = "\n\n"
-			. '<fieldset id="ci_profiler_http_headers" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_headers').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_httpheaders_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
-			. "\n\n\n<table style='width:100%;display:none' id='ci_profiler_httpheaders_table'>\n";
+			.'<fieldset id="ci_profiler_http_headers" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_headers')
+			.'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_httpheaders_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show')."</span>)</legend>\n\n\n"
+			.'<table style="width:100%;display:none;" id="ci_profiler_httpheaders_table">'."\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)
 		{
-			$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";
+			$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";
 		}
 
 		return $output."</table>\n</fieldset>";
@@ -421,10 +446,10 @@
 	protected function _compile_config()
 	{
 		$output = "\n\n"
-			. '<fieldset id="ci_profiler_config" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. "\n"
-			. '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_config').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_config_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
-			. "\n\n\n<table style='width:100%; display:none' id='ci_profiler_config_table'>\n";
+			.'<fieldset id="ci_profiler_config" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			."\n"
+			.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_config').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_config_table\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show')."</span>)</legend>\n\n\n"
+			.'<table style="width:100%;display:none;" id="ci_profiler_config_table">'."\n";
 
 		foreach ($this->CI->config->config as $config => $val)
 		{
@@ -433,7 +458,8 @@
 				$val = print_r($val, TRUE);
 			}
 
-			$output .= "<tr><td style='padding:5px; vertical-align: top;color:#900;background-color:#ddd;'>".$config."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;background-color:#ddd;'>".htmlspecialchars($val)."</td></tr>\n";
+			$output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">'
+				.$config.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;background-color:#ddd;">'.htmlspecialchars($val)."</td></tr>\n";
 		}
 
 		return $output."</table>\n</fieldset>";
@@ -453,9 +479,9 @@
 			return;
 		}
 
-		$output = '<fieldset id="ci_profiler_csession" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'
-			. '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_session_data').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_session_data\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
-			. "<table style='width:100%;display:none' id='ci_profiler_session_data'>";
+		$output = '<fieldset id="ci_profiler_csession" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee;">'
+			.'<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_session_data').'&nbsp;&nbsp;(<span style="cursor: pointer;" onclick="var s=document.getElementById(\'ci_profiler_session_data\').style;s.display=s.display==\'none\'?\'\':\'none\';this.innerHTML=this.innerHTML==\''.$this->CI->lang->line('profiler_section_show').'\'?\''.$this->CI->lang->line('profiler_section_hide').'\':\''.$this->CI->lang->line('profiler_section_show').'\';">'.$this->CI->lang->line('profiler_section_show').'</span>)</legend>'
+			.'<table style="width:100%;display:none;" id="ci_profiler_session_data">';
 
 		foreach ($this->CI->session->all_userdata() as $key => $val)
 		{
@@ -464,7 +490,8 @@
 				$val = print_r($val, TRUE);
 			}
 
-			$output .= "<tr><td style='padding:5px; vertical-align: top;color:#900;background-color:#ddd;'>".$key."&nbsp;&nbsp;</td><td style='padding:5px; color:#000;background-color:#ddd;'>".htmlspecialchars($val)."</td></tr>\n";
+			$output .= '<tr><td style="padding:5px;vertical-align:top;color:#900;background-color:#ddd;">'
+				.$key.'&nbsp;&nbsp;</td><td style="padding:5px;color:#000;background-color:#ddd;">'.htmlspecialchars($val)."</td></tr>\n";
 		}
 
 		return $output."</table>\n</fieldset>";
@@ -479,14 +506,14 @@
 	 */
 	public function run()
 	{
-		$output = "<div id='codeigniter_profiler' style='clear:both;background-color:#fff;padding:10px;'>";
+		$output = '<div id="codeigniter_profiler" style="clear:both;background-color:#fff;padding:10px;">';
 		$fields_displayed = 0;
 
 		foreach ($this->_available_sections as $section)
 		{
 			if ($this->_compile_{$section} !== FALSE)
 			{
-				$func = "_compile_{$section}";
+				$func = '_compile_'.$section;
 				$output .= $this->{$func}();
 				$fields_displayed++;
 			}
@@ -494,12 +521,14 @@
 
 		if ($fields_displayed === 0)
 		{
-			$output .= '<p style="border:1px solid #5a0099;padding:10px;margin:20px 0;background-color:#eee">'.$this->CI->lang->line('profiler_no_profiles').'</p>';
+			$output .= '<p style="border:1px solid #5a0099;padding:10px;margin:20px 0;background-color:#eee;">'
+				.$this->CI->lang->line('profiler_no_profiles').'</p>';
 		}
 
 		return $output.'</div>';
 	}
+
 }
 
 /* End of file Profiler.php */
-/* Location: ./system/libraries/Profiler.php */
+/* Location: ./system/libraries/Profiler.php */
\ No newline at end of file
diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 3a80c16..7beedd9 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -36,26 +36,151 @@
  */
 class CI_Session {
 
+	/**
+	 * Whether to encrypt the session cookie
+	 *
+	 * @var bool
+	 */
 	public $sess_encrypt_cookie		= FALSE;
+
+	/**
+	 * Whether to use to the database for session storage
+	 *
+	 * @var bool
+	 */
 	public $sess_use_database		= FALSE;
+
+	/**
+	 * Name of the database table in which to store sessions
+	 *
+	 * @var string
+	 */
 	public $sess_table_name			= '';
+
+	/**
+	 * Length of time (in seconds) for sessions to expire
+	 *
+	 * @var int
+	 */
 	public $sess_expiration			= 7200;
+
+	/**
+	 * Whether to kill session on close of browser window
+	 *
+	 * @var bool
+	 */
 	public $sess_expire_on_close		= FALSE;
+
+	/**
+	 * Whether to match session on ip address
+	 *
+	 * @var bool
+	 */
 	public $sess_match_ip			= FALSE;
+
+	/**
+	 * Whether to match session on user-agent
+	 *
+	 * @var bool
+	 */
 	public $sess_match_useragent		= TRUE;
+
+	/**
+	 * Name of session cookie
+	 *
+	 * @var string
+	 */
 	public $sess_cookie_name		= 'ci_session';
+
+	/**
+	 * Session cookie prefix
+	 *
+	 * @var string
+	 */
 	public $cookie_prefix			= '';
+
+	/**
+	 * Session cookie path
+	 *
+	 * @var string
+	 */
 	public $cookie_path			= '';
+
+	/**
+	 * Session cookie domain
+	 *
+	 * @var string
+	 */
 	public $cookie_domain			= '';
+
+	/**
+	 * Whether to set the cookie only on HTTPS connections
+	 *
+	 * @var bool
+	 */
 	public $cookie_secure			= FALSE;
+
+	/**
+	 * Whether cookie should be allowed only to be sent by the server
+	 *
+	 * @var bool
+	 */
 	public $cookie_httponly 		= FALSE;
+
+	/**
+	 * Interval at which to update session
+	 *
+	 * @var int
+	 */
 	public $sess_time_to_update		= 300;
+
+	/**
+	 * Key with which to encrypt the session cookie
+	 *
+	 * @var string
+	 */
 	public $encryption_key			= '';
+
+	/**
+	 * String to indicate flash data cookies
+	 *
+	 * @var string
+	 */
 	public $flashdata_key			= 'flash';
+
+	/**
+	 * Function to use to get the current time
+	 *
+	 * @var string
+	 */
 	public $time_reference			= 'time';
+
+	/**
+	 * Probablity level of garbage collection of old sessions
+	 *
+	 * @var int
+	 */
 	public $gc_probability			= 5;
+
+	/**
+	 * Session data
+	 *
+	 * @var array
+	 */
 	public $userdata			= array();
+
+	/**
+	 * Reference to CodeIgniter instance
+	 *
+	 * @var object
+	 */
 	public $CI;
+
+	/**
+	 * Current time
+	 *
+	 * @var int
+	 */
 	public $now;
 
 	/**
@@ -63,6 +188,9 @@
 	 *
 	 * The constructor runs the session routines automatically
 	 * whenever the class is instantiated.
+	 *
+	 * @param	array
+	 * @return	void
 	 */
 	public function __construct($params = array())
 	{
@@ -78,7 +206,7 @@
 			$this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key);
 		}
 
-		if ($this->encryption_key == '')
+		if ($this->encryption_key === '')
 		{
 			show_error('In order to use the Session class you are required to set an encryption key in your config file.');
 		}
@@ -87,13 +215,13 @@
 		$this->CI->load->helper('string');
 
 		// Do we need encryption? If so, load the encryption class
-		if ($this->sess_encrypt_cookie == TRUE)
+		if ($this->sess_encrypt_cookie === TRUE)
 		{
 			$this->CI->load->library('encrypt');
 		}
 
 		// Are we using a database? If so, load it
-		if ($this->sess_use_database === TRUE && $this->sess_table_name != '')
+		if ($this->sess_use_database === TRUE && $this->sess_table_name !== '')
 		{
 			$this->CI->load->database();
 		}
@@ -104,7 +232,7 @@
 
 		// Set the session length. If the session expiration is
 		// set to zero we'll set the expiration two years from now.
-		if ($this->sess_expiration == 0)
+		if ($this->sess_expiration === 0)
 		{
 			$this->sess_expiration = (60*60*24*365*2);
 		}
@@ -148,14 +276,14 @@
 		$session = $this->CI->input->cookie($this->sess_cookie_name);
 
 		// No cookie?  Goodbye cruel world!...
-		if ($session === FALSE)
+		if ($session === NULL)
 		{
 			log_message('debug', 'A session cookie was not found.');
 			return FALSE;
 		}
 
 		// Decrypt the cookie data
-		if ($this->sess_encrypt_cookie == TRUE)
+		if ($this->sess_encrypt_cookie === TRUE)
 		{
 			$session = $this->CI->encrypt->decode($session);
 		}
@@ -192,14 +320,14 @@
 		}
 
 		// Does the IP match?
-		if ($this->sess_match_ip == TRUE && $session['ip_address'] !== $this->CI->input->ip_address())
+		if ($this->sess_match_ip === TRUE && $session['ip_address'] !== $this->CI->input->ip_address())
 		{
 			$this->sess_destroy();
 			return FALSE;
 		}
 
 		// Does the User Agent Match?
-		if ($this->sess_match_useragent == TRUE && trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
+		if ($this->sess_match_useragent === TRUE && trim($session['user_agent']) !== trim(substr($this->CI->input->user_agent(), 0, 120)))
 		{
 			$this->sess_destroy();
 			return FALSE;
@@ -210,12 +338,12 @@
 		{
 			$this->CI->db->where('session_id', $session['session_id']);
 
-			if ($this->sess_match_ip == TRUE)
+			if ($this->sess_match_ip === TRUE)
 			{
 				$this->CI->db->where('ip_address', $session['ip_address']);
 			}
 
-			if ($this->sess_match_useragent == TRUE)
+			if ($this->sess_match_useragent === TRUE)
 			{
 				$this->CI->db->where('user_agent', $session['user_agent']);
 			}
@@ -231,7 +359,7 @@
 
 			// Is there custom data?  If so, add it to the main session array
 			$row = $query->row();
-			if (isset($row->user_data) && $row->user_data != '')
+			if ( ! empty($row->user_data))
 			{
 				$custom_data = $this->_unserialize($row->user_data);
 
@@ -443,6 +571,9 @@
 				$this->cookie_domain,
 				0
 			);
+
+		// Kill session data
+		$this->userdata = array();
 	}
 
 	// --------------------------------------------------------------------
@@ -455,7 +586,7 @@
 	 */
 	public function userdata($item)
 	{
-		return isset($this->userdata[$item]) ? $this->userdata[$item] : FALSE;
+		return isset($this->userdata[$item]) ? $this->userdata[$item] : NULL;
 	}
 
 	// --------------------------------------------------------------------
@@ -469,21 +600,21 @@
 	{
 		return $this->userdata;
 	}
-	
+
 	// --------------------------------------------------------------------------
-	
+
 	/**
 	 * Fetch all flashdata
-	 * 
+	 *
 	 * @return	array
 	 */
 	public function all_flashdata()
 	{
 		$out = array();
-		
+
 		// loop through all userdata
 		foreach ($this->all_userdata() as $key => $val)
-		{	
+		{
 			// if it contains flashdata, add it
 			if (strpos($key, 'flash:old:') !== FALSE)
 			{
@@ -525,6 +656,7 @@
 	/**
 	 * Delete a session variable from the "userdata" array
 	 *
+	 * @param	array
 	 * @return	void
 	 */
 	public function unset_userdata($newdata = array())
@@ -583,7 +715,7 @@
 	{
 		// 'old' flashdata gets removed. Here we mark all
 		// flashdata as 'new' to preserve it from _flashdata_sweep()
-		// Note the function will return FALSE if the $key
+		// Note the function will return NULL if the $key
 		// provided cannot be found
 		$value = $this->userdata($this->flashdata_key.':old:'.$key);
 
@@ -664,6 +796,7 @@
 	/**
 	 * Write the session cookie
 	 *
+	 * @param	mixed
 	 * @return	void
 	 */
 	protected function _set_cookie($cookie_data = NULL)
@@ -676,7 +809,7 @@
 		// Serialize the userdata for the cookie
 		$cookie_data = $this->_serialize($cookie_data);
 
-		if ($this->sess_encrypt_cookie == TRUE)
+		if ($this->sess_encrypt_cookie === TRUE)
 		{
 			$cookie_data = $this->CI->encrypt->encode($cookie_data);
 		}
@@ -796,7 +929,7 @@
 	 */
 	protected function _sess_gc()
 	{
-		if ($this->sess_use_database != TRUE)
+		if ($this->sess_use_database !== TRUE)
 		{
 			return;
 		}
@@ -816,4 +949,4 @@
 }
 
 /* End of file Session.php */
-/* Location: ./system/libraries/Session.php */
+/* Location: ./system/libraries/Session.php */
\ No newline at end of file
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index 11a4858..0f8404d 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -38,14 +38,61 @@
  */
 class CI_Table {
 
-	public $rows			= array();
-	public $heading			= array();
-	public $auto_heading		= TRUE;
-	public $caption			= NULL;
-	public $template		= NULL;
-	public $newline			= "\n";
-	public $empty_cells		= '';
-	public $function		= FALSE;
+	/**
+	 * Data for table rows
+	 *
+	 * @var array
+	 */
+	public $rows		= array();
+
+	/**
+	 * Data for table heading
+	 *
+	 * @var array
+	 */
+	public $heading		= array();
+
+	/**
+	 * Whether or not to automatically create the table header
+	 *
+	 * @var bool
+	 */
+	public $auto_heading	= TRUE;
+
+	/**
+	 * Table caption
+	 *
+	 * @var string
+	 */
+	public $caption		= NULL;
+
+	/**
+	 * Table layout template
+	 *
+	 * @var array
+	 */
+	public $template	= NULL;
+
+	/**
+	 * Newline setting
+	 *
+	 * @var string
+	 */
+	public $newline		= "\n";
+
+	/**
+	 * Contents of empty cells
+	 *
+	 * @var string
+	 */
+	public $empty_cells	= '';
+
+	/**
+	 * Callback for custom table layout
+	 *
+	 * @var function
+	 */
+	public $function	= FALSE;
 
 	/**
 	 * Set the template from the table config file if it exists
@@ -55,13 +102,13 @@
 	 */
 	public function __construct($config = array())
 	{
-		log_message('debug', 'Table Class Initialized');
-
 		// initialize config
 		foreach ($config as $key => $val)
 		{
 			$this->template[$key] = $val;
 		}
+
+		log_message('debug', 'Table Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -70,7 +117,7 @@
 	 * Set the template
 	 *
 	 * @param	array
-	 * @return	void
+	 * @return	bool
 	 */
 	public function set_template($template)
 	{
@@ -80,6 +127,7 @@
 		}
 
 		$this->template = $template;
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -92,7 +140,7 @@
 	 * @param	mixed
 	 * @return	void
 	 */
-	public function set_heading()
+	public function set_heading($args = array())
 	{
 		$args = func_get_args();
 		$this->heading = $this->_prep_args($args);
@@ -101,9 +149,9 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Set columns.  Takes a one-dimensional array as input and creates
+	 * Set columns. Takes a one-dimensional array as input and creates
 	 * a multi-dimensional array with a depth equal to the number of
-	 * columns.  This allows a single array with many elements to  be
+	 * columns. This allows a single array with many elements to be
 	 * displayed in a table that has a fixed column count.
 	 *
 	 * @param	array
@@ -121,7 +169,7 @@
 		// will want headings from a one-dimensional array
 		$this->auto_heading = FALSE;
 
-		if ($col_limit == 0)
+		if ($col_limit === 0)
 		{
 			return $array;
 		}
@@ -171,7 +219,7 @@
 	 * @param	mixed
 	 * @return	void
 	 */
-	public function add_row()
+	public function add_row($args = array())
 	{
 		$args = func_get_args();
 		$this->rows[] = $this->_prep_args($args);
@@ -184,29 +232,22 @@
 	 *
 	 * Ensures a standard associative array format for all cell data
 	 *
-	 * @param	type
-	 * @return	type
+	 * @param	array
+	 * @return	array
 	 */
 	protected function _prep_args($args)
 	{
 		// If there is no $args[0], skip this and treat as an associative array
 		// This can happen if there is only a single key, for example this is passed to table->generate
 		// array(array('foo'=>'bar'))
-		if (isset($args[0]) AND (count($args) === 1 && is_array($args[0])))
+		if (isset($args[0]) && count($args) === 1 && is_array($args[0]))
 		{
 			// args sent as indexed array
 			if ( ! isset($args[0]['data']))
 			{
 				foreach ($args[0] as $key => $val)
 				{
-					if (is_array($val) && isset($val['data']))
-					{
-						$args[$key] = $val;
-					}
-					else
-					{
-						$args[$key] = array('data' => $val);
-					}
+					$args[$key] = (is_array($val) && isset($val['data'])) ? $val : array('data' => $val);
 				}
 			}
 		}
@@ -257,13 +298,13 @@
 			}
 			elseif (is_array($table_data))
 			{
-				$set_heading = (count($this->heading) === 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE;
+				$set_heading = (count($this->heading) !== 0 OR $this->auto_heading !== FALSE);
 				$this->_set_from_array($table_data, $set_heading);
 			}
 		}
 
-		// Is there anything to display?  No?  Smite them!
-		if (count($this->heading) === 0 AND count($this->rows) === 0)
+		// Is there anything to display? No? Smite them!
+		if (count($this->heading) === 0 && count($this->rows) === 0)
 		{
 			return 'Undefined table data';
 		}
@@ -295,9 +336,9 @@
 
 				foreach ($heading as $key => $val)
 				{
-					if ($key != 'data')
+					if ($key !== 'data')
 					{
-						$temp = str_replace('<th', "<th $key='$val'", $temp);
+						$temp = str_replace('<th', '<th '.$key.'="'.$val.'"', $temp);
 					}
 				}
 
@@ -321,7 +362,7 @@
 				}
 
 				// We use modulus to alternate the row colors
-				$name = (fmod($i++, 2)) ? '' : 'alt_';
+				$name = fmod($i++, 2) ? '' : 'alt_';
 
 				$out .= $this->template['row_'.$name.'start'].$this->newline;
 
@@ -333,27 +374,24 @@
 					{
 						if ($key !== 'data')
 						{
-							$temp = str_replace('<td', "<td $key='$val'", $temp);
+							$temp = str_replace('<td', '<td '.$key.'="'.$val.'"', $temp);
 						}
 					}
 
 					$cell = isset($cell['data']) ? $cell['data'] : '';
 					$out .= $temp;
 
-					if ($cell === "" OR $cell === NULL)
+					if ($cell === '' OR $cell === NULL)
 					{
 						$out .= $this->empty_cells;
 					}
+					elseif ($function !== FALSE && is_callable($function))
+					{
+						$out .= call_user_func($function, $cell);
+					}
 					else
 					{
-						if ($function !== FALSE && is_callable($function))
-						{
-							$out .= call_user_func($function, $cell);
-						}
-						else
-						{
-							$out .= $cell;
-						}
+						$out .= $cell;
 					}
 
 					$out .= $this->template['cell_'.$name.'end'];
@@ -382,9 +420,9 @@
 	 */
 	public function clear()
 	{
-		$this->rows				= array();
-		$this->heading			= array();
-		$this->auto_heading		= TRUE;
+		$this->rows		= array();
+		$this->heading		= array();
+		$this->auto_heading	= TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -399,7 +437,7 @@
 	{
 		if ( ! is_object($query))
 		{
-			return FALSE;
+			return;
 		}
 
 		// First generate the headings from the table column names
@@ -407,14 +445,13 @@
 		{
 			if ( ! is_callable(array($query, 'list_fields')))
 			{
-				return FALSE;
+				return;
 			}
 
 			$this->heading = $this->_prep_args($query->list_fields());
 		}
 
 		// Next blast through the result array and build out the rows
-
 		if ($query->num_rows() > 0)
 		{
 			foreach ($query->result_array() as $row)
@@ -430,6 +467,7 @@
 	 * Set table data from an array
 	 *
 	 * @param	array
+	 * @param	bool
 	 * @return	void
 	 */
 	protected function _set_from_array($data, $set_heading = TRUE)
@@ -443,7 +481,7 @@
 		foreach ($data as $row)
 		{
 			// If a heading hasn't already been set we'll use the first row of the array as the heading
-			if ($i++ === 0 AND count($data) > 1 AND count($this->heading) === 0 AND $set_heading == TRUE)
+			if ($i++ === 0 && count($data) > 1 && count($this->heading) === 0 && $set_heading === TRUE)
 			{
 				$this->heading = $this->_prep_args($row);
 			}
@@ -463,7 +501,7 @@
 	 */
 	protected function _compile_template()
 	{
-		if ($this->template == NULL)
+		if ($this->template === NULL)
 		{
 			$this->template = $this->_default_template();
 			return;
@@ -488,36 +526,35 @@
 	 */
 	protected function _default_template()
 	{
-		return  array (
-						'table_open'			=> '<table border="0" cellpadding="4" cellspacing="0">',
+		return  array(
+				'table_open'		=> '<table border="0" cellpadding="4" cellspacing="0">',
 
-						'thead_open'			=> '<thead>',
-						'thead_close'			=> '</thead>',
+				'thead_open'		=> '<thead>',
+				'thead_close'		=> '</thead>',
 
-						'heading_row_start'		=> '<tr>',
-						'heading_row_end'		=> '</tr>',
-						'heading_cell_start'	=> '<th>',
-						'heading_cell_end'		=> '</th>',
+				'heading_row_start'	=> '<tr>',
+				'heading_row_end'	=> '</tr>',
+				'heading_cell_start'	=> '<th>',
+				'heading_cell_end'	=> '</th>',
 
-						'tbody_open'			=> '<tbody>',
-						'tbody_close'			=> '</tbody>',
+				'tbody_open'		=> '<tbody>',
+				'tbody_close'		=> '</tbody>',
 
-						'row_start'				=> '<tr>',
-						'row_end'				=> '</tr>',
-						'cell_start'			=> '<td>',
-						'cell_end'				=> '</td>',
+				'row_start'		=> '<tr>',
+				'row_end'		=> '</tr>',
+				'cell_start'		=> '<td>',
+				'cell_end'		=> '</td>',
 
-						'row_alt_start'		=> '<tr>',
-						'row_alt_end'			=> '</tr>',
-						'cell_alt_start'		=> '<td>',
-						'cell_alt_end'			=> '</td>',
+				'row_alt_start'		=> '<tr>',
+				'row_alt_end'		=> '</tr>',
+				'cell_alt_start'	=> '<td>',
+				'cell_alt_end'		=> '</td>',
 
-						'table_close'			=> '</table>'
-					);
+				'table_close'		=> '</table>'
+			);
 	}
 
-
 }
 
 /* End of file Table.php */
-/* Location: ./system/libraries/Table.php */
+/* Location: ./system/libraries/Table.php */
\ No newline at end of file
diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php
index be1de6f..9a680dc 100644
--- a/system/libraries/Trackback.php
+++ b/system/libraries/Trackback.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Trackback Class
  *
@@ -49,7 +47,7 @@
 
 	public function __construct()
 	{
-		log_message('debug', "Trackback Class Initialized");
+		log_message('debug', 'Trackback Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -90,16 +88,17 @@
 			}
 
 			// Convert High ASCII Characters
-			if ($this->convert_ascii == TRUE && in_array($item, array('excerpt', 'title', 'blog_name')))
+			if ($this->convert_ascii === TRUE && in_array($item, array('excerpt', 'title', 'blog_name')))
 			{
 				$$item = $this->convert_ascii($$item);
 			}
 		}
 
 		// Build the Trackback data string
-		$charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset'];
+		$charset = isset($tb_data['charset']) ? $tb_data['charset'] : $this->charset;
 
-		$data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset);
+		$data = 'url='.rawurlencode($url).'&title='.rawurlencode($title).'&blog_name='.rawurlencode($blog_name)
+			.'&excerpt='.rawurlencode($excerpt).'&charset='.rawurlencode($charset);
 
 		// Send Trackback(s)
 		$return = TRUE;
@@ -107,7 +106,7 @@
 		{
 			foreach ($ping_url as $url)
 			{
-				if ($this->process($url, $data) == FALSE)
+				if ($this->process($url, $data) === FALSE)
 				{
 					$return = FALSE;
 				}
@@ -133,22 +132,22 @@
 	{
 		foreach (array('url', 'title', 'blog_name', 'excerpt') as $val)
 		{
-			if ( ! isset($_POST[$val]) OR $_POST[$val] == '')
+			if (empty($_POST[$val]))
 			{
 				$this->set_error('The following required POST variable is missing: '.$val);
 				return FALSE;
 			}
 
-			$this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset']));
+			$this->data['charset'] = isset($_POST['charset']) ? strtoupper(trim($_POST['charset'])) : 'auto';
 
-			if ($val != 'url' && MB_ENABLED === TRUE)
+			if ($val !== 'url' && MB_ENABLED === TRUE)
 			{
 				$_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']);
 			}
 
-			$_POST[$val] = ($val != 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]);
+			$_POST[$val] = ($val !== 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]);
 
-			if ($val == 'excerpt')
+			if ($val === 'excerpt')
 			{
 				$_POST['excerpt'] = $this->limit_characters($_POST['excerpt']);
 			}
@@ -164,7 +163,7 @@
 	/**
 	 * Send Trackback Error Message
 	 *
-	 * Allows custom errors to be set.  By default it
+	 * Allows custom errors to be set. By default it
 	 * sends the "incomplete information" error, as that's
 	 * the most common one.
 	 *
@@ -173,7 +172,7 @@
 	 */
 	public function send_error($message = 'Incomplete Information')
 	{
-		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>";
+		echo '<?xml version="1.0" encoding="utf-8"?'.">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>";
 		exit;
 	}
 
@@ -189,7 +188,7 @@
 	 */
 	public function send_success()
 	{
-		echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>0</error>\n</response>";
+		echo '<?xml version="1.0" encoding="utf-8"?'.">\n<response>\n<error>0</error>\n</response>";
 		exit;
 	}
 
@@ -203,7 +202,7 @@
 	 */
 	public function data($item)
 	{
-		return ( ! isset($this->data[$item])) ? '' : $this->data[$item];
+		return isset($this->data[$item]) ? $this->data[$item] : '';
 	}
 
 	// --------------------------------------------------------------------
@@ -212,7 +211,7 @@
 	 * Process Trackback
 	 *
 	 * Opens a socket connection and passes the data to
-	 * the server.  Returns TRUE on success, FALSE on failure
+	 * the server. Returns TRUE on success, FALSE on failure
 	 *
 	 * @param	string
 	 * @param	string
@@ -230,37 +229,36 @@
 		}
 
 		// Build the path
-		$ppath = ( ! isset($target['path'])) ? $url : $target['path'];
+		$ppath = isset($target['path']) ? $target['path'] : $url;
 
-		$path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath;
+		$path = empty($target['query']) ? $ppath : $ppath.'?'.$target['query'];
 
 		// Add the Trackback ID to the data string
 		if ($id = $this->get_id($url))
 		{
-			$data = "tb_id=".$id."&".$data;
+			$data = 'tb_id='.$id.'&'.$data;
 		}
 
 		// Transfer the data
-		fputs ($fp, "POST " . $path . " HTTP/1.0\r\n" );
-		fputs ($fp, "Host: " . $target['host'] . "\r\n" );
-		fputs ($fp, "Content-type: application/x-www-form-urlencoded\r\n" );
-		fputs ($fp, "Content-length: " . strlen($data) . "\r\n" );
-		fputs ($fp, "Connection: close\r\n\r\n" );
-		fputs ($fp, $data);
+		fputs($fp, 'POST '.$path." HTTP/1.0\r\n");
+		fputs($fp, 'Host: '.$target['host']."\r\n");
+		fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
+		fputs($fp, 'Content-length: '.strlen($data)."\r\n");
+		fputs($fp, "Connection: close\r\n\r\n");
+		fputs($fp, $data);
 
 		// Was it successful?
-		$this->response = "";
 
+		$this->response = '';
 		while ( ! feof($fp))
 		{
 			$this->response .= fgets($fp, 128);
 		}
 		@fclose($fp);
 
-
 		if (stripos($this->response, '<error>0</error>') === FALSE)
 		{
-			$message = (preg_match('/<message>(.*?)<\/message>/is', $this->response, $match)) ? trim($match[1]) : 'An unknown error was encountered';
+			$message = preg_match('/<message>(.*?)<\/message>/is', $this->response, $match) ? trim($match[1]) : 'An unknown error was encountered';
 			$this->set_error($message);
 			return FALSE;
 		}
@@ -282,11 +280,8 @@
 	 */
 	public function extract_urls($urls)
 	{
-		// Remove the pesky white space and replace with a comma.
-		$urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls);
-
-		// If they use commas get rid of the doubles.
-		$urls = str_replace(",,", ",", $urls);
+		// Remove the pesky white space and replace with a comma, then replace doubles.
+		$urls = str_replace(',,', ',', preg_replace('/\s*(\S+)\s*/', '\\1,', $urls));
 
 		// Remove any comma that might be at the end
 		if (substr($urls, -1) === ',')
@@ -294,11 +289,8 @@
 			$urls = substr($urls, 0, -1);
 		}
 
-		// Break into an array via commas
-		$urls = preg_split('/[,]/', $urls);
-
-		// Removes duplicates
-		$urls = array_unique($urls);
+		// Break into an array via commas and remove duplicates
+		$urls = array_unique(preg_split('/[,]/', $urls));
 
 		array_walk($urls, array($this, 'validate_url'));
 
@@ -313,9 +305,9 @@
 	 * Simply adds "http://" if missing
 	 *
 	 * @param	string
-	 * @return	string
+	 * @return	void
 	 */
-	public function validate_url($url)
+	public function validate_url(&$url)
 	{
 		$url = trim($url);
 
@@ -335,7 +327,7 @@
 	 */
 	public function get_id($url)
 	{
-		$tb_id = "";
+		$tb_id = '';
 
 		if (strpos($url, '?') !== FALSE)
 		{
@@ -359,18 +351,11 @@
 
 			if ( ! is_numeric($tb_id))
 			{
-				$tb_id  = $tb_array[count($tb_array)-2];
+				$tb_id = $tb_array[count($tb_array)-2];
 			}
 		}
 
-		if ( ! preg_match ("/^([0-9]+)$/", $tb_id))
-		{
-			return FALSE;
-		}
-		else
-		{
-			return $tb_id;
-		}
+		return preg_match('/^[0-9]+$/', $tb_id) ? $tb_id : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -385,15 +370,13 @@
 	{
 		$temp = '__TEMP_AMPERSANDS__';
 
-		$str = preg_replace(array('/&#(\d+);/', '/&(\w+);/'), "$temp\\1;", $str);
+		$str = preg_replace(array('/&#(\d+);/', '/&(\w+);/'), $temp.'\\1;', $str);
 
-		$str = str_replace(array("&","<",">","\"", "'", "-"),
-							array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),
-							$str);
+		$str = str_replace(array('&', '<', '>', '"', "'", '-'),
+					array('&amp;', '&lt;', '&gt;', '&quot;', '&#39;', '&#45;'),
+					$str);
 
-		$str = preg_replace(array("/$temp(\d+);/", "/$temp(\w+);/"), array('&#\\1;', '&\\1;'), $str);
-
-		return $str;
+		return preg_replace(array('/'.$temp.'(\d+);/', '/'.$temp.'(\w+);/'), array('&#\\1;', '&\\1;'), $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -404,7 +387,7 @@
 	 * Limits the string based on the character count. Will preserve complete words.
 	 *
 	 * @param	string
-	 * @param	integer
+	 * @param	int
 	 * @param	string
 	 * @return	string
 	 */
@@ -415,7 +398,7 @@
 			return $str;
 		}
 
-		$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
+		$str = preg_replace('/\s+/', ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
 
 		if (strlen($str) <= $n)
 		{
@@ -469,7 +452,9 @@
 
 				if (count($temp) === $count)
 				{
-					$number = ($count == 3) ? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64) : (($temp[0] % 32) * 64) + ($temp[1] % 64);
+					$number = ($count === 3)
+						? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64)
+						: (($temp[0] % 32) * 64) + ($temp[1] % 64);
 
 					$out .= '&#'.$number.';';
 					$count = 1;
@@ -506,11 +491,10 @@
 	 */
 	public function display_errors($open = '<p>', $close = '</p>')
 	{
-		return (count($this->error_msg) > 0) ? $open . implode($close . $open, $this->error_msg) . $close : '';
+		return (count($this->error_msg) > 0) ? $open.implode($close.$open, $this->error_msg).$close : '';
 	}
 
 }
-// END Trackback Class
 
 /* End of file Trackback.php */
-/* Location: ./system/libraries/Trackback.php */
+/* Location: ./system/libraries/Trackback.php */
\ No newline at end of file
diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php
index 21bbad0..a50934f 100644
--- a/system/libraries/Typography.php
+++ b/system/libraries/Typography.php
@@ -36,22 +36,46 @@
  */
 class CI_Typography {
 
-	// Block level elements that should not be wrapped inside <p> tags
+	/**
+	 * Block level elements that should not be wrapped inside <p> tags
+	 *
+	 * @var string
+	 */
 	public $block_elements = 'address|blockquote|div|dl|fieldset|form|h\d|hr|noscript|object|ol|p|pre|script|table|ul';
 
-	// Elements that should not have <p> and <br /> tags within them.
+	/**
+	 * Elements that should not have <p> and <br /> tags within them.
+	 *
+	 * @var string
+	 */
 	public $skip_elements	= 'p|pre|ol|ul|dl|object|table|h\d';
 
-	// Tags we want the parser to completely ignore when splitting the string.
+	/**
+	 * Tags we want the parser to completely ignore when splitting the string.
+	 *
+	 * @var string
+	 */
 	public $inline_elements = 'a|abbr|acronym|b|bdo|big|br|button|cite|code|del|dfn|em|i|img|ins|input|label|map|kbd|q|samp|select|small|span|strong|sub|sup|textarea|tt|var';
 
-	// array of block level elements that require inner content to be within another block level element
+	/**
+	 * array of block level elements that require inner content to be within another block level element
+	 *
+	 * @var array
+	 */
 	public $inner_block_required = array('blockquote');
 
-	// the last block element parsed
+	/**
+	 * the last block element parsed
+	 *
+	 * @var string
+	 */
 	public $last_block_element = '';
 
-	// whether or not to protect quotes within { curly braces }
+	/**
+	 * whether or not to protect quotes within { curly braces }
+	 *
+	 * @var bool
+	 */
 	public $protect_braced_quotes = FALSE;
 
 	/**
@@ -71,7 +95,7 @@
 	 */
 	public function auto_typography($str, $reduce_linebreaks = FALSE)
 	{
-		if ($str == '')
+		if ($str === '')
 		{
 			return '';
 		}
@@ -149,7 +173,7 @@
 					$process = ($match[1] === '/');
 				}
 
-				if ($match[1] == '')
+				if ($match[1] === '')
 				{
 					$this->last_block_element = $match[2];
 				}
@@ -320,7 +344,7 @@
 	 */
 	protected function _format_newlines($str)
 	{
-		if ($str == '' OR (strpos($str, "\n") === FALSE && ! in_array($this->last_block_element, $this->inner_block_required)))
+		if ($str === '' OR (strpos($str, "\n") === FALSE && ! in_array($this->last_block_element, $this->inner_block_required)))
 		{
 			return $str;
 		}
@@ -332,7 +356,7 @@
 		$str = preg_replace("/([^\n])(\n)([^\n])/", '\\1<br />\\2\\3', $str);
 
 		// Wrap the whole enchilada in enclosing paragraphs
-		if ($str != "\n")
+		if ($str !== "\n")
 		{
 			// We trim off the right-side new line so that the closing </p> tag
 			// will be positioned immediately following the string, matching
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 2eb8df3..70ad8dc 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Unit Testing Class
  *
@@ -60,7 +58,7 @@
 							'notes'
 						);
 
-		log_message('debug', "Unit Testing Class Initialized");
+		log_message('debug', 'Unit Testing Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -75,7 +73,7 @@
 	 */
 	public function set_test_items($items = array())
 	{
-		if ( ! empty($items) AND is_array($items))
+		if ( ! empty($items) && is_array($items))
 		{
 			$this->_test_items_visible = $items;
 		}
@@ -95,20 +93,20 @@
 	 */
 	public function run($test, $expected = TRUE, $test_name = 'undefined', $notes = '')
 	{
-		if ($this->active == FALSE)
+		if ($this->active === FALSE)
 		{
 			return FALSE;
 		}
 
 		if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE))
 		{
-			$expected = str_replace('is_float', 'is_double', $expected);
-			$result = ($expected($test)) ? TRUE : FALSE;
+			$expected = str_replace('is_double', 'is_float', $expected);
+			$result = $expected($test);
 			$extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected));
 		}
 		else
 		{
-			$result = ($this->strict == TRUE) ? ($test === $expected) : ($test == $expected);
+			$result = ($this->strict === TRUE) ? ($test === $expected) : ($test === $expected);
 			$extype = gettype($expected);
 		}
 
@@ -126,7 +124,7 @@
 
 		$this->results[] = $report;
 
-		return($this->report($this->result($report)));
+		return $this->report($this->result($report));
 	}
 
 	// --------------------------------------------------------------------
@@ -157,13 +155,13 @@
 
 			foreach ($res as $key => $val)
 			{
-				if ($key == $CI->lang->line('ut_result'))
+				if ($key === $CI->lang->line('ut_result'))
 				{
-					if ($val == $CI->lang->line('ut_passed'))
+					if ($val === $CI->lang->line('ut_passed'))
 					{
 						$val = '<span style="color: #0C0;">'.$val.'</span>';
 					}
-					elseif ($val == $CI->lang->line('ut_failed'))
+					elseif ($val === $CI->lang->line('ut_failed'))
 					{
 						$val = '<span style="color: #C00;">'.$val.'</span>';
 					}
@@ -186,7 +184,7 @@
 	 * Causes the evaluation to use === rather than ==
 	 *
 	 * @param	bool
-	 * @return	null
+	 * @return	void
 	 */
 	public function use_strict($state = TRUE)
 	{
@@ -201,7 +199,7 @@
 	 * Enables/disables unit testing
 	 *
 	 * @param	bool
-	 * @return	null
+	 * @return	void
 	 */
 	public function active($state = TRUE)
 	{
@@ -291,15 +289,11 @@
 	 */
 	protected function _backtrace()
 	{
-		if (function_exists('debug_backtrace'))
-		{
-			$back = debug_backtrace();
-			return array(
-					'file' => (isset($back[1]['file']) ? $back[1]['file'] : ''),
-					'line' => (isset($back[1]['line']) ? $back[1]['line'] : '')
-				);
-		}
-		return array('file' => 'Unknown', 'line' => 'Unknown');
+		$back = debug_backtrace();
+		return array(
+				'file' => (isset($back[1]['file']) ? $back[1]['file'] : ''),
+				'line' => (isset($back[1]['line']) ? $back[1]['line'] : '')
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -311,10 +305,10 @@
 	 */
 	protected function _default_template()
 	{
-		$this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">{rows}'."\n".'</table>';
+		$this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">{rows}'."\n</table>";
 
 		$this->_template_rows = "\n\t<tr>\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>'
-					. "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>'."\n\t</tr>";
+					."\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>'."\n\t</tr>";
 	}
 
 	// --------------------------------------------------------------------
@@ -333,7 +327,7 @@
 			return;
 		}
 
-		if (is_null($this->_template) OR ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))
+		if (is_null($this->_template) OR ! preg_match('/\{rows\}(.*?)\{\/rows\}/si', $this->_template, $match))
 		{
 			$this->_default_template();
 			return;
@@ -344,7 +338,6 @@
 	}
 
 }
-// END Unit_test Class
 
 /**
  * Helper functions to test boolean true/false
@@ -353,13 +346,12 @@
  */
 function is_true($test)
 {
-	return (is_bool($test) AND $test === TRUE) ? TRUE : FALSE;
+	return ($test === TRUE);
 }
 function is_false($test)
 {
-	return (is_bool($test) AND $test === FALSE) ? TRUE : FALSE;
+	return ($test === FALSE);
 }
 
-
 /* End of file Unit_test.php */
-/* Location: ./system/libraries/Unit_test.php */
+/* Location: ./system/libraries/Unit_test.php */
\ No newline at end of file
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 8ad6705..1f6aeeb 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -78,6 +78,8 @@
 			$this->initialize($props);
 		}
 
+		$this->mimes =& get_mimes();
+
 		log_message('debug', 'Upload Class Initialized');
 	}
 
@@ -113,7 +115,6 @@
 					'image_type'			=> '',
 					'image_size_str'		=> '',
 					'error_msg'			=> array(),
-					'mimes'				=> array(),
 					'remove_spaces'			=> TRUE,
 					'xss_clean'			=> FALSE,
 					'temp_prefix'			=> 'temp_file_',
@@ -223,7 +224,7 @@
 		}
 
 		// if we're overriding, let's now make sure the new name and type is allowed
-		if ($this->_file_name_override != '')
+		if ($this->_file_name_override !== '')
 		{
 			$this->file_name = $this->_prep_filename($this->_file_name_override);
 
@@ -276,7 +277,7 @@
 		}
 
 		// Remove white spaces in the name
-		if ($this->remove_spaces == TRUE)
+		if ($this->remove_spaces === TRUE)
 		{
 			$this->file_name = preg_replace('/\s+/', '_', $this->file_name);
 		}
@@ -289,7 +290,7 @@
 		 */
 		$this->orig_name = $this->file_name;
 
-		if ($this->overwrite == FALSE)
+		if ($this->overwrite === FALSE)
 		{
 			$this->file_name = $this->set_filename($this->upload_path, $this->file_name);
 
@@ -397,7 +398,7 @@
 	 */
 	public function set_filename($path, $filename)
 	{
-		if ($this->encrypt_name == TRUE)
+		if ($this->encrypt_name === TRUE)
 		{
 			mt_srand();
 			$filename = md5(uniqid(mt_rand())).$this->file_ext;
@@ -420,7 +421,7 @@
 			}
 		}
 
-		if ($new_filename == '')
+		if ($new_filename === '')
 		{
 			$this->set_error('upload_bad_filename');
 			return FALSE;
@@ -545,7 +546,7 @@
 	 */
 	public function set_xss_clean($flag = FALSE)
 	{
-		$this->xss_clean = ($flag == TRUE);
+		$this->xss_clean = ($flag === TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -641,7 +642,7 @@
 	 */
 	public function is_allowed_filesize()
 	{
-		return ($this->max_size == 0 OR $this->max_size > $this->file_size);
+		return ($this->max_size === 0 OR $this->max_size > $this->file_size);
 	}
 
 	// --------------------------------------------------------------------
@@ -687,13 +688,13 @@
 	 */
 	public function validate_upload_path()
 	{
-		if ($this->upload_path == '')
+		if ($this->upload_path === '')
 		{
 			$this->set_error('upload_no_filepath');
 			return FALSE;
 		}
 
-		if (function_exists('realpath') && @realpath($this->upload_path) !== FALSE)
+		if (@realpath($this->upload_path) !== FALSE)
 		{
 			$this->upload_path = str_replace('\\', '/', realpath($this->upload_path));
 		}
@@ -725,7 +726,7 @@
 	public function get_extension($filename)
 	{
 		$x = explode('.', $filename);
-		return '.'.end($x);
+		return (count($x) !== 1) ? '.'.end($x) : '';
 	}
 
 	// --------------------------------------------------------------------
@@ -747,6 +748,8 @@
 				';',
 				'?',
 				'/',
+				'!',
+				'#',
 				'%20',
 				'%22',
 				'%3c',		// <
@@ -812,17 +815,17 @@
 			return FALSE;
 		}
 
-		if (function_exists('memory_get_usage') && memory_get_usage() && ini_get('memory_limit') != '')
+		if (memory_get_usage() && ($memory_limit = ini_get('memory_limit')))
 		{
-			$current = ini_get('memory_limit') * 1024 * 1024;
+			$memory_limit *= 1024 * 1024;
 
 			// There was a bug/behavioural change in PHP 5.2, where numbers over one million get output
 			// into scientific notation. number_format() ensures this number is an integer
 			// http://bugs.php.net/bug.php?id=43053
 
-			$new_memory = number_format(ceil(filesize($file) + $current), 0, '.', '');
+			$memory_limit = number_format(ceil(filesize($file) + $memory_limit), 0, '.', '');
 
-			ini_set('memory_limit', $new_memory); // When an integer is used, the value is measured in bytes. - PHP.net
+			ini_set('memory_limit', $memory_limit); // When an integer is used, the value is measured in bytes. - PHP.net
 		}
 
 		// If the file being uploaded is an image, then we should have no problem with XSS attacks (in theory), but
@@ -846,10 +849,8 @@
 			// <a, <body, <head, <html, <img, <plaintext, <pre, <script, <table, <title
 			// title is basically just in SVG, but we filter it anyhow
 
-			if ( ! preg_match('/<(a|body|head|html|img|plaintext|pre|script|table|title)[\s>]/i', $opening_bytes))
-			{
-				return TRUE; // its an image, no "triggers" detected in the first 256 bytes, we're good
-			}
+			// if its an image or no "triggers" detected in the first 256 bytes - we're good
+			return ! preg_match('/<(a|body|head|html|img|plaintext|pre|script|table|title)[\s>]/i', $opening_bytes);
 		}
 
 		if (($data = @file_get_contents($file)) === FALSE)
@@ -878,14 +879,14 @@
 		{
 			foreach ($msg as $val)
 			{
-				$msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);
+				$msg = ($CI->lang->line($val) === FALSE) ? $val : $CI->lang->line($val);
 				$this->error_msg[] = $msg;
 				log_message('error', $msg);
 			}
 		}
 		else
 		{
-			$msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
+			$msg = ($CI->lang->line($msg) === FALSE) ? $msg : $CI->lang->line($msg);
 			$this->error_msg[] = $msg;
 			log_message('error', $msg);
 		}
@@ -918,26 +919,6 @@
 	 */
 	public function mimes_types($mime)
 	{
-		global $mimes;
-
-		if (count($this->mimes) == 0)
-		{
-			if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
-			{
-				include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
-			}
-			elseif (is_file(APPPATH.'config/mimes.php'))
-			{
-				include(APPPATH.'config/mimes.php');
-			}
-			else
-			{
-				return FALSE;
-			}
-
-			$this->mimes = $mimes;
-		}
-
 		return isset($this->mimes[$mime]) ? $this->mimes[$mime] : FALSE;
 	}
 
@@ -954,7 +935,7 @@
 	 */
 	protected function _prep_filename($filename)
 	{
-		if (strpos($filename, '.') === FALSE OR $this->allowed_types == '*')
+		if (strpos($filename, '.') === FALSE OR $this->allowed_types === '*')
 		{
 			return $filename;
 		}
@@ -1032,7 +1013,7 @@
 		 */
 		if (DIRECTORY_SEPARATOR !== '\\')
 		{
-			$cmd = 'file --brief --mime ' . escapeshellarg($file['tmp_name']) . ' 2>&1';
+			$cmd = 'file --brief --mime '.escapeshellarg($file['tmp_name']).' 2>&1';
 
 			if (function_exists('exec'))
 			{
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index 9109edd..ff596f0 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * User Agent Class
  *
@@ -40,25 +38,110 @@
  */
 class CI_User_agent {
 
-	public $agent		= NULL;
+	/**
+	 * Current user-agent
+	 *
+	 * @var string
+	 */
+	public $agent = NULL;
 
-	public $is_browser	= FALSE;
-	public $is_robot	= FALSE;
-	public $is_mobile	= FALSE;
+	/**
+	 * Flag for if the user-agent belongs to a browser
+	 *
+	 * @var bool
+	 */
+	public $is_browser = FALSE;
 
-	public $languages	= array();
-	public $charsets	= array();
+	/**
+	 * Flag for if the user-agent is a robot
+	 *
+	 * @var bool
+	 */
+	public $is_robot = FALSE;
 
-	public $platforms	= array();
-	public $browsers	= array();
-	public $mobiles		= array();
-	public $robots		= array();
+	/**
+	 * Flag for if the user-agent is a mobile browser
+	 *
+	 * @var bool
+	 */
+	public $is_mobile = FALSE;
 
-	public $platform	= '';
-	public $browser		= '';
-	public $version		= '';
-	public $mobile		= '';
-	public $robot		= '';
+	/**
+	 * Languages accepted by the current user agent
+	 *
+	 * @var array
+	 */
+	public $languages = array();
+
+	/**
+	 * Character sets accepted by the current user agent
+	 *
+	 * @var array
+	 */
+	public $charsets = array();
+
+	/**
+	 * List of platforms to compare against current user agent
+	 *
+	 * @var array
+	 */
+	public $platforms = array();
+
+	/**
+	 * List of browsers to compare against current user agent
+	 *
+	 * @var array
+	 */
+	public $browsers = array();
+
+	/**
+	 * List of mobile browsers to compare against current user agent
+	 *
+	 * @var array
+	 */
+	public $mobiles = array();
+
+	/**
+	 * List of robots to compare against current user agent
+	 *
+	 * @var array
+	 */
+	public $robots = array();
+
+	/**
+	 * Current user-agent platform
+	 *
+	 * @var string
+	 */
+	public $platform = '';
+
+	/**
+	 * Current user-agent browser
+	 *
+	 * @var string
+	 */
+	public $browser = '';
+
+	/**
+	 * Current user-agent version
+	 *
+	 * @var string
+	 */
+	public $version = '';
+
+	/**
+	 * Current user-agent mobile name
+	 *
+	 * @var string
+	 */
+	public $mobile = '';
+
+	/**
+	 * Current user-agent robot name
+	 *
+	 * @var string
+	 */
+	public $robot = '';
 
 	/**
 	 * Constructor
@@ -74,15 +157,12 @@
 			$this->agent = trim($_SERVER['HTTP_USER_AGENT']);
 		}
 
-		if ( ! is_null($this->agent))
+		if ( ! is_null($this->agent) && $this->_load_agent_file())
 		{
-			if ($this->_load_agent_file())
-			{
-				$this->_compile_data();
-			}
+			$this->_compile_data();
 		}
 
-		log_message('debug', "User Agent Class Initialized");
+		log_message('debug', 'User Agent Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -94,7 +174,7 @@
 	 */
 	protected function _load_agent_file()
 	{
-		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php'))
+		if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php'))
 		{
 			include(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php');
 		}
@@ -165,22 +245,24 @@
 	/**
 	 * Set the Platform
 	 *
-	 * @return	mixed
+	 * @return	bool
 	 */
 	protected function _set_platform()
 	{
-		if (is_array($this->platforms) AND count($this->platforms) > 0)
+		if (is_array($this->platforms) && count($this->platforms) > 0)
 		{
 			foreach ($this->platforms as $key => $val)
 			{
-				if (preg_match("|".preg_quote($key)."|i", $this->agent))
+				if (preg_match('|'.preg_quote($key).'|i', $this->agent))
 				{
 					$this->platform = $val;
 					return TRUE;
 				}
 			}
 		}
+
 		$this->platform = 'Unknown Platform';
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -192,11 +274,11 @@
 	 */
 	protected function _set_browser()
 	{
-		if (is_array($this->browsers) AND count($this->browsers) > 0)
+		if (is_array($this->browsers) && count($this->browsers) > 0)
 		{
 			foreach ($this->browsers as $key => $val)
 			{
-				if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match))
+				if (preg_match('|'.preg_quote($key).'.*?([0-9\.]+)|i', $this->agent, $match))
 				{
 					$this->is_browser = TRUE;
 					$this->version = $match[1];
@@ -206,6 +288,7 @@
 				}
 			}
 		}
+
 		return FALSE;
 	}
 
@@ -218,11 +301,11 @@
 	 */
 	protected function _set_robot()
 	{
-		if (is_array($this->robots) AND count($this->robots) > 0)
+		if (is_array($this->robots) && count($this->robots) > 0)
 		{
 			foreach ($this->robots as $key => $val)
 			{
-				if (preg_match("|".preg_quote($key)."|i", $this->agent))
+				if (preg_match('|'.preg_quote($key).'|i', $this->agent))
 				{
 					$this->is_robot = TRUE;
 					$this->robot = $val;
@@ -230,6 +313,7 @@
 				}
 			}
 		}
+
 		return FALSE;
 	}
 
@@ -242,11 +326,11 @@
 	 */
 	protected function _set_mobile()
 	{
-		if (is_array($this->mobiles) AND count($this->mobiles) > 0)
+		if (is_array($this->mobiles) && count($this->mobiles) > 0)
 		{
 			foreach ($this->mobiles as $key => $val)
 			{
-				if (FALSE !== (strpos(strtolower($this->agent), $key)))
+				if (FALSE !== (stripos($this->agent, $key)))
 				{
 					$this->is_mobile = TRUE;
 					$this->mobile = $val;
@@ -254,6 +338,7 @@
 				}
 			}
 		}
+
 		return FALSE;
 	}
 
@@ -266,7 +351,7 @@
 	 */
 	protected function _set_languages()
 	{
-		if ((count($this->languages) === 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '')
+		if ((count($this->languages) === 0) && ! empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
 		{
 			$this->languages = explode(',', preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE']))));
 		}
@@ -286,7 +371,7 @@
 	 */
 	protected function _set_charsets()
 	{
-		if ((count($this->charsets) === 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '')
+		if ((count($this->charsets) === 0) && ! empty($_SERVER['HTTP_ACCEPT_CHARSET']))
 		{
 			$this->charsets = explode(',', preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET']))));
 		}
@@ -302,6 +387,7 @@
 	/**
 	 * Is Browser
 	 *
+	 * @param	string	$key
 	 * @return	bool
 	 */
 	public function is_browser($key = NULL)
@@ -318,7 +404,7 @@
 		}
 
 		// Check for a specific browser
-		return array_key_exists($key, $this->browsers) AND $this->browser === $this->browsers[$key];
+		return (isset($this->browsers[$key]) && $this->browser === $this->browsers[$key]);
 	}
 
 	// --------------------------------------------------------------------
@@ -326,6 +412,7 @@
 	/**
 	 * Is Robot
 	 *
+	 * @param	string	$key
 	 * @return	bool
 	 */
 	public function is_robot($key = NULL)
@@ -342,7 +429,7 @@
 		}
 
 		// Check for a specific robot
-		return array_key_exists($key, $this->robots) AND $this->robot === $this->robots[$key];
+		return (isset($this->robots[$key]) && $this->robot === $this->robots[$key]);
 	}
 
 	// --------------------------------------------------------------------
@@ -350,6 +437,7 @@
 	/**
 	 * Is Mobile
 	 *
+	 * @param	string	$key
 	 * @return	bool
 	 */
 	public function is_mobile($key = NULL)
@@ -366,7 +454,7 @@
 		}
 
 		// Check for a specific robot
-		return array_key_exists($key, $this->mobiles) AND $this->mobile === $this->mobiles[$key];
+		return (isset($this->mobiles[$key]) && $this->mobile === $this->mobiles[$key]);
 	}
 
 	// --------------------------------------------------------------------
@@ -378,7 +466,7 @@
 	 */
 	public function is_referral()
 	{
-		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE;
+		return ! empty($_SERVER['HTTP_REFERER']);
 	}
 
 	// --------------------------------------------------------------------
@@ -461,7 +549,7 @@
 	 */
 	public function referrer()
 	{
-		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']);
+		return empty($_SERVER['HTTP_REFERER']) ? '' : trim($_SERVER['HTTP_REFERER']);
 	}
 
 	// --------------------------------------------------------------------
@@ -503,11 +591,12 @@
 	/**
 	 * Test for a particular language
 	 *
+	 * @param	string	$lang
 	 * @return	bool
 	 */
 	public function accept_lang($lang = 'en')
 	{
-		return (in_array(strtolower($lang), $this->languages(), TRUE));
+		return in_array(strtolower($lang), $this->languages(), TRUE);
 	}
 
 	// --------------------------------------------------------------------
@@ -515,14 +604,15 @@
 	/**
 	 * Test for a particular character set
 	 *
+	 * @param	string	$charset
 	 * @return	bool
 	 */
 	public function accept_charset($charset = 'utf-8')
 	{
-		return (in_array(strtolower($charset), $this->charsets(), TRUE));
+		return in_array(strtolower($charset), $this->charsets(), TRUE);
 	}
 
 }
 
 /* End of file User_agent.php */
-/* Location: ./system/libraries/User_agent.php */
+/* Location: ./system/libraries/User_agent.php */
\ No newline at end of file
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 32e2e52..6f35423 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -25,14 +25,6 @@
  * @filesource
  */
 
-if ( ! function_exists('xml_parser_create'))
-{
-	show_error('Your PHP installation does not support XML');
-}
-
-
-// ------------------------------------------------------------------------
-
 /**
  * XML-RPC request handler class
  *
@@ -42,6 +34,14 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/libraries/xmlrpc.html
  */
+
+if ( ! function_exists('xml_parser_create'))
+{
+	show_error('Your PHP installation does not support XML');
+}
+
+// ------------------------------------------------------------------------
+
 class CI_Xmlrpc {
 
 	public $debug		= FALSE;	// Debugging on or off
@@ -77,13 +77,17 @@
 
 	public $xss_clean		= TRUE;
 
-	//-------------------------------------
-	//  VALUES THAT MULTIPLE CLASSES NEED
-	//-------------------------------------
 
+	/**
+	 * Constructor
+	 *
+	 * Initializes property default values
+	 *
+	 * @param	array
+	 * @return	void
+	 */
 	public function __construct($config = array())
 	{
-		$this->xmlrpcName	= $this->xmlrpcName;
 		$this->xmlrpc_backslash = chr(92).chr(92);
 
 		// Types for info sent back and forth
@@ -100,24 +104,24 @@
 			);
 
 		// Array of Valid Parents for Various XML-RPC elements
-		$this->valid_parents = array('BOOLEAN'			=> array('VALUE'),
-						'I4'				=> array('VALUE'),
-						'INT'				=> array('VALUE'),
-						'STRING'			=> array('VALUE'),
-						'DOUBLE'			=> array('VALUE'),
-						'DATETIME.ISO8601'	=> array('VALUE'),
-						'BASE64'			=> array('VALUE'),
-						'ARRAY'			=> array('VALUE'),
-						'STRUCT'			=> array('VALUE'),
-						'PARAM'			=> array('PARAMS'),
-						'METHODNAME'		=> array('METHODCALL'),
-						'PARAMS'			=> array('METHODCALL', 'METHODRESPONSE'),
-						'MEMBER'			=> array('STRUCT'),
-						'NAME'				=> array('MEMBER'),
-						'DATA'				=> array('ARRAY'),
-						'FAULT'			=> array('METHODRESPONSE'),
-						'VALUE'			=> array('MEMBER', 'DATA', 'PARAM', 'FAULT')
-					 );
+		$this->valid_parents = array('BOOLEAN' => array('VALUE'),
+			'I4'				=> array('VALUE'),
+			'INT'				=> array('VALUE'),
+			'STRING'			=> array('VALUE'),
+			'DOUBLE'			=> array('VALUE'),
+			'DATETIME.ISO8601'	=> array('VALUE'),
+			'BASE64'			=> array('VALUE'),
+			'ARRAY'			=> array('VALUE'),
+			'STRUCT'			=> array('VALUE'),
+			'PARAM'			=> array('PARAMS'),
+			'METHODNAME'		=> array('METHODCALL'),
+			'PARAMS'			=> array('METHODCALL', 'METHODRESPONSE'),
+			'MEMBER'			=> array('STRUCT'),
+			'NAME'				=> array('MEMBER'),
+			'DATA'				=> array('ARRAY'),
+			'FAULT'			=> array('METHODRESPONSE'),
+			'VALUE'			=> array('MEMBER', 'DATA', 'PARAM', 'FAULT')
+		 );
 
 
 		// XML-RPC Responses
@@ -136,14 +140,17 @@
 
 		$this->initialize($config);
 
-		log_message('debug', "XML-RPC Class Initialized");
+		log_message('debug', 'XML-RPC Class Initialized');
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Initialize Prefs
-	//-------------------------------------
-
+	/**
+	 * Initialize
+	 *
+	 * @param	array
+	 * @return	void
+	 */
 	public function initialize($config = array())
 	{
 		if (count($config) > 0)
@@ -157,36 +164,43 @@
 			}
 		}
 	}
-	// END
 
-	//-------------------------------------
-	//  Take URL and parse it
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
-	public function server($url, $port=80)
+	/**
+	 * Parse server URL
+	 *
+	 * @param	string	url
+	 * @param	int	port
+	 * @return	void
+	 */
+	public function server($url, $port = 80)
 	{
 		if (strpos($url, 'http') !== 0)
 		{
-			$url = "http://".$url;
+			$url = 'http://'.$url;
 		}
 
 		$parts = parse_url($url);
 
-		$path = ( ! isset($parts['path'])) ? '/' : $parts['path'];
+		$path = isset($parts['path']) ? $parts['path'] : '/';
 
-		if (isset($parts['query']) && $parts['query'] != '')
+		if ( ! empty($parts['query']))
 		{
 			$path .= '?'.$parts['query'];
 		}
 
 		$this->client = new XML_RPC_Client($path, $parts['host'], $port);
 	}
-	// END
 
-	//-------------------------------------
-	//  Set Timeout
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Set Timeout
+	 *
+	 * @param	int	seconds
+	 * @return	void
+	 */
 	public function timeout($seconds = 5)
 	{
 		if ( ! is_null($this->client) && is_int($seconds))
@@ -194,27 +208,34 @@
 			$this->client->timeout = $seconds;
 		}
 	}
-	// END
 
-	//-------------------------------------
-	//  Set Methods
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Set Methods
+	 *
+	 * @param	string	method name
+	 * @return	void
+	 */
 	public function method($function)
 	{
 		$this->method = $function;
 	}
-	// END
 
-	//-------------------------------------
-	//  Take Array of Data and Create Objects
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Take Array of Data and Create Objects
+	 *
+	 * @param	array
+	 * @return	void
+	 */
 	public function request($incoming)
 	{
 		if ( ! is_array($incoming))
 		{
 			// Send Error
+			return;
 		}
 
 		$this->data = array();
@@ -224,33 +245,39 @@
 			$this->data[$key] = $this->values_parsing($value);
 		}
 	}
-	// END
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Set Debug
-	//-------------------------------------
-
+	/**
+	 * Set Debug
+	 *
+	 * @param	bool
+	 * @return	void
+	 */
 	public function set_debug($flag = TRUE)
 	{
-		$this->debug = ($flag == TRUE);
+		$this->debug = ($flag === TRUE);
 	}
 
-	//-------------------------------------
-	//  Values Parsing
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
-	public function values_parsing($value, $return = FALSE)
+	/**
+	 * Values Parsing
+	 *
+	 * @param	mixed
+	 * @return	object
+	 */
+	public function values_parsing($value)
 	{
 		if (is_array($value) && array_key_exists(0, $value))
 		{
-			if ( ! isset($value[1]) OR ( ! isset($this->xmlrpcTypes[$value[1]])))
+			if ( ! isset($value[1], $this->xmlrpcTypes[$value[1]]))
 			{
 				$temp = new XML_RPC_Values($value[0], (is_array($value[0]) ? 'array' : 'string'));
 			}
 			else
 			{
-				if (is_array($value[0]) && ($value[1] == 'struct' OR $value[1] == 'array'))
+				if (is_array($value[0]) && ($value[1] === 'struct' OR $value[1] === 'array'))
 				{
 					while (list($k) = each($value[0]))
 					{
@@ -268,16 +295,17 @@
 
 		return $temp;
 	}
-	// END
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Sends XML-RPC Request
-	//-------------------------------------
-
+	/**
+	 * Sends XML-RPC Request
+	 *
+	 * @return	bool
+	 */
 	public function send_request()
 	{
-		$this->message = new XML_RPC_Message($this->method,$this->data);
+		$this->message = new XML_RPC_Message($this->method, $this->data);
 		$this->message->debug = $this->debug;
 
 		if ( ! $this->result = $this->client->send($this->message) OR ! is_object($this->result->val))
@@ -289,55 +317,62 @@
 		$this->response = $this->result->decode();
 		return TRUE;
 	}
-	// END
 
-	//-------------------------------------
-	//  Returns Error
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Returns Error
+	 *
+	 * @return	string
+	 */
 	public function display_error()
 	{
 		return $this->error;
 	}
-	// END
 
-	//-------------------------------------
-	//  Returns Remote Server Response
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Returns Remote Server Response
+	 *
+	 * @return	string
+	 */
 	public function display_response()
 	{
 		return $this->response;
 	}
-	// END
 
-	//-------------------------------------
-	//  Sends an Error Message for Server Request
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Sends an Error Message for Server Request
+	 *
+	 * @param	int
+	 * @param	string
+	 * @return	object
+	 */
 	public function send_error_message($number, $message)
 	{
 		return new XML_RPC_Response(0, $number, $message);
 	}
-	// END
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  Send Response for Server Request
-	//-------------------------------------
-
+	/**
+	 * Send Response for Server Request
+	 *
+	 * @param	array
+	 * @return	object
+	 */
 	public function send_response($response)
 	{
 		// $response should be array of values, which will be parsed
 		// based on their data and type into a valid group of XML-RPC values
 		return new XML_RPC_Response($this->values_parsing($response));
 	}
-	// END
 
 } // END XML_RPC Class
 
-
-
 /**
  * XML-RPC Client class
  *
@@ -355,7 +390,15 @@
 	public $timeout		= 5;
 	public $no_multicall	= FALSE;
 
-	public function __construct($path, $server, $port=80)
+	/**
+	 * Constructor
+	 *
+	 * @param	string
+	 * @param	object
+	 * @param	int
+	 * @return	void
+	 */
+	public function __construct($path, $server, $port = 80)
 	{
 		parent::__construct();
 
@@ -364,27 +407,41 @@
 		$this->path = $path;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send message
+	 *
+	 * @param	mixed
+	 * @return	object
+	 */
 	public function send($msg)
 	{
 		if (is_array($msg))
 		{
 			// Multi-call disabled
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'],$this->xmlrpcstr['multicall_recursion']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['multicall_recursion'], $this->xmlrpcstr['multicall_recursion']);
 		}
 
 		return $this->sendPayload($msg);
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Send payload
+	 *
+	 * @param	object
+	 * @return	object
+	 */
 	public function sendPayload($msg)
 	{
-		$fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);
+		$fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstring, $this->timeout);
 
 		if ( ! is_resource($fp))
 		{
 			error_log($this->xmlrpcstr['http_error']);
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
 		}
 
 		if (empty($msg->payload))
@@ -394,27 +451,25 @@
 		}
 
 		$r = "\r\n";
-		$op = "POST {$this->path} HTTP/1.0$r"
-			. "Host: {$this->server}$r"
-			. "Content-Type: text/xml$r"
-			. "User-Agent: {$this->xmlrpcName}$r"
-			. "Content-Length: ".strlen($msg->payload)."$r$r"
-			. $msg->payload;
+		$op = 'POST '.$this->path.' HTTP/1.0'.$r
+			.'Host: '.$this->server.$r
+			.'Content-Type: text/xml'.$r
+			.'User-Agent: '.$this->xmlrpcName.$r
+			.'Content-Length: '.strlen($msg->payload).$r.$r
+			.$msg->payload;
 
-
-		if ( ! fputs($fp, $op, strlen($op)))
+		if ( ! fwrite($fp, $op, strlen($op)))
 		{
 			error_log($this->xmlrpcstr['http_error']);
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']);
 		}
+
 		$resp = $msg->parseResponse($fp);
 		fclose($fp);
 		return $resp;
 	}
 
-}
-// end class XML_RPC_Client
+} // END XML_RPC_Client Class
 
 /**
  * XML-RPC Response class
@@ -425,31 +480,34 @@
  */
 class XML_RPC_Response
 {
-	public $val = 0;
-	public $errno = 0;
-	public $errstr = '';
-	public $headers = array();
-	public $xss_clean = TRUE;
+	public $val		= 0;
+	public $errno		= 0;
+	public $errstr		= '';
+	public $headers		= array();
+	public $xss_clean	= TRUE;
 
+	/**
+	 * Constructor
+	 *
+	 * @param	mixed
+	 * @param	int
+	 * @param	string
+	 * @return	void
+	 */
 	public function __construct($val, $code = 0, $fstr = '')
 	{
-		if ($code != 0)
+		if ($code !== 0)
 		{
 			// error
 			$this->errno = $code;
-			if ( ! is_php('5.4'))
-			{
-				$this->errstr = htmlspecialchars($fstr, ENT_NOQUOTES, 'UTF-8');
-			}
-			else
-			{
-				$this->errstr = htmlspecialchars($fstr, ENT_XML1 | ENT_NOQUOTES, 'UTF-8');
-			}
+			$this->errstr = htmlspecialchars($fstr,
+							(is_php('5.4') ? ENT_XML1 | ENT_NOQUOTES : ENT_NOQUOTES),
+							'UTF-8');
 		}
-		else if ( ! is_object($val))
+		elseif ( ! is_object($val))
 		{
 			// programmer error, not an object
-			error_log("Invalid type '" . gettype($val) . "' (value: $val) passed to XML_RPC_Response.  Defaulting to empty value.");
+			error_log("Invalid type '".gettype($val)."' (value: ".$val.') passed to XML_RPC_Response. Defaulting to empty value.');
 			$this->val = new XML_RPC_Values();
 		}
 		else
@@ -458,43 +516,79 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fault code
+	 *
+	 * @return	int
+	 */
 	public function faultCode()
 	{
 		return $this->errno;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fault string
+	 *
+	 * @return	string
+	 */
 	public function faultString()
 	{
 		return $this->errstr;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Value
+	 *
+	 * @return	mixed
+	 */
 	public function value()
 	{
 		return $this->val;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Prepare response
+	 *
+	 * @return	string	xml
+	 */
 	public function prepare_response()
 	{
 		return "<methodResponse>\n"
-			. ($this->errno
-			? '<fault>
+			.($this->errno
+				? '<fault>
 	<value>
 		<struct>
 			<member>
 				<name>faultCode</name>
-				<value><int>' . $this->errno . '</int></value>
+				<value><int>'.$this->errno.'</int></value>
 			</member>
 			<member>
 				<name>faultString</name>
-				<value><string>' . $this->errstr . '</string></value>
+				<value><string>'.$this->errstr.'</string></value>
 			</member>
 		</struct>
 	</value>
 </fault>'
-			: "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>")
-			. "\n</methodResponse>";
+				: "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>")
+			."\n</methodResponse>";
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Decode
+	 *
+	 * @param	mixed
+	 * @return	array
+	 */
 	public function decode($array = FALSE)
 	{
 		$CI =& get_instance();
@@ -513,40 +607,40 @@
 				}
 			}
 
-			$result = $array;
+			return $array;
+		}
+
+		$result = $this->xmlrpc_decoder($this->val);
+
+		if (is_array($result))
+		{
+			$result = $this->decode($result);
 		}
 		else
 		{
-			$result = $this->xmlrpc_decoder($this->val);
-
-			if (is_array($result))
-			{
-				$result = $this->decode($result);
-			}
-			else
-			{
-				$result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
-			}
+			$result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result;
 		}
 
 		return $result;
 	}
 
+	// --------------------------------------------------------------------
 
-
-	//-------------------------------------
-	//  XML-RPC Object to PHP Types
-	//-------------------------------------
-
+	/**
+	 * XML-RPC Object to PHP Types
+	 *
+	 * @param	object
+	 * @return	array
+	 */
 	public function xmlrpc_decoder($xmlrpc_val)
 	{
 		$kind = $xmlrpc_val->kindOf();
 
-		if ($kind == 'scalar')
+		if ($kind === 'scalar')
 		{
 			return $xmlrpc_val->scalarval();
 		}
-		elseif ($kind == 'array')
+		elseif ($kind === 'array')
 		{
 			reset($xmlrpc_val->me);
 			$b = current($xmlrpc_val->me);
@@ -558,7 +652,7 @@
 			}
 			return $arr;
 		}
-		elseif ($kind == 'struct')
+		elseif ($kind === 'struct')
 		{
 			reset($xmlrpc_val->me['struct']);
 			$arr = array();
@@ -571,25 +665,28 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  ISO-8601 time to server or UTC time
-	//-------------------------------------
-
-	public function iso8601_decode($time, $utc = 0)
+	/**
+	 * ISO-8601 time to server or UTC time
+	 *
+	 * @param	string
+	 * @param	bool
+	 * @return	int	unix timestamp
+	 */
+	public function iso8601_decode($time, $utc = FALSE)
 	{
-		// return a timet in the localtime, or UTC
+		// return a time in the localtime, or UTC
 		$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))
 		{
-			$fnc = ($utc == 1) ? 'gmmktime' : 'mktime';
+			$fnc = ($utc === TRUE) ? 'gmmktime' : 'mktime';
 			$t = $fnc($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
 		}
 		return $t;
 	}
 
-}
-// End Response Class
+} // END XML_RPC_Response Class
 
 /**
  * XML-RPC Message class
@@ -602,10 +699,17 @@
 {
 	public $payload;
 	public $method_name;
-	public $params			= array();
-	public $xh				= array();
+	public $params		= array();
+	public $xh		= array();
 
-	public function __construct($method, $pars=0)
+	/**
+	 * Constructor
+	 *
+	 * @param	string	method name
+	 * @param	array
+	 * @return	void
+	 */
+	public function __construct($method, $pars = FALSE)
 	{
 		parent::__construct();
 
@@ -620,15 +724,18 @@
 		}
 	}
 
-	//-------------------------------------
-	//  Create Payload to Send
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Create Payload to Send
+	 *
+	 * @return	void
+	 */
 	public function createPayload()
 	{
-		$this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n"
-				. '<methodName>'.$this->method_name."</methodName>\r\n"
-				. "<params>\r\n";
+		$this->payload = '<?xml version="1.0"?'.">\r\n<methodCall>\r\n"
+				.'<methodName>'.$this->method_name."</methodName>\r\n"
+				."<params>\r\n";
 
 		for ($i = 0, $c = count($this->params); $i < $c; $i++)
 		{
@@ -640,10 +747,14 @@
 		$this->payload .= "</params>\r\n</methodCall>\r\n";
 	}
 
-	//-------------------------------------
-	//  Parse External XML-RPC Server's Response
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Parse External XML-RPC Server's Response
+	 *
+	 * @param	resource
+	 * @return	object
+	 */
 	public function parseResponse($fp)
 	{
 		$data = '';
@@ -653,36 +764,24 @@
 			$data .= $datum;
 		}
 
-		//-------------------------------------
-		//  DISPLAY HTTP CONTENT for DEBUGGING
-		//-------------------------------------
-
+		// Display HTTP content for debugging
 		if ($this->debug === TRUE)
 		{
 			echo "<pre>---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n</pre>";
 		}
 
-		//-------------------------------------
-		//  Check for data
-		//-------------------------------------
-
+		// Check for data
 		if ($data === '')
 		{
 			error_log($this->xmlrpcstr['no_data']);
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
 		}
 
-
-		//-------------------------------------
-		//  Check for HTTP 200 Response
-		//-------------------------------------
-
+		// Check for HTTP 200 Response
 		if (strncmp($data, 'HTTP', 4) === 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
 		{
-			$errstr= substr($data, 0, strpos($data, "\n")-1);
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')');
-			return $r;
+			$errstr = substr($data, 0, strpos($data, "\n")-1);
+			return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error'].' ('.$errstr.')');
 		}
 
 		//-------------------------------------
@@ -692,25 +791,21 @@
 		$parser = xml_parser_create($this->xmlrpc_defencoding);
 
 		$this->xh[$parser] = array(
-						'isf' =>	0,
-						'ac' =>		'',
-						'headers' =>	array(),
-						'stack' =>	array(),
-						'valuestack' =>	array(),
-						'isf_reason' =>	0
+						'isf'		=> 0,
+						'ac'		=> '',
+						'headers'	=> array(),
+						'stack'		=> array(),
+						'valuestack'	=> array(),
+						'isf_reason'	=> 0
 					);
 
 		xml_set_object($parser, $this);
-		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
+		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, TRUE);
 		xml_set_element_handler($parser, 'open_tag', 'closing_tag');
 		xml_set_character_data_handler($parser, 'character_data');
 		//xml_set_default_handler($parser, 'default_handler');
 
-
-		//-------------------------------------
-		//  GET HEADERS
-		//-------------------------------------
-
+		// Get headers
 		$lines = explode("\r\n", $data);
 		while (($line = array_shift($lines)))
 		{
@@ -722,16 +817,12 @@
 		}
 		$data = implode("\r\n", $lines);
 
-
-		//-------------------------------------
-		//  PARSE XML DATA
-		//-------------------------------------
-
+		// Parse XML data
 		if ( ! xml_parse($parser, $data, count($data)))
 		{
 			$errstr = sprintf('XML error: %s at line %d',
-					xml_error_string(xml_get_error_code($parser)),
-					xml_get_current_line_number($parser));
+						xml_error_string(xml_get_error_code($parser)),
+						xml_get_current_line_number($parser));
 			//error_log($errstr);
 			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
 			xml_parser_free($parser);
@@ -739,10 +830,7 @@
 		}
 		xml_parser_free($parser);
 
-		// ---------------------------------------
-		//  Got Ourselves Some Badness, It Seems
-		// ---------------------------------------
-
+		// Got ourselves some badness, it seems
 		if ($this->xh[$parser]['isf'] > 1)
 		{
 			if ($this->debug === TRUE)
@@ -750,29 +838,24 @@
 				echo "---Invalid Return---\n".$this->xh[$parser]['isf_reason']."---Invalid Return---\n\n";
 			}
 
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
 		}
 		elseif ( ! is_object($this->xh[$parser]['value']))
 		{
-			$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
-			return $r;
+			return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']);
 		}
 
-		//-------------------------------------
-		//  DISPLAY XML CONTENT for DEBUGGING
-		//-------------------------------------
-
+		// Display XML content for debugging
 		if ($this->debug === TRUE)
 		{
-			echo "<pre>";
+			echo '<pre>';
 
 			if (count($this->xh[$parser]['headers'] > 0))
 			{
 				echo "---HEADERS---\n";
 				foreach ($this->xh[$parser]['headers'] as $header)
 				{
-					echo "$header\n";
+					echo $header."\n";
 				}
 				echo "---END HEADERS---\n\n";
 			}
@@ -782,10 +865,7 @@
 			echo "\n---END PARSED---</pre>";
 		}
 
-		//-------------------------------------
-		//  SEND RESPONSE
-		//-------------------------------------
-
+		// Send response
 		$v = $this->xh[$parser]['value'];
 		if ($this->xh[$parser]['isf'])
 		{
@@ -793,7 +873,7 @@
 			$errstr_v = $v->me['struct']['faultString'];
 			$errno = $errno_v->scalarval();
 
-			if ($errno == 0)
+			if ($errno === 0)
 			{
 				// FAULT returned, errno needs to reflect that
 				$errno = -1;
@@ -810,6 +890,8 @@
 		return $r;
 	}
 
+	// --------------------------------------------------------------------
+
 	// ------------------------------------
 	//  Begin Return Message Parsing section
 	// ------------------------------------
@@ -824,63 +906,61 @@
 	//	 stack - array with parent tree of the xml element,
 	//			 used to validate the nesting of elements
 
-	//-------------------------------------
-	//  Start Element Handler
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
-	public function open_tag($the_parser, $name, $attrs)
+	/**
+	 * Start Element Handler
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
+	public function open_tag($the_parser, $name)
 	{
 		// If invalid nesting, then return
 		if ($this->xh[$the_parser]['isf'] > 1) return;
 
 		// Evaluate and check for correct nesting of XML elements
-
-		if (count($this->xh[$the_parser]['stack']) == 0)
+		if (count($this->xh[$the_parser]['stack']) === 0)
 		{
-			if ($name != 'METHODRESPONSE' && $name != 'METHODCALL')
+			if ($name !== 'METHODRESPONSE' && $name !== 'METHODCALL')
 			{
 				$this->xh[$the_parser]['isf'] = 2;
 				$this->xh[$the_parser]['isf_reason'] = 'Top level XML-RPC element is missing';
 				return;
 			}
 		}
-		else
+		// not top level element: see if parent is OK
+		elseif ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
 		{
-			// not top level element: see if parent is OK
-			if ( ! in_array($this->xh[$the_parser]['stack'][0], $this->valid_parents[$name], TRUE))
-			{
-				$this->xh[$the_parser]['isf'] = 2;
-				$this->xh[$the_parser]['isf_reason'] = "XML-RPC element $name cannot be child of ".$this->xh[$the_parser]['stack'][0];
-				return;
-			}
+			$this->xh[$the_parser]['isf'] = 2;
+			$this->xh[$the_parser]['isf_reason'] = 'XML-RPC element $name cannot be child of '.$this->xh[$the_parser]['stack'][0];
+			return;
 		}
 
-		switch($name)
+		switch ($name)
 		{
 			case 'STRUCT':
 			case 'ARRAY':
 				// Creates array for child elements
-
-				$cur_val = array('value' => array(),
-								 'type'	 => $name);
-
+				$cur_val = array('value' => array(), 'type' => $name);
 				array_unshift($this->xh[$the_parser]['valuestack'], $cur_val);
-			break;
+				break;
 			case 'METHODNAME':
 			case 'NAME':
 				$this->xh[$the_parser]['ac'] = '';
-			break;
+				break;
 			case 'FAULT':
 				$this->xh[$the_parser]['isf'] = 1;
-			break;
+				break;
 			case 'PARAM':
 				$this->xh[$the_parser]['value'] = NULL;
-			break;
+				break;
 			case 'VALUE':
 				$this->xh[$the_parser]['vt'] = 'value';
 				$this->xh[$the_parser]['ac'] = '';
 				$this->xh[$the_parser]['lv'] = 1;
-			break;
+				break;
 			case 'I4':
 			case 'INT':
 			case 'STRING':
@@ -888,70 +968,74 @@
 			case 'DOUBLE':
 			case 'DATETIME.ISO8601':
 			case 'BASE64':
-				if ($this->xh[$the_parser]['vt'] != 'value')
+				if ($this->xh[$the_parser]['vt'] !== 'value')
 				{
 					//two data elements inside a value: an error occurred!
 					$this->xh[$the_parser]['isf'] = 2;
-					$this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value";
+					$this->xh[$the_parser]['isf_reason'] = "'Twas a ".$name.' element following a '
+										.$this->xh[$the_parser]['vt'].' element inside a single value';
 					return;
 				}
 
 				$this->xh[$the_parser]['ac'] = '';
-			break;
+				break;
 			case 'MEMBER':
 				// Set name of <member> to nothing to prevent errors later if no <name> is found
 				$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;
-			break;
+				break;
 			case 'DATA':
 			case 'METHODCALL':
 			case 'METHODRESPONSE':
 			case 'PARAMS':
 				// valid elements that add little to processing
-			break;
+				break;
 			default:
 				/// An Invalid Element is Found, so we have trouble
 				$this->xh[$the_parser]['isf'] = 2;
-				$this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name";
-			break;
+				$this->xh[$the_parser]['isf_reason'] = 'Invalid XML-RPC element found: '.$name;
+				break;
 		}
 
 		// Add current element name to stack, to allow validation of nesting
 		array_unshift($this->xh[$the_parser]['stack'], $name);
 
-		if ($name != 'VALUE') $this->xh[$the_parser]['lv'] = 0;
+		$name === 'VALUE' OR $this->xh[$the_parser]['lv'] = 0;
 	}
-	// END
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	//  End Element Handler
-	//-------------------------------------
-
+	/**
+	 * End Element Handler
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
 	public function closing_tag($the_parser, $name)
 	{
 		if ($this->xh[$the_parser]['isf'] > 1) return;
 
 		// Remove current element from stack and set variable
 		// NOTE: If the XML validates, then we do not have to worry about
-		// the opening and closing of elements.  Nesting is checked on the opening
+		// the opening and closing of elements. Nesting is checked on the opening
 		// tag so we be safe there as well.
 
 		$curr_elem = array_shift($this->xh[$the_parser]['stack']);
 
-		switch($name)
+		switch ($name)
 		{
 			case 'STRUCT':
 			case 'ARRAY':
 				$cur_val = array_shift($this->xh[$the_parser]['valuestack']);
-				$this->xh[$the_parser]['value'] = ( ! isset($cur_val['values'])) ? array() : $cur_val['values'];
+				$this->xh[$the_parser]['value'] = isset($cur_val['values']) ? $cur_val['values'] : array();
 				$this->xh[$the_parser]['vt']	= strtolower($name);
-			break;
+				break;
 			case 'NAME':
 				$this->xh[$the_parser]['valuestack'][0]['name'] = $this->xh[$the_parser]['ac'];
-			break;
+				break;
 			case 'BOOLEAN':
 			case 'I4':
 			case 'INT':
@@ -961,60 +1045,43 @@
 			case 'BASE64':
 				$this->xh[$the_parser]['vt'] = strtolower($name);
 
-				if ($name == 'STRING')
+				if ($name === 'STRING')
 				{
 					$this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
 				}
-				elseif ($name=='DATETIME.ISO8601')
+				elseif ($name === 'DATETIME.ISO8601')
 				{
 					$this->xh[$the_parser]['vt']	= $this->xmlrpcDateTime;
 					$this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac'];
 				}
-				elseif ($name=='BASE64')
+				elseif ($name === 'BASE64')
 				{
 					$this->xh[$the_parser]['value'] = base64_decode($this->xh[$the_parser]['ac']);
 				}
-				elseif ($name=='BOOLEAN')
+				elseif ($name === 'BOOLEAN')
 				{
 					// Translated BOOLEAN values to TRUE AND FALSE
-					if ($this->xh[$the_parser]['ac'] == '1')
-					{
-						$this->xh[$the_parser]['value'] = TRUE;
-					}
-					else
-					{
-						$this->xh[$the_parser]['value'] = FALSE;
-					}
+					$this->xh[$the_parser]['value'] = (bool) $this->xh[$the_parser]['ac'];
 				}
 				elseif ($name=='DOUBLE')
 				{
 					// we have a DOUBLE
 					// we must check that only 0123456789-.<space> are characters here
-					if ( ! preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac']))
-					{
-						$this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
-					}
-					else
-					{
-						$this->xh[$the_parser]['value'] = (double)$this->xh[$the_parser]['ac'];
-					}
+					$this->xh[$the_parser]['value'] = preg_match('/^[+-]?[eE0-9\t \.]+$/', $this->xh[$the_parser]['ac'])
+										? (float) $this->xh[$the_parser]['ac']
+										: 'ERROR_NON_NUMERIC_FOUND';
 				}
 				else
 				{
 					// we have an I4/INT
 					// we must check that only 0123456789-<space> are characters here
-					if ( ! preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac']))
-					{
-						$this->xh[$the_parser]['value'] = 'ERROR_NON_NUMERIC_FOUND';
-					}
-					else
-					{
-						$this->xh[$the_parser]['value'] = (int)$this->xh[$the_parser]['ac'];
-					}
+					$this->xh[$the_parser]['value'] = preg_match('/^[+-]?[0-9\t ]+$/', $this->xh[$the_parser]['ac'])
+										? (int) $this->xh[$the_parser]['ac']
+										: 'ERROR_NON_NUMERIC_FOUND';
 				}
 				$this->xh[$the_parser]['ac'] = '';
 				$this->xh[$the_parser]['lv'] = 3; // indicate we've found a value
-			break;
+				break;
 			case 'VALUE':
 				// This if() detects if no scalar was inside <VALUE></VALUE>
 				if ($this->xh[$the_parser]['vt']=='value')
@@ -1026,7 +1093,7 @@
 				// build the XML-RPC value out of the data received, and substitute it
 				$temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']);
 
-				if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY')
+				if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] === 'ARRAY')
 				{
 					// Array
 					$this->xh[$the_parser]['valuestack'][0]['values'][] = $temp;
@@ -1036,57 +1103,62 @@
 					// Struct
 					$this->xh[$the_parser]['value'] = $temp;
 				}
-			break;
+				break;
 			case 'MEMBER':
-				$this->xh[$the_parser]['ac']='';
+				$this->xh[$the_parser]['ac'] = '';
 
 				// If value add to array in the stack for the last element built
 				if ($this->xh[$the_parser]['value'])
 				{
 					$this->xh[$the_parser]['valuestack'][0]['values'][$this->xh[$the_parser]['valuestack'][0]['name']] = $this->xh[$the_parser]['value'];
 				}
-			break;
+				break;
 			case 'DATA':
-				$this->xh[$the_parser]['ac']='';
-			break;
+				$this->xh[$the_parser]['ac'] = '';
+				break;
 			case 'PARAM':
 				if ($this->xh[$the_parser]['value'])
 				{
 					$this->xh[$the_parser]['params'][] = $this->xh[$the_parser]['value'];
 				}
-			break;
+				break;
 			case 'METHODNAME':
 				$this->xh[$the_parser]['method'] = ltrim($this->xh[$the_parser]['ac']);
-			break;
+				break;
 			case 'PARAMS':
 			case 'FAULT':
 			case 'METHODCALL':
 			case 'METHORESPONSE':
 				// We're all good kids with nuthin' to do
-			break;
+				break;
 			default:
-				// End of an Invalid Element.  Taken care of during the opening tag though
-			break;
+				// End of an Invalid Element. Taken care of during the opening tag though
+				break;
 		}
 	}
 
-	//-------------------------------------
-	//  Parses Character Data
-	//-------------------------------------
+	// --------------------------------------------------------------------
 
+	/**
+	 * Parse character data
+	 *
+	 * @param	string
+	 * @param	string
+	 * @return	void
+	 */
 	public function character_data($the_parser, $data)
 	{
 		if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
 
 		// If a value has not been found
-		if ($this->xh[$the_parser]['lv'] != 3)
+		if ($this->xh[$the_parser]['lv'] !== 3)
 		{
-			if ($this->xh[$the_parser]['lv'] == 1)
+			if ($this->xh[$the_parser]['lv'] === 1)
 			{
 				$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'] = '';
 			}
@@ -1095,12 +1167,27 @@
 		}
 	}
 
+	// --------------------------------------------------------------------
 
+	/**
+	 * Add parameter
+	 *
+	 * @param	mixed
+	 * @return	void
+	 */
 	public function addParam($par)
 	{
 		$this->params[] = $par;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Output parameters
+	 *
+	 * @param	array
+	 * @return	array
+	 */
 	public function output_parameters($array = FALSE)
 	{
 		$CI =& get_instance();
@@ -1117,57 +1204,62 @@
 				{
 					// 'bits' is for the MetaWeblog API image bits
 					// @todo - this needs to be made more general purpose
-					$array[$key] = ($key == 'bits' OR $this->xss_clean == FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]);
+					$array[$key] = ($key === 'bits' OR $this->xss_clean === FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]);
 				}
 			}
 
-			$parameters = $array;
+			return $array;
 		}
-		else
+
+		$parameters = array();
+
+		for ($i = 0, $c = count($this->params); $i < $c; $i++)
 		{
-			$parameters = array();
+			$a_param = $this->decode_message($this->params[$i]);
 
-			for ($i = 0, $c = count($this->params); $i < $c; $i++)
+			if (is_array($a_param))
 			{
-				$a_param = $this->decode_message($this->params[$i]);
-
-				if (is_array($a_param))
-				{
-					$parameters[] = $this->output_parameters($a_param);
-				}
-				else
-				{
-					$parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param;
-				}
+				$parameters[] = $this->output_parameters($a_param);
+			}
+			else
+			{
+				$parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param;
 			}
 		}
 
 		return $parameters;
 	}
 
+	// --------------------------------------------------------------------
 
+	/**
+	 * Decode message
+	 *
+	 * @param	object
+	 * @return	mixed
+	 */
 	public function decode_message($param)
 	{
 		$kind = $param->kindOf();
 
-		if ($kind == 'scalar')
+		if ($kind === 'scalar')
 		{
 			return $param->scalarval();
 		}
-		elseif ($kind == 'array')
+		elseif ($kind === 'array')
 		{
 			reset($param->me);
 			$b = current($param->me);
 			$arr = array();
 
-			for($i = 0, $c = count($b); $i < $c; $i++)
+			for ($i = 0, $c = count($b); $i < $c; $i++)
 			{
 				$arr[] = $this->decode_message($param->me['array'][$i]);
 			}
 
 			return $arr;
 		}
-		elseif ($kind == 'struct')
+		elseif ($kind === 'struct')
 		{
 			reset($param->me['struct']);
 			$arr = array();
@@ -1181,8 +1273,7 @@
 		}
 	}
 
-}
-// End XML_RPC_Messages class
+} // END XML_RPC_Message Class
 
 /**
  * XML-RPC Values class
@@ -1196,51 +1287,67 @@
 	public $me	= array();
 	public $mytype	= 0;
 
+	/**
+	 * Constructor
+	 *
+	 * @param	mixed
+	 * @param	string
+	 * @return	void
+	 */
 	public function __construct($val = -1, $type = '')
 	{
 		parent::__construct();
 
-		if ($val != -1 OR $type != '')
+		if ($val !== -1 OR $type !== '')
 		{
-			$type = $type == '' ? 'string' : $type;
+			$type = $type === '' ? 'string' : $type;
 
-			if ($this->xmlrpcTypes[$type] == 1)
+			if ($this->xmlrpcTypes[$type] === 1)
 			{
 				$this->addScalar($val,$type);
 			}
-			elseif ($this->xmlrpcTypes[$type] == 2)
+			elseif ($this->xmlrpcTypes[$type] === 2)
 			{
 				$this->addArray($val);
 			}
-			elseif ($this->xmlrpcTypes[$type] == 3)
+			elseif ($this->xmlrpcTypes[$type] === 3)
 			{
 				$this->addStruct($val);
 			}
 		}
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add scalar value
+	 *
+	 * @param	scalar
+	 * @param	string
+	 * @return	int
+	 */
 	public function addScalar($val, $type = 'string')
 	{
 		$typeof = $this->xmlrpcTypes[$type];
 
-		if ($this->mytype==1)
+		if ($this->mytype === 1)
 		{
 			echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />';
 			return 0;
 		}
 
-		if ($typeof != 1)
+		if ($typeof !== 1)
 		{
 			echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />';
 			return 0;
 		}
 
-		if ($type == $this->xmlrpcBoolean)
+		if ($type === $this->xmlrpcBoolean)
 		{
-			$val = (strcasecmp($val,'true') === 0 OR $val == 1 OR ($val == true && strcasecmp($val, 'false'))) ? 1 : 0;
+			$val = (int) (strcasecmp($val,'true') === 0 OR $val === 1 OR ($val === TRUE && strcasecmp($val, 'false')));
 		}
 
-		if ($this->mytype == 2)
+		if ($this->mytype === 2)
 		{
 			// adding to an array here
 			$ar = $this->me['array'];
@@ -1253,12 +1360,21 @@
 			$this->me[$type] = $val;
 			$this->mytype = $typeof;
 		}
+
 		return 1;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add array value
+	 *
+	 * @param	array
+	 * @return	int
+	 */
 	public function addArray($vals)
 	{
-		if ($this->mytype != 0)
+		if ($this->mytype !== 0)
 		{
 			echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
 			return 0;
@@ -1269,9 +1385,17 @@
 		return 1;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Add struct value
+	 *
+	 * @param	object
+	 * @return	int
+	 */
 	public function addStruct($vals)
 	{
-		if ($this->mytype != 0)
+		if ($this->mytype !== 0)
 		{
 			echo '<strong>XML_RPC_Values</strong>: already initialized as a [' . $this->kindOf() . ']<br />';
 			return 0;
@@ -1281,29 +1405,37 @@
 		return 1;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Get value type
+	 *
+	 * @return	string
+	 */
 	public function kindOf()
 	{
-		switch($this->mytype)
+		switch ($this->mytype)
 		{
-			case 3:
-				return 'struct';
-				break;
-			case 2:
-				return 'array';
-				break;
-			case 1:
-				return 'scalar';
-				break;
-			default:
-				return 'undef';
+			case 3: return 'struct';
+			case 2: return 'array';
+			case 1: return 'scalar';
+			default: return 'undef';
 		}
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Serialize data
+	 *
+	 * @param	string
+	 * @param	mixed
+	 */
 	public function serializedata($typ, $val)
 	{
 		$rs = '';
 
-		switch($this->xmlrpcTypes[$typ])
+		switch ($this->xmlrpcTypes[$typ])
 		{
 			case 3:
 				// struct
@@ -1314,11 +1446,11 @@
 					$rs .= "<member>\n<name>{$key2}</name>\n".$this->serializeval($val2)."</member>\n";
 				}
 				$rs .= '</struct>';
-			break;
+				break;
 			case 2:
 				// array
 				$rs .= "<array>\n<data>\n";
-				for($i = 0, $c = count($val); $i < $c; $i++)
+				for ($i = 0, $c = count($val); $i < $c; $i++)
 				{
 					$rs .= $this->serializeval($val[$i]);
 				}
@@ -1329,29 +1461,45 @@
 				switch ($typ)
 				{
 					case $this->xmlrpcBase64:
-						$rs .= "<{$typ}>" . base64_encode((string)$val) . "</{$typ}>\n";
-					break;
+						$rs .= '<'.$typ.'>'.base64_encode( (string) $val).'</'.$typ.">\n";
+						break;
 					case $this->xmlrpcBoolean:
-						$rs .= "<{$typ}>" . ((bool)$val ? '1' : '0') . "</{$typ}>\n";
-					break;
+						$rs .= '<'.$typ.'>'.( (bool) $val ? '1' : '0').'</'.$typ.">\n";
+						break;
 					case $this->xmlrpcString:
-						$rs .= "<{$typ}>" . htmlspecialchars((string)$val). "</{$typ}>\n";
-					break;
+						$rs .= '<'.$typ.'>'.htmlspecialchars( (string) $val).'</'.$typ.">\n";
+						break;
 					default:
-						$rs .= "<{$typ}>{$val}</{$typ}>\n";
-					break;
+						$rs .= '<'.$typ.'>'.$val.'</'.$typ.">\n";
+						break;
 				}
 			default:
-			break;
+				break;
 		}
+
 		return $rs;
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Serialize class
+	 *
+	 * @return	string
+	 */
 	public function serialize_class()
 	{
 		return $this->serializeval($this);
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Serialize value
+	 *
+	 * @param	object
+	 * @return	string
+	 */
 	public function serializeval($o)
 	{
 		$ar = $o->me;
@@ -1361,26 +1509,35 @@
 		return "<value>\n".$this->serializedata($typ, $val)."</value>\n";
 	}
 
+	// --------------------------------------------------------------------
+
+	/**
+	 * Scalar value
+	 *
+	 * @return	mixed
+	 */
 	public function scalarval()
 	{
 		reset($this->me);
 		return current($this->me);
 	}
 
+	// --------------------------------------------------------------------
 
-	//-------------------------------------
-	// Encode time in ISO-8601 form.
-	//-------------------------------------
-
-	// Useful for sending time in XML-RPC
-
-	public function iso8601_encode($time, $utc = 0)
+	/**
+	 * Encode time in ISO-8601 form.
+	 * Useful for sending time in XML-RPC
+	 *
+	 * @param	int	unix timestamp
+	 * @param	bool
+	 * @return	string
+	*/
+	public function iso8601_encode($time, $utc = FALSE)
 	{
 		return ($utc) ? strftime('%Y%m%dT%H:%i:%s', $time) : gmstrftime('%Y%m%dT%H:%i:%s', $time);
 	}
 
-}
-// END XML_RPC_Values Class
+} // END XML_RPC_Values Class
 
 /* End of file Xmlrpc.php */
-/* Location: ./system/libraries/Xmlrpc.php */
+/* Location: ./system/libraries/Xmlrpc.php */
\ No newline at end of file
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index 6d270c2..be930b0 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -48,12 +48,40 @@
  */
 class CI_Xmlrpcs extends CI_Xmlrpc
 {
-	public $methods		= array();	//array of methods mapped to function names and signatures
-	public $debug_msg	= '';		// Debug Message
-	public $system_methods	= array();	// XML RPC Server methods
-	public $controller_obj;
-	public $object		= FALSE;
+	/**
+	 * array of methods mapped to function names and signatures
+	 *
+	 * @var array
+	 */
+	public $methods = array();
 
+	/**
+	 * Debug Message
+	 *
+	 * @var string
+	 */
+	public $debug_msg = '';
+
+	/**
+	 * XML RPC Server methods
+	 *
+	 * @var array
+	 */
+	public $system_methods	= array();
+
+	/**
+	 * Configuration object
+	 *
+	 * @var object
+	 */
+	public $object = FALSE;
+
+	/**
+	 * Initialize XMLRPC class
+	 *
+	 * @param	array	$config
+	 * @return	void
+	 */
 	public function __construct($config = array())
 	{
 		parent::__construct();
@@ -180,7 +208,7 @@
 		//  Get Data
 		//-------------------------------------
 
-		if ($data == '')
+		if ($data === '')
 		{
 			$data = $HTTP_RAW_POST_DATA;
 		}
@@ -277,7 +305,7 @@
 		// Check to see if it is a system call
 		$system_call = (strncmp($methName, 'system', 5) === 0);
 
-		if ($this->xss_clean == FALSE)
+		if ($this->xss_clean === FALSE)
 		{
 			$m->xss_clean = FALSE;
 		}
@@ -296,7 +324,7 @@
 		//-------------------------------------
 
 		$method_parts = explode('.', $this->methods[$methName]['function']);
-		$objectCall = (isset($method_parts[1]) && $method_parts[1] != '');
+		$objectCall = (isset($method_parts[1]) && $method_parts[1] !== '');
 
 		if ($system_call === TRUE)
 		{
@@ -328,9 +356,9 @@
 					for ($n = 0, $mc = count($m->params); $n < $mc; $n++)
 					{
 						$p = $m->params[$n];
-						$pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
+						$pt = ($p->kindOf() === 'scalar') ? $p->scalarval() : $p->kindOf();
 
-						if ($pt != $current_sig[$n+1])
+						if ($pt !== $current_sig[$n+1])
 						{
 							$pno = $n+1;
 							$wanted = $current_sig[$n+1];
@@ -499,7 +527,7 @@
 
 			$attempt = $this->_execute($m);
 
-			if ($attempt->faultCode() != 0)
+			if ($attempt->faultCode() !== 0)
 			{
 				return $attempt;
 			}
@@ -539,7 +567,7 @@
 	 */
 	public function do_multicall($call)
 	{
-		if ($call->kindOf() != 'struct')
+		if ($call->kindOf() !== 'struct')
 		{
 			return $this->multicall_error('notstruct');
 		}
@@ -549,13 +577,13 @@
 		}
 
 		list($scalar_type,$scalar_value)=each($methName->me);
-		$scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
+		$scalar_type = $scalar_type === $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type;
 
-		if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string')
+		if ($methName->kindOf() !== 'scalar' OR $scalar_type !== 'string')
 		{
 			return $this->multicall_error('notstring');
 		}
-		elseif ($scalar_value == 'system.multicall')
+		elseif ($scalar_value === 'system.multicall')
 		{
 			return $this->multicall_error('recursion');
 		}
@@ -563,7 +591,7 @@
 		{
 			return $this->multicall_error('noparams');
 		}
-		elseif ($params->kindOf() != 'array')
+		elseif ($params->kindOf() !== 'array')
 		{
 			return $this->multicall_error('notarray');
 		}
@@ -578,7 +606,7 @@
 
 		$result = $this->_execute($msg);
 
-		if ($result->faultCode() != 0)
+		if ($result->faultCode() !== 0)
 		{
 			return $this->multicall_error($result);
 		}
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index e91e2a2..e0dc637 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -42,13 +42,53 @@
  */
 class CI_Zip  {
 
+	/**
+	 * Zip data in string form
+	 *
+	 * @var string
+	 */
 	public $zipdata		= '';
+
+	/**
+	 * Zip data for a directory in string form
+	 *
+	 * @var string
+	 */
 	public $directory	= '';
+
+	/**
+	 * Number of files/folder in zip file
+	 *
+	 * @var int
+	 */
 	public $entries		= 0;
+
+	/**
+	 * Number of files in zip
+	 *
+	 * @var int
+	 */
 	public $file_num	= 0;
+
+	/**
+	 * relative offset of local header
+	 *
+	 * @var int
+	 */
 	public $offset		= 0;
+
+	/**
+	 * Reference to time at init
+	 *
+	 * @var int
+	 */
 	public $now;
 
+	/**
+	 * Initialize zip compression class
+	 *
+	 * @return	void
+	 */
 	public function __construct()
 	{
 		$this->now = time();
@@ -279,7 +319,7 @@
 	 */
 	public function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL)
 	{
-		$path = rtrim($path, '/\\').'/';
+		$path = rtrim($path, '/\\').DIRECTORY_SEPARATOR;
 		if ( ! $fp = @opendir($path))
 		{
 			return FALSE;
@@ -288,7 +328,7 @@
 		// Set the original directory root for child dir's to use as relative
 		if ($root_path === NULL)
 		{
-			$root_path = dirname($path).'/';
+			$root_path = dirname($path).DIRECTORY_SEPARATOR;
 		}
 
 		while (FALSE !== ($file = readdir($fp)))
@@ -300,11 +340,11 @@
 
 			if (@is_dir($path.$file))
 			{
-				$this->read_dir($path.$file.'/', $preserve_filepath, $root_path);
+				$this->read_dir($path.$file.DIRECTORY_SEPARATOR, $preserve_filepath, $root_path);
 			}
 			elseif (FALSE !== ($data = file_get_contents($path.$file)))
 			{
-				$name = str_replace('\\', '/', $path);
+				$name = str_replace(array('\\', '/'), DIRECTORY_SEPARATOR, $path);
 				if ($preserve_filepath === FALSE)
 				{
 					$name = str_replace($root_path, '', $name);
diff --git a/system/libraries/javascript/Jquery.php b/system/libraries/javascript/Jquery.php
index f30d7c6..44c16b5 100644
--- a/system/libraries/javascript/Jquery.php
+++ b/system/libraries/javascript/Jquery.php
@@ -25,8 +25,6 @@
  * @filesource
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Jquery Class
  *
@@ -57,7 +55,7 @@
 			$this->script();
 		}
 
-		log_message('debug', "Jquery Class Initialized");
+		log_message('debug', 'Jquery Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -115,7 +113,7 @@
 
 		if ($ret_false)
 		{
-			$js[] = "return false;";
+			$js[] = 'return false;';
 		}
 
 		return $this->_add_event($element, $js, 'click');
@@ -183,7 +181,7 @@
 	 */
 	protected function _hover($element = 'this', $over, $out)
 	{
-		$event = "\n\t$(" . $this->_prep_element($element) . ").hover(\n\t\tfunction()\n\t\t{\n\t\t\t{$over}\n\t\t}, \n\t\tfunction()\n\t\t{\n\t\t\t{$out}\n\t\t});\n";
+		$event = "\n\t$(".$this->_prep_element($element).").hover(\n\t\tfunction()\n\t\t{\n\t\t\t{$over}\n\t\t}, \n\t\tfunction()\n\t\t{\n\t\t\t{$out}\n\t\t});\n";
 
 		$this->jquery_code_for_compile[] = $event;
 
@@ -322,7 +320,7 @@
 
 		foreach ($array_js as $js)
 		{
-			$this->jquery_code_for_compile[] = "\t$js\n";
+			$this->jquery_code_for_compile[] = "\t".$js."\n";
 		}
 	}
 
@@ -389,7 +387,7 @@
 	protected function _addClass($element = 'this', $class='')
 	{
 		$element = $this->_prep_element($element);
-		return "$({$element}).addClass(\"$class\");";
+		return '$('.$element.').addClass("'.$class.'");';
 	}
 
 	// --------------------------------------------------------------------
@@ -411,24 +409,24 @@
 
 		$animations = "\t\t\t";
 
-		foreach ($params as $param=>$value)
+		foreach ($params as $param => $value)
 		{
-			$animations .= $param.': \''.$value.'\', ';
+			$animations .= $param.": '".$value."', ";
 		}
 
 		$animations = substr($animations, 0, -2); // remove the last ", "
 
-		if ($speed != '')
+		if ($speed !== '')
 		{
 			$speed = ', '.$speed;
 		}
 
-		if ($extra != '')
+		if ($extra !== '')
 		{
 			$extra = ', '.$extra;
 		}
 
-		return "$({$element}).animate({\n$animations\n\t\t}".$speed.$extra.");";
+		return "$({$element}).animate({\n$animations\n\t\t}".$speed.$extra.');';
 	}
 
 	// --------------------------------------------------------------------
@@ -448,7 +446,7 @@
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
 
-		if ($callback != '')
+		if ($callback !== '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
@@ -473,12 +471,12 @@
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
 
-		if ($callback != '')
+		if ($callback !== '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
 
-		return "$({$element}).fadeOut({$speed}{$callback});";
+		return '$('.$element.').fadeOut('.$speed.$callback.');';
 	}
 
 	// --------------------------------------------------------------------
@@ -498,7 +496,7 @@
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
 
-		if ($callback != '')
+		if ($callback !== '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
@@ -519,7 +517,7 @@
 	protected function _removeClass($element = 'this', $class='')
 	{
 		$element = $this->_prep_element($element);
-		return "$({$element}).removeClass(\"$class\");";
+		return '$('.$element.').removeClass("'.$class.'");';
 	}
 
 	// --------------------------------------------------------------------
@@ -539,12 +537,12 @@
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
 
-		if ($callback != '')
+		if ($callback !== '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
 
-		return "$({$element}).slideUp({$speed}{$callback});";
+		return '$('.$element.').slideUp('.$speed.$callback.');';
 	}
 
 	// --------------------------------------------------------------------
@@ -564,12 +562,12 @@
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
 
-		if ($callback != '')
+		if ($callback !== '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
 
-		return "$({$element}).slideDown({$speed}{$callback});";
+		return '$('.$element.').slideDown('.$speed.$callback.');';
 	}
 
 	// --------------------------------------------------------------------
@@ -589,12 +587,12 @@
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
 
-		if ($callback != '')
+		if ($callback !== '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
 
-		return "$({$element}).slideToggle({$speed}{$callback});";
+		return '$('.$element.').slideToggle('.$speed.$callback.');';
 	}
 
 	// --------------------------------------------------------------------
@@ -610,7 +608,7 @@
 	protected function _toggle($element = 'this')
 	{
 		$element = $this->_prep_element($element);
-		return "$({$element}).toggle();";
+		return '$('.$element.').toggle();';
 	}
 
 	// --------------------------------------------------------------------
@@ -626,7 +624,7 @@
 	protected function _toggleClass($element = 'this', $class='')
 	{
 		$element = $this->_prep_element($element);
-		return "$({$element}).toggleClass(\"$class\");";
+		return '$('.$element.').toggleClass("'.$class.'");';
 	}
 
 	// --------------------------------------------------------------------
@@ -646,12 +644,12 @@
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
 
-		if ($callback != '')
+		if ($callback !== '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
 
-		return "$({$element}).show({$speed}{$callback});";
+		return '$('.$element.').show('.$speed.$callback.');';
 	}
 
 	// --------------------------------------------------------------------
@@ -674,24 +672,24 @@
 		$controller = (strpos('://', $controller) === FALSE) ? $controller : $this->CI->config->site_url($controller);
 
 		// ajaxStart and ajaxStop are better choices here... but this is a stop gap
-		if ($this->CI->config->item('javascript_ajax_img') == '')
+		if ($this->CI->config->item('javascript_ajax_img') === '')
 		{
-			$loading_notifier = "Loading...";
+			$loading_notifier = 'Loading...';
 		}
 		else
 		{
-			$loading_notifier = '<img src=\''.$this->CI->config->slash_item('base_url').$this->CI->config->item('javascript_ajax_img').'\' alt=\'Loading\' />';
+			$loading_notifier = '<img src="'.$this->CI->config->slash_item('base_url').$this->CI->config->item('javascript_ajax_img').'" alt="Loading" />';
 		}
 
-		$updater = "$($container).empty();\n" // anything that was in... get it out
-			. "\t\t$($container).prepend(\"$loading_notifier\");\n"; // to replace with an image
+		$updater = '$('.$container.").empty();\n" // anything that was in... get it out
+			."\t\t$(".$container.').prepend("'.$loading_notifier."\");\n"; // to replace with an image
 
 		$request_options = '';
-		if ($options != '')
+		if ($options !== '')
 		{
 			$request_options .= ', {'
-					. (is_array($options) ? "'".implode("', '", $options)."'" : "'".str_replace(":", "':'", $options)."'")
-					. '}';
+					.(is_array($options) ? "'".implode("', '", $options)."'" : "'".str_replace(':', "':'", $options)."'")
+					.'}';
 		}
 
 		return $updater."\t\t$($container).load('$controller'$request_options);";
@@ -711,12 +709,12 @@
 	 */
 	protected function _zebraTables($class = '', $odd = 'odd', $hover = '')
 	{
-		$class = ($class != '') ? '.'.$class : '';
+		$class = ($class !== '') ? '.'.$class : '';
 		$zebra  = "\t\$(\"table{$class} tbody tr:nth-child(even)\").addClass(\"{$odd}\");";
 
 		$this->jquery_code_for_compile[] = $zebra;
 
-		if ($hover != '')
+		if ($hover !== '')
 		{
 			$hover = $this->hover("table{$class} tbody tr", "$(this).addClass('hover');", "$(this).removeClass('hover');");
 		}
@@ -741,12 +739,12 @@
 		// may want to make this configurable down the road
 		$corner_location = '/plugins/jquery.corner.js';
 
-		if ($corner_style != '')
+		if ($corner_style !== '')
 		{
 			$corner_style = '"'.$corner_style.'"';
 		}
 
-		return "$(" . $this->_prep_element($element) . ").corner(".$corner_style.");";
+		return '$('.$this->_prep_element($element).').corner('.$corner_style.');';
 	}
 
 	// --------------------------------------------------------------------
@@ -821,16 +819,16 @@
 			$sort_options = array();
 			foreach ($options as $k=>$v)
 			{
-				$sort_options[] = "\n\t\t".$k.': '.$v."";
+				$sort_options[] = "\n\t\t".$k.': '.$v;
 			}
-			$sort_options = implode(",", $sort_options);
+			$sort_options = implode(',', $sort_options);
 		}
 		else
 		{
 			$sort_options = '';
 		}
 
-		return "$(" . $this->_prep_element($element) . ").sortable({".$sort_options."\n\t});";
+		return '$('.$this->_prep_element($element).').sortable({'.$sort_options."\n\t});";
 	}
 
 	// --------------------------------------------------------------------
@@ -844,7 +842,7 @@
 	 */
 	public function tablesorter($table = '', $options = '')
 	{
-		$this->jquery_code_for_compile[] = "\t$(" . $this->_prep_element($table) . ").tablesorter($options);\n";
+		$this->jquery_code_for_compile[] = "\t$(".$this->_prep_element($table).').tablesorter('.$options.");\n";
 	}
 
 	// --------------------------------------------------------------------
@@ -869,7 +867,7 @@
 
 		}
 
-		$event = "\n\t$(" . $this->_prep_element($element) . ").{$event}(function(){\n\t\t{$js}\n\t});\n";
+		$event = "\n\t$(".$this->_prep_element($element).').'.$event."(function(){\n\t\t{$js}\n\t});\n";
 		$this->jquery_code_for_compile[] = $event;
 		return $event;
 	}
@@ -898,8 +896,8 @@
 
 		// Inline references
 		$script = '$(document).ready(function() {'."\n"
-			. implode('', $this->jquery_code_for_compile)
-			. '});';
+			.implode('', $this->jquery_code_for_compile)
+			.'});';
 
 		$output = ($script_tags === FALSE) ? $script : $this->inline($script);
 
@@ -974,7 +972,7 @@
 	 */
 	protected function _prep_element($element)
 	{
-		if ($element != 'this')
+		if ($element !== 'this')
 		{
 			$element = '"'.$element.'"';
 		}
@@ -998,7 +996,7 @@
 		{
 			return '"'.$speed.'"';
 		}
-		elseif (preg_match("/[^0-9]/", $speed))
+		elseif (preg_match('/[^0-9]/', $speed))
 		{
 			return '';
 		}
@@ -1009,4 +1007,4 @@
 }
 
 /* End of file Jquery.php */
-/* Location: ./system/libraries/Jquery.php */
+/* Location: ./system/libraries/Jquery.php */
\ No newline at end of file