Merged with latest commit
diff --git a/.travis.yml b/.travis.yml
index 405d0a9..c5a9993 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,4 +10,4 @@
   - pyrus install http://pear.php-tools.net/get/vfsStream-0.11.2.tgz
   - phpenv rehash
 
-script: phpunit --configuration tests/phpunit.xml
\ No newline at end of file
+script: phpunit --configuration phpunit.xml
\ No newline at end of file
diff --git a/application/config/autoload.php b/application/config/autoload.php
index a45567b..db49ca1 100644
--- a/application/config/autoload.php
+++ b/application/config/autoload.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/config.php b/application/config/config.php
index 063c3d5..17b854b 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
@@ -326,12 +326,14 @@
 | 'csrf_token_name' = The token name
 | 'csrf_cookie_name' = The cookie name
 | 'csrf_expire' = The number in seconds the token should expire.
+| 'csrf_regenerate' = Regenerate token on every submission
 | 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
 */
 $config['csrf_protection'] = FALSE;
 $config['csrf_token_name'] = 'csrf_test_name';
 $config['csrf_cookie_name'] = 'csrf_cookie_name';
 $config['csrf_expire'] = 7200;
+$config['csrf_regenerate'] = TRUE;
 $config['csrf_exclude_uris'] = array();
 
 /*
diff --git a/application/config/constants.php b/application/config/constants.php
index 3b79a03..c7203e4 100644
--- a/application/config/constants.php
+++ b/application/config/constants.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/database.php b/application/config/database.php
index 880773d..bd68db1 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
@@ -37,6 +37,7 @@
 | EXPLANATION OF VARIABLES
 | -------------------------------------------------------------------
 |
+|	['dsn']      The full DSN string describe a connection to the database.
 |	['hostname'] The hostname of your database server.
 |	['username'] The username used to connect to the database
 |	['password'] The password used to connect to the database
@@ -74,13 +75,14 @@
 $active_group = 'default';
 $active_record = TRUE;
 
+$db['default']['dsn']      = '';
 $db['default']['hostname'] = 'localhost';
 $db['default']['username'] = '';
 $db['default']['password'] = '';
 $db['default']['database'] = '';
 $db['default']['dbdriver'] = 'mysql';
 $db['default']['dbprefix'] = '';
-$db['default']['pconnect'] = TRUE;
+$db['default']['pconnect'] = FALSE;
 $db['default']['db_debug'] = TRUE;
 $db['default']['cache_on'] = FALSE;
 $db['default']['cachedir'] = '';
diff --git a/application/config/doctypes.php b/application/config/doctypes.php
index 48ccc05..984da59 100644
--- a/application/config/doctypes.php
+++ b/application/config/doctypes.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/foreign_chars.php b/application/config/foreign_chars.php
index 6917623..1ae0cef 100644
--- a/application/config/foreign_chars.php
+++ b/application/config/foreign_chars.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/hooks.php b/application/config/hooks.php
index 000ae51..80269df 100644
--- a/application/config/hooks.php
+++ b/application/config/hooks.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/memcached.php b/application/config/memcached.php
new file mode 100644
index 0000000..2b1a772
--- /dev/null
+++ b/application/config/memcached.php
@@ -0,0 +1,46 @@
+<?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 Academic Free License version 3.0
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0) that is
+ * bundled with this package in the files license_afl.txt / license_afl.rst.
+ * It is also available through the world wide web at this URL:
+ * http://opensource.org/licenses/AFL-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/AFL-3.0 Academic Free License (AFL 3.0)
+ * @link		http://codeigniter.com
+ * @since		Version 2.0
+ * @filesource
+ */
+
+/*
+| -------------------------------------------------------------------------
+| Memcached settings
+| -------------------------------------------------------------------------
+| Your Memcached servers can be specified below.
+|
+|	See: http://codeigniter.com/user_guide/libraries/caching.html#memcached
+|
+*/
+$config = array(
+	'default' => array(
+		'hostname' => '127.0.0.1',
+		'port'     => '11211',
+		'weight'   => '1',
+	),
+);
+
+/* End of file memcached.php */
+/* Location: ./application/config/memcached.php */
\ No newline at end of file
diff --git a/application/config/migration.php b/application/config/migration.php
index 4fb027b..668c357 100644
--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/mimes.php b/application/config/mimes.php
index c43f1fc..d69497a 100644
--- a/application/config/mimes.php
+++ b/application/config/mimes.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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 Academic Free License version 3.0
- * 
+ *
  * This source file is subject to the Academic Free License (AFL 3.0) that is
  * bundled with this package in the files license_afl.txt / license_afl.rst.
  * It is also available through the world wide web at this URL:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
@@ -111,8 +111,8 @@
 				'log'	=>	array('text/plain', 'text/x-log'),
 				'rtx'	=>	'text/richtext',
 				'rtf'	=>	'text/rtf',
-				'xml'	=>	'text/xml',
-				'xsl'	=>	'text/xml',
+				'xml'	=>	array('application/xml', 'text/xml'),
+				'xsl'	=>	array('application/xml', 'text/xsl', 'text/xml'),
 				'mpeg'	=>	'video/mpeg',
 				'mpg'	=>	'video/mpeg',
 				'mpe'	=>	'video/mpeg',
@@ -120,9 +120,9 @@
 				'mov'	=>	'video/quicktime',
 				'avi'	=>	array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'),
 				'movie'	=>	'video/x-sgi-movie',
-				'doc'	=>	'application/msword',
-				'docx'	=>	'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
-				'xlsx'	=>	'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+				'doc'	=>	array('application/msword', 'application/vnd.ms-office'),
+				'docx'	=>	array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'),
+				'xlsx'	=>	array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip'),
 				'word'	=>	array('application/msword', 'application/octet-stream'),
 				'xl'	=>	'application/excel',
 				'eml'	=>	'message/rfc822',
@@ -160,8 +160,9 @@
 				'ac3'   =>	'audio/ac3',
 				'flac'  =>	'audio/x-flac',
 				'ogg'   =>	'audio/ogg',
+				'kmz'	=>	array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'),
+				'kml'	=>	array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml')
 			);
 
-
 /* End of file mimes.php */
 /* Location: ./application/config/mimes.php */
diff --git a/application/config/profiler.php b/application/config/profiler.php
index b0bd2cd..f956142 100644
--- a/application/config/profiler.php
+++ b/application/config/profiler.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/routes.php b/application/config/routes.php
index b7f4056..53fc7e7 100644
--- a/application/config/routes.php
+++ b/application/config/routes.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/smileys.php b/application/config/smileys.php
index ada329a..4132aed 100644
--- a/application/config/smileys.php
+++ b/application/config/smileys.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/config/user_agents.php b/application/config/user_agents.php
index 7f5fe81..e7a6894 100644
--- a/application/config/user_agents.php
+++ b/application/config/user_agents.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/controllers/welcome.php b/application/controllers/welcome.php
index 0757f2d..5eb0e96 100644
--- a/application/controllers/welcome.php
+++ b/application/controllers/welcome.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/errors/error_404.php b/application/errors/error_404.php
index eb98deb..4dd8fc4 100644
--- a/application/errors/error_404.php
+++ b/application/errors/error_404.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/errors/error_db.php b/application/errors/error_db.php
index a53c389..130ffc1 100644
--- a/application/errors/error_db.php
+++ b/application/errors/error_db.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/errors/error_general.php b/application/errors/error_general.php
index 7d9a29f..2a844a8 100644
--- a/application/errors/error_general.php
+++ b/application/errors/error_general.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/errors/error_php.php b/application/errors/error_php.php
index 1bf2454..8e293cd 100644
--- a/application/errors/error_php.php
+++ b/application/errors/error_php.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/application/views/welcome_message.php b/application/views/welcome_message.php
index 7090453..acc36b6 100644
--- a/application/views/welcome_message.php
+++ b/application/views/welcome_message.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
  * @license		http://opensource.org/licenses/AFL-3.0 Academic Free License (AFL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 1.0
diff --git a/index.php b/index.php
index 08e5d6d..a378266 100644
--- a/index.php
+++ b/index.php
@@ -5,9 +5,9 @@
  * 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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -41,7 +41,6 @@
  *     production
  *
  * NOTE: If you change these, also change the error_reporting() code below
- *
  */
 	define('ENVIRONMENT', 'development');
 /*
@@ -60,12 +59,10 @@
 		case 'development':
 			error_reporting(-1);
 		break;
-	
 		case 'testing':
 		case 'production':
 			error_reporting(0);
 		break;
-
 		default:
 			exit('The application environment is not set correctly.');
 	}
@@ -79,7 +76,6 @@
  * This variable must contain the name of your "system" folder.
  * Include the path if the folder is not in the same  directory
  * as this file.
- *
  */
 	$system_path = 'system';
 
@@ -90,30 +86,28 @@
  *
  * If you want this front controller to use a different "application"
  * folder then the default one you can set its name here. The folder
- * can also be renamed or relocated anywhere on your server.  If
+ * can also be renamed or relocated anywhere on your server. If
  * you do, use a full server path. For more info please see the user guide:
  * http://codeigniter.com/user_guide/general/managing_apps.html
  *
  * NO TRAILING SLASH!
- *
  */
 	$application_folder = 'application';
-		
+
 /*
  *---------------------------------------------------------------
  * VIEW FOLDER NAME
  *---------------------------------------------------------------
- * 
- * If you want to move the view folder out of the application 
+ *
+ * If you want to move the view folder out of the application
  * folder set the path to the folder here. The folder can be renamed
- * and relocated anywhere on your server. If blank, it will default 
- * to the standard location inside your application folder.  If you 
- * do move this, use the full server path to this folder 
+ * and relocated anywhere on your server. If blank, it will default
+ * to the standard location inside your application folder. If you
+ * do move this, use the full server path to this folder.
  *
  * NO TRAILING SLASH!
- *
  */
-	$view_folder = '';	
+	$view_folder = '';
 
 
 /*
@@ -123,18 +117,17 @@
  *
  * Normally you will set your default controller in the routes.php file.
  * You can, however, force a custom routing by hard-coding a
- * specific controller class/function here.  For most applications, you
+ * specific controller class/function here. For most applications, you
  * WILL NOT set your routing here, but it's an option for those
  * special instances where you might want to override the standard
  * routing in a specific front controller that shares a common CI installation.
  *
- * IMPORTANT:  If you set the routing here, NO OTHER controller will be
+ * IMPORTANT: If you set the routing here, NO OTHER controller will be
  * callable. In essence, this preference limits your application to ONE
- * specific controller.  Leave the function name blank if you need
+ * specific controller. Leave the function name blank if you need
  * to call functions dynamically via the URI.
  *
  * Un-comment the $routing array below to use this feature
- *
  */
 	// The directory name, relative to the "controllers" folder.  Leave blank
 	// if your controller is not in a sub-folder within the "controllers" folder
@@ -160,7 +153,6 @@
  * config values.
  *
  * Un-comment the $assign_to_config array below to use this feature
- *
  */
 	// $assign_to_config['name_of_config_item'] = 'value of config item';
 
@@ -193,7 +185,7 @@
 	// Is the system path correct?
 	if ( ! is_dir($system_path))
 	{
-		exit("Your system folder path does not appear to be set correctly. Please open the following file and correct this: ".pathinfo(__FILE__, PATHINFO_BASENAME));
+		exit('Your system folder path does not appear to be set correctly. Please open the following file and correct this: '.pathinfo(__FILE__, PATHINFO_BASENAME));
 	}
 
 /*
@@ -209,7 +201,7 @@
 	define('EXT', '.php');
 
 	// Path to the system folder
-	define('BASEPATH', str_replace("\\", "/", $system_path));
+	define('BASEPATH', str_replace('\\', '/', $system_path));
 
 	// Path to the front controller (this file)
 	define('FCPATH', str_replace(SELF, '', __FILE__));
@@ -217,7 +209,6 @@
 	// Name of the "system folder"
 	define('SYSDIR', trim(strrchr(trim(BASEPATH, '/'), '/'), '/'));
 
-
 	// The path to the "application" folder
 	if (is_dir($application_folder))
 	{
@@ -227,27 +218,28 @@
 	{
 		if ( ! is_dir(BASEPATH.$application_folder.'/'))
 		{
-			exit("Your application folder path does not appear to be set correctly. Please open the following file and correct this: ".SELF);
+			header('HTTP/1.1 503 Service Unavailable.', TRUE, '503');
+			exit('Your application folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF);
 		}
 
 		define('APPPATH', BASEPATH.$application_folder.'/');
 	}
-	
+
 	// The path to the "views" folder
-	if (is_dir($view_folder)) 
+	if (is_dir($view_folder))
 	{
 		define ('VIEWPATH', $view_folder .'/');
 	}
-	else 
+	else
 	{
 		if ( ! is_dir(APPPATH.'views/'))
 		{
-			exit("Your view folder path does not appear to be set correctly. Please open the following file and correct this: ".SELF);
+			header('HTTP/1.1 503 Service Unavailable.', TRUE, '503');
+			exit('Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF);
 		}
-				
-		define ('VIEWPATH', APPPATH.'views/' );	
+
+		define ('VIEWPATH', APPPATH.'views/' );
 	}
-	
 
 /*
  * --------------------------------------------------------------------
@@ -255,9 +247,8 @@
  * --------------------------------------------------------------------
  *
  * And away we go...
- *
  */
 require_once BASEPATH.'core/CodeIgniter.php';
 
 /* End of file index.php */
-/* Location: ./index.php */
\ No newline at end of file
+/* Location: ./index.php */
diff --git a/license.rst b/license.rst
deleted file mode 100644
index 17179a9..0000000
--- a/license.rst
+++ /dev/null
@@ -1,245 +0,0 @@
-###################################
-Open Software License ("OSL") v 3.0
-###################################
-
-This Open Software License (the "License") applies to any original work of
-authorship (the "Original Work") whose owner (the "Licensor") has placed the
-following licensing notice adjacent to the copyright notice for the Original
-Work:
-
-*Licensed under the Open Software License version 3.0*
-
-
-*****************************
-1) Grant of Copyright License
-*****************************
-
-Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable
-license, for the duration of the copyright, to do the following:
-
-	*a)* to reproduce the Original Work in copies, either alone or as part of
-	a collective work;
-
-	*b)* to translate, adapt, alter, transform, modify, or arrange the
-	Original Work, thereby creating derivative works ("Derivative Works")
-	based upon the Original Work;
-
-	*c)* to distribute or communicate copies of the Original Work and
-	Derivative Works to the public, *with the proviso that copies of Original
-	Work or Derivative Works that You distribute or communicate shall be
-	licensed under this Open Software License*;
-
-	*d)* to perform the Original Work publicly; and
-
-	*e)* to display the Original Work publicly.
-
-
-**************************
-2) Grant of Patent License
-**************************
-
-Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable
-license, under patent claims owned or controlled by the Licensor that are
-embodied in the Original Work as furnished by the Licensor, for the duration
-of the patents, to make, use, sell, offer for sale, have made, and import the
-Original Work and Derivative Works.
-
-
-*******************************
-3) Grant of Source Code License
-*******************************
-
-The term "Source Code" means the preferred form of the Original Work for
-making modifications to it and all available documentation describing how to
-modify the Original Work. Licensor agrees to provide a machine-readable copy
-of the Source Code of the Original Work along with each copy of the Original
-Work that Licensor distributes. Licensor reserves the right to satisfy this
-obligation by placing a machine-readable copy of the Source Code in an
-information repository reasonably calculated to permit inexpensive and
-convenient access by You for as long as Licensor continues to distribute the
-Original Work.
-
-
-********************************
-4) Exclusions From License Grant
-********************************
-
-Neither the names of Licensor, nor the names of any contributors to the
-Original Work, nor any of their trademarks or service marks, may be used to
-endorse or promote products derived from this Original Work without express
-prior permission of the Licensor. Except as expressly stated herein, nothing
-in this License grants any license to Licensor's trademarks, copyrights,
-patents, trade secrets or any other intellectual property. No patent license
-is granted to make, use, sell, offer for sale, have made, or import
-embodiments of any patent claims other than the licensed claims defined in
-Section 2) No license is granted to the trademarks of Licensor even if such
-marks are included in the Original Work. Nothing in this License shall be
-interpreted to prohibit Licensor from licensing under terms different from
-this License any Original Work that Licensor otherwise would have a right to
-license.
-
-
-**********************
-5) External Deployment
-**********************
-
-The term "External Deployment" means the use, distribution, or communication
-of the Original Work or Derivative Works in any way such that the Original
-Work or Derivative Works may be used by anyone other than You, whether those
-works are distributed or communicated to those persons or made available as an
-application intended for use over a network. As an express condition for the
-grants of license hereunder, You must treat any External Deployment by You of
-the Original Work or a Derivative Work as a distribution under section 1(c).
-
-
-*********************
-6) Attribution Rights
-*********************
-
-You must retain, in the Source Code of any Derivative Works that You create,
-all copyright, patent, or trademark notices from the Source Code of the
-Original Work, as well as any notices of licensing and any descriptive text
-identified therein as an "Attribution Notice." You must cause the Source Code
-for any Derivative Works that You create to carry a prominent Attribution
-Notice reasonably calculated to inform recipients that You have modified the
-Original Work.
-
-
-****************************************************
-7) Warranty of Provenance and Disclaimer of Warranty
-****************************************************
-
-Licensor warrants that the copyright in and to the Original Work and the
-patent rights granted herein by Licensor are owned by the Licensor or are
-sublicensed to You under the terms of this License with the permission of the
-contributor(s) of those copyrights and patent rights. Except as expressly
-stated in the immediately preceding sentence, the Original Work is provided
-under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or
-implied, including, without limitation, the warranties of non-infringement,
-merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE
-QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY
-constitutes an essential part of this License. No license to the Original Work
-is granted by this License except under this disclaimer.
-
-
-**************************
-8) Limitation of Liability
-**************************
-
-Under no circumstances and under no legal theory, whether in tort (including
-negligence), contract, or otherwise, shall the Licensor be liable to anyone
-for any indirect, special, incidental, or consequential damages of any
-character arising as a result of this License or the use of the Original Work
-including, without limitation, damages for loss of goodwill, work stoppage,
-computer failure or malfunction, or any and all other commercial damages or
-losses. This limitation of liability shall not apply to the extent applicable
-law prohibits such limitation.
-
-
-*****************************
-9) Acceptance and Termination
-*****************************
-
-If, at any time, You expressly assented to this License, that assent indicates
-your clear and irrevocable acceptance of this License and all of its terms and
-conditions. If You distribute or communicate copies of the Original Work or a
-Derivative Work, You must make a reasonable effort under the circumstances to
-obtain the express assent of recipients to the terms of this License. This
-License conditions your rights to undertake the activities listed in Section
-1, including your right to create Derivative Works based upon the Original
-Work, and doing so without honoring these terms and conditions is prohibited
-by copyright law and international treaty. Nothing in this License is intended
-to affect copyright exceptions and limitations (including "fair use" or "fair
-dealing"). This License shall terminate immediately and You may no longer
-exercise any of the rights granted to You by this License upon your failure to
-honor the conditions in Section 1(c).
-
-
-*********************************
-10) Termination for Patent Action
-*********************************
-
-This License shall terminate automatically and You may no longer exercise any
-of the rights granted to You by this License as of the date You commence an
-action, including a cross-claim or counterclaim, against Licensor or any
-licensee alleging that the Original Work infringes a patent. This termination
-provision shall not apply for an action alleging patent infringement by
-combinations of the Original Work with other software or hardware.
-
-
-*****************************************
-11) Jurisdiction, Venue and Governing Law
-*****************************************
-
-Any action or suit relating to this License may be brought only in the courts
-of a jurisdiction wherein the Licensor resides or in which Licensor conducts
-its primary business, and under the laws of that jurisdiction excluding its
-conflict-of-law provisions. The application of the United Nations Convention
-on Contracts for the International Sale of Goods is expressly excluded. Any
-use of the Original Work outside the scope of this License or after its
-termination shall be subject to the requirements and penalties of copyright or
-patent law in the appropriate jurisdiction. This section shall survive the
-termination of this License.
-
-
-*******************
-12) Attorneys' Fees
-*******************
-
-In any action to enforce the terms of this License or seeking damages relating
-thereto, the prevailing party shall be entitled to recover its costs and
-expenses, including, without limitation, reasonable attorneys' fees and costs
-incurred in connection with such action, including any appeal of such action.
-This section shall survive the termination of this License.
-
-
-*****************
-13) Miscellaneous
-*****************
-
-If any provision of this License is held to be unenforceable, such provision
-shall be reformed only to the extent necessary to make it enforceable.
-
-
-***************************************
-14) Definition of "You" in This License
-***************************************
-
-"You" throughout this License, whether in upper or lower case, means an
-individual or a legal entity exercising rights under, and complying with all
-of the terms of, this License. For legal entities, "You" includes any entity
-that controls, is controlled by, or is under common control with you. For
-purposes of this definition, "control" means (i) the power, direct or
-indirect, to cause the direction or management of such entity, whether by
-contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
-outstanding shares, or (iii) beneficial ownership of such entity.
-
-
-****************
-15) Right to Use
-****************
-
-You may use the Original Work in all ways not otherwise restricted or
-conditioned by this License or by law, and Licensor promises not to interfere
-with or be responsible for such uses by You.
-
-
-********************************
-16) Modification of This License
-********************************
-
-This License is Copyright © 2005 Lawrence Rosen. Permission is granted to
-copy, distribute, or communicate this License without modification. Nothing in
-this License permits You to modify this License as applied to the Original
-Work or to Derivative Works. However, You may modify the text of this License
-and copy, distribute or communicate your modified version (the "Modified
-License") and apply it to other original works of authorship subject to the
-following conditions: (i) You may not indicate in any way that your Modified
-License is the "Open Software License" or "OSL" and you may not use those
-names in the name of your Modified License; (ii) You must replace the notice
-specified in the first paragraph above with the notice "Licensed under <insert
-your license name here>" or with a notice of your own that is not confusingly
-similar to the notice in this License; and (iii) You may not claim that your
-original works are open source software unless your Modified License has been
-approved by Open Source Initiative (OSI) and You comply with its license
-review and certification process.
\ No newline at end of file
diff --git a/tests/phpunit.xml b/phpunit.xml
similarity index 63%
rename from tests/phpunit.xml
rename to phpunit.xml
index 2f18dae..aca7809 100644
--- a/tests/phpunit.xml
+++ b/phpunit.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
 <phpunit 
-	bootstrap="./Bootstrap.php"
+	bootstrap="tests/Bootstrap.php"
 	colors="true"
 	convertNoticesToExceptions="true"
 	convertWarningsToExceptions="true"
@@ -11,10 +11,10 @@
 	stopOnSkipped="false">
 	<testsuites>
 		<testsuite name="CodeIgniter Core Test Suite">
-			<file>codeigniter/Setup_test.php</file>
-			<directory suffix="test.php">codeigniter/core</directory>
-			<directory suffix="test.php">codeigniter/helpers</directory>
-			<directory suffix="test.php">codeigniter/libraries</directory>
+			<file>tests/codeigniter/Setup_test.php</file>
+			<directory suffix="test.php">tests/codeigniter/core</directory>
+			<directory suffix="test.php">tests/codeigniter/helpers</directory>
+			<directory suffix="test.php">tests/codeigniter/libraries</directory>
 			<!-- We'll worry about these later ...
 			<directory suffix="test.php">codeigniter/libraries</directory>
 			<directory suffix="test.php">codeigniter/helpers</directory>
diff --git a/readme.rst b/readme.rst
index 26e04ce..2369a8d 100644
--- a/readme.rst
+++ b/readme.rst
@@ -23,7 +23,7 @@
 **************************
 
 You can find a list of all changes for each release in the `user
-guide change log <https://github.com/EllisLab/CodeIgniter/blob/develop/user_guide/changelog.html>`_.
+guide change log <https://github.com/EllisLab/CodeIgniter/blob/develop/user_guide_src/source/changelog.rst>`_.
 
 *******************
 Server Requirements
@@ -193,4 +193,4 @@
 ***************
 
 The EllisLab team and The Reactor Engineers would like to thank all the
-contributors to the CodeIgniter project and you, the CodeIgniter user.
\ No newline at end of file
+contributors to the CodeIgniter project and you, the CodeIgniter user.
diff --git a/system/core/Benchmark.php b/system/core/Benchmark.php
index 0f31040..f4dfd3d 100755
--- a/system/core/Benchmark.php
+++ b/system/core/Benchmark.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -15,10 +15,10 @@
  * 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 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -46,7 +46,7 @@
 	 *
 	 * @var array
 	 */
-	var $marker = array();
+	public $marker = array();
 
 	// --------------------------------------------------------------------
 
@@ -56,11 +56,10 @@
 	 * Multiple calls to this function can be made so that several
 	 * execution points can be timed
 	 *
-	 * @access	public
 	 * @param	string	$name	name of the marker
 	 * @return	void
 	 */
-	function mark($name)
+	public function mark($name)
 	{
 		$this->marker[$name] = microtime();
 	}
@@ -75,13 +74,12 @@
 	 * execution time to be shown in a template. The output class will
 	 * swap the real value for this variable.
 	 *
-	 * @access	public
 	 * @param	string	a particular marked point
 	 * @param	string	a particular marked point
 	 * @param	integer	the number of decimal places
 	 * @return	mixed
 	 */
-	function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
+	public function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
 	{
 		if ($point1 == '')
 		{
@@ -114,17 +112,14 @@
 	 * without the memory being calculated until the end.
 	 * The output class will swap the real value for this variable.
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function memory_usage()
+	public function memory_usage()
 	{
 		return '{memory_usage}';
 	}
 
 }
 
-// END CI_Benchmark class
-
 /* End of file Benchmark.php */
-/* Location: ./system/core/Benchmark.php */
\ No newline at end of file
+/* Location: ./system/core/Benchmark.php */
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
index 97527e5..7af3c48 100755
--- a/system/core/CodeIgniter.php
+++ b/system/core/CodeIgniter.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -59,7 +59,7 @@
  *  Load the framework constants
  * ------------------------------------------------------
  */
-	if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
+	if (defined('ENVIRONMENT') && file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php'))
 	{
 		require(APPPATH.'config/'.ENVIRONMENT.'/constants.php');
 	}
@@ -91,12 +91,12 @@
  * "libraries" folder. Since CI allows config items to be
  * overriden via data set in the main index. php file,
  * before proceeding we need to know if a subclass_prefix
- * override exists.  If so, we will set this value now,
+ * override exists. If so, we will set this value now,
  * before any classes are loaded
  * Note: Since the config file data is cached it doesn't
  * hurt to load it here.
  */
-	if (isset($assign_to_config['subclass_prefix']) AND $assign_to_config['subclass_prefix'] != '')
+	if (isset($assign_to_config['subclass_prefix']) && $assign_to_config['subclass_prefix'] != '')
 	{
 		get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
 	}
@@ -106,13 +106,10 @@
  *  Set a liberal script execution time limit
  * ------------------------------------------------------
  */
-	if (function_exists("set_time_limit") AND @ini_get("safe_mode") == 0)
+	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
 	{
-		// Do not override the Time Limit value if running from Command Line
-		if(php_sapi_name() != 'cli')
-		{
-			@set_time_limit(300);
-		}
+		@set_time_limit(300);
 	}
 
 /*
@@ -162,7 +159,6 @@
  * after the Config class is instantiated.
  *
  */
-
 	$UNI =& load_class('Utf8', 'core');
 
 /*
@@ -195,15 +191,13 @@
 
 /*
  * ------------------------------------------------------
- *	Is there a valid cache file?  If so, we're done...
+ *	Is there a valid cache file? If so, we're done...
  * ------------------------------------------------------
  */
-	if ($EXT->_call_hook('cache_override') === FALSE)
+	if ($EXT->_call_hook('cache_override') === FALSE
+		&& $OUT->_display_cache($CFG, $URI) == TRUE)
 	{
-		if ($OUT->_display_cache($CFG, $URI) == TRUE)
-		{
-			exit;
-		}
+		exit;
 	}
 
 /*
@@ -273,13 +267,13 @@
 	$method = $RTR->fetch_method();
 
 	if ( ! class_exists($class)
-		OR strncmp($method, '_', 1) == 0
+		OR strpos($method, '_') === 0
 		OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
 		)
 	{
 		if ( ! empty($RTR->routes['404_override']))
 		{
-			$x = explode('/', $RTR->routes['404_override']);
+			$x = explode('/', $RTR->routes['404_override'], 2);
 			$class = $x[0];
 			$method = (isset($x[1]) ? $x[1] : 'index');
 			if ( ! class_exists($class))
@@ -341,7 +335,7 @@
 			// Check and see if we are using a 404 override and use it.
 			if ( ! empty($RTR->routes['404_override']))
 			{
-				$x = explode('/', $RTR->routes['404_override']);
+				$x = explode('/', $RTR->routes['404_override'], 2);
 				$class = $x[0];
 				$method = (isset($x[1]) ? $x[1] : 'index');
 				if ( ! class_exists($class))
@@ -367,7 +361,6 @@
 		call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
 	}
 
-
 	// Mark a benchmark end point
 	$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
 
@@ -400,11 +393,10 @@
  *  Close the DB connection if one exists
  * ------------------------------------------------------
  */
-	if (class_exists('CI_DB') AND isset($CI->db))
+	if (class_exists('CI_DB') && isset($CI->db))
 	{
 		$CI->db->close();
 	}
 
-
 /* End of file CodeIgniter.php */
-/* Location: ./system/core/CodeIgniter.php */
\ No newline at end of file
+/* Location: ./system/core/CodeIgniter.php */
diff --git a/system/core/Common.php b/system/core/Common.php
index b0921fe..4919793 100644
--- a/system/core/Common.php
+++ b/system/core/Common.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -56,7 +56,7 @@
 	function is_php($version = '5.0.0')
 	{
 		static $_is_php;
-		$version = (string)$version;
+		$version = (string) $version;
 
 		if ( ! isset($_is_php[$version]))
 		{
@@ -73,10 +73,10 @@
  * 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
+ * the file, based on the read-only attribute. is_writable() is also unreliable
  * on Unix servers if safe_mode is on.
  *
- * @access	private
+ * @access	public
  * @return	void
  */
 if ( ! function_exists('is_really_writable'))
@@ -84,17 +84,17 @@
 	function is_really_writable($file)
 	{
 		// If we're on a Unix server with safe_mode off we call is_writable
-		if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
+		if (DIRECTORY_SEPARATOR === '/' && (bool) @ini_get('safe_mode') === FALSE)
 		{
 			return is_writable($file);
 		}
 
-		// For windows servers and safe_mode "on" installations we'll actually
-		// write a file then read it.  Bah...
+		/* For Windows servers and safe_mode "on" installations we'll actually
+		 * write a file then read it. Bah...
+		 */
 		if (is_dir($file))
 		{
 			$file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
-
 			if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
 			{
 				return FALSE;
@@ -120,7 +120,7 @@
 /**
 * Class registry
 *
-* This function acts as a singleton.  If the requested class does not
+* 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.
 *
@@ -136,7 +136,7 @@
 	{
 		static $_classes = array();
 
-		// Does the class exist?  If so, we're done...
+		// Does the class exist? If so, we're done...
 		if (isset($_classes[$class]))
 		{
 			return $_classes[$class];
@@ -161,7 +161,7 @@
 			}
 		}
 
-		// Is the request a class extension?  If so we load it too
+		// Is the request a class extension? If so we load it too
 		if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'))
 		{
 			$name = config_item('subclass_prefix').$class;
@@ -177,6 +177,7 @@
 		{
 			// Note: We use exit() rather then show_error() in order to avoid a
 			// self-referencing loop with the Excptions class
+			set_status_header(503);
 			exit('Unable to locate the specified class: '.$class.'.php');
 		}
 
@@ -191,7 +192,7 @@
 // --------------------------------------------------------------------
 
 /**
-* Keeps track of which libraries have been loaded.  This function is
+* Keeps track of which libraries have been loaded. This function is
 * called by the load_class() function above
 *
 * @access	public
@@ -199,7 +200,7 @@
 */
 if ( ! function_exists('is_loaded'))
 {
-	function is_loaded($class = '')
+	function &is_loaded($class = '')
 	{
 		static $_is_loaded = array();
 
@@ -243,6 +244,7 @@
 		// Fetch the config file
 		if ( ! file_exists($file_path))
 		{
+			set_status_header(503);
 			exit('The configuration file does not exist.');
 		}
 
@@ -251,6 +253,7 @@
 		// Does the $config array exist in the file?
 		if ( ! isset($config) OR ! is_array($config))
 		{
+			set_status_header(503);
 			exit('Your config file does not appear to be formatted correctly.');
 		}
 
@@ -387,76 +390,76 @@
 	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]) AND $text == '')
+		if (isset($stati[$code]) && $text == '')
 		{
 			$text = $stati[$code];
 		}
 
 		if ($text == '')
 		{
-			show_error('No status text available.  Please check your status code number or supply your own message text.', 500);
+			show_error('No status text available. Please check your status code number or supply your own message text.', 500);
 		}
 
-		$server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
+		$server_protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
 
-		if (substr(php_sapi_name(), 0, 3) == 'cgi')
+		if (strpos(php_sapi_name(), 'cgi') === 0)
 		{
-			header("Status: {$code} {$text}", TRUE);
+			header('Status: '.$code.' '.$text, TRUE);
 		}
-		elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')
+		elseif ($server_protocol === 'HTTP/1.0')
 		{
-			header($server_protocol." {$code} {$text}", TRUE, $code);
+			header('HTTP/1.0 '.$code.' '.$text, TRUE, $code);
 		}
 		else
 		{
-			header("HTTP/1.1 {$code} {$text}", TRUE, $code);
+			header('HTTP/1.1 '.$code.' '.$text, TRUE, $code);
 		}
 	}
 }
@@ -527,16 +530,15 @@
 	function remove_invisible_characters($str, $url_encoded = TRUE)
 	{
 		$non_displayables = array();
-		
-		// every control character except newline (dec 10)
-		// carriage return (dec 13), and horizontal tab (dec 09)
-		
+
+		// every control character except newline (dec 10),
+		// carriage return (dec 13) and horizontal tab (dec 09)
 		if ($url_encoded)
 		{
 			$non_displayables[] = '/%0[0-8bcef]/';	// url encoded 00-08, 11, 12, 14, 15
 			$non_displayables[] = '/%1[0-9a-f]/';	// url encoded 16-31
 		}
-		
+
 		$non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';	// 00-08, 11, 12, 14-31, 127
 
 		do
@@ -562,16 +564,11 @@
 {
 	function html_escape($var)
 	{
-		if (is_array($var))
-		{
-			return array_map('html_escape', $var);
-		}
-		else
-		{
-			return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
-		}
+		return is_array($var)
+			? array_map('html_escape', $var)
+			: htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
 	}
 }
 
 /* End of file Common.php */
-/* Location: ./system/core/Common.php */
\ No newline at end of file
+/* Location: ./system/core/Common.php */
diff --git a/system/core/Config.php b/system/core/Config.php
index 5106284..6841743 100755
--- a/system/core/Config.php
+++ b/system/core/Config.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -45,46 +45,45 @@
 	 *
 	 * @var array
 	 */
-	var $config = array();
+	public $config = array();
 	/**
 	 * List of all loaded config files
 	 *
 	 * @var array
 	 */
-	var $is_loaded = array();
+	public $is_loaded = array();
 	/**
-	 * List of paths to search when trying to load a config file
+	 * 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
 	 */
-	var $_config_paths = array(APPPATH);
+	public $_config_paths = array(APPPATH);
 
 	/**
 	 * Constructor
 	 *
 	 * Sets the $config data from the primary config.php file as a class variable
 	 *
-	 * @access   public
 	 * @param   string	the config file name
 	 * @param   boolean  if configuration values should be loaded into their own section
 	 * @param   boolean  true if errors should just return false, false if an error message should be displayed
 	 * @return  boolean  if the file was successfully loaded or not
 	 */
-	function __construct()
+	public function __construct()
 	{
 		$this->config =& get_config();
-		log_message('debug', "Config Class Initialized");
+		log_message('debug', 'Config Class Initialized');
 
 		// Set the base_url automatically if none was provided
 		if ($this->config['base_url'] == '')
 		{
 			if (isset($_SERVER['HTTP_HOST']))
 			{
-				$base_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
-				$base_url .= '://'. $_SERVER['HTTP_HOST'];
-				$base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']).'/';
+				$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
 			{
 				$base_url = 'http://localhost/';
@@ -99,17 +98,15 @@
 	/**
 	 * Load Config File
 	 *
-	 * @access	public
 	 * @param	string	the config file name
-	 * @param   boolean  if configuration values should be loaded into their own section
-	 * @param   boolean  true if errors should just return false, false if an error message should be displayed
+	 * @param	boolean	if configuration values should be loaded into their own section
+	 * @param	boolean	true if errors should just return false, false if an error message should be displayed
 	 * @return	boolean	if the file was loaded correctly
 	 */
-	function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
+	public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
 	{
 		$file = ($file == '') ? 'config' : str_replace('.php', '', $file);
-		$found = FALSE;
-		$loaded = FALSE;
+		$found = $loaded = FALSE;
 
 		foreach ($this->_config_paths as $path)
 		{
@@ -192,39 +189,19 @@
 	 * Fetch a config file item
 	 *
 	 *
-	 * @access	public
 	 * @param	string	the config item name
 	 * @param	string	the index name
 	 * @param	bool
 	 * @return	string
 	 */
-	function item($item, $index = '')
+	public function item($item, $index = '')
 	{
 		if ($index == '')
 		{
-			if ( ! isset($this->config[$item]))
-			{
-				return FALSE;
-			}
-
-			$pref = $this->config[$item];
-		}
-		else
-		{
-			if ( ! isset($this->config[$index]))
-			{
-				return FALSE;
-			}
-
-			if ( ! isset($this->config[$index][$item]))
-			{
-				return FALSE;
-			}
-
-			$pref = $this->config[$index][$item];
+			return isset($this->config[$item]) ? $this->config[$item] : FALSE;
 		}
 
-		return $pref;
+		return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -232,18 +209,17 @@
 	/**
 	 * Fetch a config file item - adds slash after item (if item is not empty)
 	 *
-	 * @access	public
 	 * @param	string	the config item name
 	 * @param	bool
 	 * @return	string
 	 */
-	function slash_item($item)
+	public function slash_item($item)
 	{
 		if ( ! isset($this->config[$item]))
 		{
 			return FALSE;
 		}
-		if( trim($this->config[$item]) == '')
+		elseif (trim($this->config[$item]) == '')
 		{
 			return '';
 		}
@@ -257,11 +233,10 @@
 	 * Site URL
 	 * Returns base_url . index_page [. uri_string]
 	 *
-	 * @access	public
 	 * @param	string	the URI string
 	 * @return	string
 	 */
-	function site_url($uri = '')
+	public function site_url($uri = '')
 	{
 		if ($uri == '')
 		{
@@ -285,11 +260,10 @@
 	 * Base URL
 	 * Returns base_url [. uri_string]
 	 *
-	 * @access public
 	 * @param string $uri
 	 * @return string
 	 */
-	function base_url($uri = '')
+	public function base_url($uri = '')
 	{
 		return $this->slash_item('base_url').ltrim($this->_uri_string($uri),'/');
 	}
@@ -299,8 +273,7 @@
 	/**
 	 * Build URI string for use in Config::site_url() and Config::base_url()
 	 *
-	 * @access protected
-	 * @param  $uri
+	 * @param  mixed $uri
 	 * @return string
 	 */
 	protected function _uri_string($uri)
@@ -311,23 +284,21 @@
 			{
 				$uri = implode('/', $uri);
 			}
-			$uri = trim($uri, '/');
+			return trim($uri, '/');
 		}
-		else
+		elseif (is_array($uri))
 		{
-			if (is_array($uri))
+			$i = 0;
+			$str = '';
+			foreach ($uri as $key => $val)
 			{
-				$i = 0;
-				$str = '';
-				foreach ($uri as $key => $val)
-				{
-					$prefix = ($i == 0) ? '' : '&';
-					$str .= $prefix.$key.'='.$val;
-					$i++;
-				}
-				$uri = $str;
+				$prefix = ($i === 0) ? '' : '&';
+				$str .= $prefix.$key.'='.$val;
+				$i++;
 			}
+			return $str;
 		}
+
 		return $uri;
 	}
 
@@ -336,12 +307,11 @@
 	/**
 	 * System URL
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function system_url()
+	public function system_url()
 	{
-		$x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH));
+		$x = explode('/', preg_replace('|/*(.+?)/*$|', '\\1', BASEPATH));
 		return $this->slash_item('base_url').end($x).'/';
 	}
 
@@ -350,12 +320,11 @@
 	/**
 	 * Set a config file item
 	 *
-	 * @access	public
 	 * @param	string	the config item key
 	 * @param	string	the config item value
 	 * @return	void
 	 */
-	function set_item($item, $value)
+	public function set_item($item, $value)
 	{
 		$this->config[$item] = $value;
 	}
@@ -366,14 +335,13 @@
 	 * Assign to Config
 	 *
 	 * This function is called by the front controller (CodeIgniter.php)
-	 * after the Config class is instantiated.  It permits config items
+	 * after the Config class is instantiated. It permits config items
 	 * to be assigned or overriden by variables contained in the index.php file
 	 *
-	 * @access	private
 	 * @param	array
 	 * @return	void
 	 */
-	function _assign_to_config($items = array())
+	public function _assign_to_config($items = array())
 	{
 		if (is_array($items))
 		{
@@ -385,7 +353,5 @@
 	}
 }
 
-// END CI_Config class
-
 /* End of file Config.php */
 /* Location: ./system/core/Config.php */
diff --git a/system/core/Controller.php b/system/core/Controller.php
index ca2bf41..0dc1317 100644
--- a/system/core/Controller.php
+++ b/system/core/Controller.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -43,13 +43,10 @@
 
 	private static $instance;
 
-	/**
-	 * Constructor
-	 */
 	public function __construct()
 	{
 		self::$instance =& $this;
-		
+
 		// Assign all the class objects that were instantiated by the
 		// bootstrap file (CodeIgniter.php) to local class variables
 		// so that CI can run as one big super object.
@@ -59,10 +56,8 @@
 		}
 
 		$this->load =& load_class('Loader', 'core');
-
 		$this->load->initialize();
-		
-		log_message('debug', "Controller Class Initialized");
+		log_message('debug', 'Controller Class Initialized');
 	}
 
 	public static function &get_instance()
@@ -70,7 +65,6 @@
 		return self::$instance;
 	}
 }
-// END Controller class
 
 /* End of file Controller.php */
-/* Location: ./system/core/Controller.php */
\ No newline at end of file
+/* Location: ./system/core/Controller.php */
diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php
index ead8d81..bf99012 100755
--- a/system/core/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -37,49 +37,44 @@
  * @link		http://codeigniter.com/user_guide/libraries/exceptions.html
  */
 class CI_Exceptions {
-	var $action;
-	var $severity;
-	var $message;
-	var $filename;
-	var $line;
+
+	public $action;
+	public $severity;
+	public $message;
+	public $filename;
+	public $line;
 
 	/**
 	 * Nesting level of the output buffering mechanism
 	 *
 	 * @var int
-	 * @access public
 	 */
-	var $ob_level;
+	public $ob_level;
 
 	/**
 	 * List if available error levels
 	 *
 	 * @var array
-	 * @access public
 	 */
-	var $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'
-					);
+	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'
+			);
 
-
-	/**
-	 * Constructor
-	 */
 	public function __construct()
 	{
 		$this->ob_level = ob_get_level();
-		// Note:  Do not log messages from this constructor.
+		// Note: Do not log messages from this constructor.
 	}
 
 	// --------------------------------------------------------------------
@@ -89,17 +84,15 @@
 	 *
 	 * This function logs PHP generated error messages
 	 *
-	 * @access	private
 	 * @param	string	the error severity
 	 * @param	string	the error string
 	 * @param	string	the error filepath
 	 * @param	string	the error line number
-	 * @return	string
+	 * @return	void
 	 */
-	function log_exception($severity, $message, $filepath, $line)
+	public function log_exception($severity, $message, $filepath, $line)
 	{
 		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
-
 		log_message('error', 'Severity: '.$severity.'  --> '.$message. ' '.$filepath.' '.$line, TRUE);
 	}
 
@@ -108,15 +101,14 @@
 	/**
 	 * 404 Page Not Found Handler
 	 *
-	 * @access	private
 	 * @param	string	the page
 	 * @param 	bool	log error yes/no
 	 * @return	string
 	 */
-	function show_404($page = '', $log_error = TRUE)
+	public function show_404($page = '', $log_error = TRUE)
 	{
-		$heading = "404 Page Not Found";
-		$message = "The page you requested was not found.";
+		$heading = '404 Page Not Found';
+		$message = 'The page you requested was not found.';
 
 		// By default we log this, but allow a dev to skip it
 		if ($log_error)
@@ -137,14 +129,13 @@
 	 * (either as a string or an array) and displays
 	 * it using the specified template.
 	 *
-	 * @access	private
 	 * @param	string	the heading
 	 * @param	string	the message
 	 * @param	string	the template name
 	 * @param 	int		the status code
 	 * @return	string
 	 */
-	function show_error($heading, $message, $template = 'error_general', $status_code = 500)
+	public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
 	{
 		set_status_header($status_code);
 
@@ -166,7 +157,6 @@
 	/**
 	 * Native PHP error handler
 	 *
-	 * @access	private
 	 * @param	string	the error severity
 	 * @param	string	the error string
 	 * @param	string	the error filepath
@@ -176,8 +166,7 @@
 	function show_php_error($severity, $message, $filepath, $line)
 	{
 		$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
-
-		$filepath = str_replace("\\", "/", $filepath);
+		$filepath = str_replace('\\', '/', $filepath);
 
 		// For safety reasons we do not show the full file path
 		if (FALSE !== strpos($filepath, '/'))
@@ -191,15 +180,13 @@
 			ob_end_flush();
 		}
 		ob_start();
-		include(APPPATH.'errors/error_php.php');
+		include(APPPATH.'errors/'.'error_php.php');
 		$buffer = ob_get_contents();
 		ob_end_clean();
 		echo $buffer;
 	}
 
-
 }
-// END Exceptions Class
 
 /* End of file Exceptions.php */
-/* Location: ./system/core/Exceptions.php */
\ No newline at end of file
+/* Location: ./system/core/Exceptions.php */
diff --git a/system/core/Hooks.php b/system/core/Hooks.php
index aa251a3..e1ac58e 100755
--- a/system/core/Hooks.php
+++ b/system/core/Hooks.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -45,28 +45,24 @@
 	 *
 	 * @var bool
 	 */
-	var $enabled		= FALSE;
+	public $enabled		= FALSE;
 	/**
 	 * List of all hooks set in config/hooks.php
 	 *
 	 * @var array
 	 */
-	var $hooks			= array();
+	public $hooks			= array();
 	/**
 	 * Determines wether hook is in progress, used to prevent infinte loops
 	 *
 	 * @var bool
 	 */
-	var $in_progress	= FALSE;
+	public $in_progress	= FALSE;
 
-	/**
-	 * Constructor
-	 *
-	 */
-	function __construct()
+	public function __construct()
 	{
 		$this->_initialize();
-		log_message('debug', "Hooks Class Initialized");
+		log_message('debug', 'Hooks Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -74,24 +70,20 @@
 	/**
 	 * Initialize the Hooks Preferences
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _initialize()
+	private function _initialize()
 	{
 		$CFG =& load_class('Config', 'core');
 
 		// If hooks are not enabled in the config file
 		// there is nothing else to do
-
 		if ($CFG->item('enable_hooks') == FALSE)
 		{
 			return;
 		}
 
 		// Grab the "hooks" definition file.
-		// If there are no hooks, we're done.
-
 		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
 		{
 			include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
@@ -101,7 +93,7 @@
 			include(APPPATH.'config/hooks.php');
 		}
 
-
+		// If there are no hooks, we're done.
 		if ( ! isset($hook) OR ! is_array($hook))
 		{
 			return;
@@ -116,13 +108,12 @@
 	/**
 	 * Call Hook
 	 *
-	 * Calls a particular hook
+	 * Calls a particular hook. Called by CodeIgniter.php.
 	 *
-	 * @access	private
 	 * @param	string	the hook name
 	 * @return	mixed
 	 */
-	function _call_hook($which = '')
+	public function _call_hook($which = '')
 	{
 		if ( ! $this->enabled OR ! isset($this->hooks[$which]))
 		{
@@ -151,11 +142,10 @@
 	 *
 	 * Runs a particular hook
 	 *
-	 * @access	private
 	 * @param	array	the hook details
 	 * @return	bool
 	 */
-	function _run_hook($data)
+	protected function _run_hook($data)
 	{
 		if ( ! is_array($data))
 		{
@@ -168,7 +158,6 @@
 
 		// If the script being called happens to have the same
 		// hook call within it a loop can happen
-
 		if ($this->in_progress == TRUE)
 		{
 			return;
@@ -254,7 +243,5 @@
 
 }
 
-// END CI_Hooks class
-
 /* End of file Hooks.php */
-/* Location: ./system/core/Hooks.php */
\ No newline at end of file
+/* Location: ./system/core/Hooks.php */
diff --git a/system/core/Input.php b/system/core/Input.php
index 3cbbe78..ee15f40 100755
--- a/system/core/Input.php
+++ b/system/core/Input.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Input Class
  *
@@ -45,39 +43,39 @@
 	 *
 	 * @var string
 	 */
-	var $ip_address				= FALSE;
+	public $ip_address				= FALSE;
 	/**
 	 * user agent (web browser) being used by the current user
 	 *
 	 * @var string
 	 */
-	var $user_agent				= FALSE;
+	public $user_agent				= FALSE;
 	/**
 	 * If FALSE, then $_GET will be set to an empty array
 	 *
 	 * @var bool
 	 */
-	var $_allow_get_array		= TRUE;
+	protected $_allow_get_array		= TRUE;
 	/**
 	 * If TRUE, then newlines are standardized
 	 *
 	 * @var bool
 	 */
-	var $_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
 	 */
-	var $_enable_xss			= FALSE;
+	protected $_enable_xss			= FALSE;
 	/**
 	 * Enables a CSRF cookie token to be set.
 	 * Set automatically based on config setting
 	 *
 	 * @var bool
 	 */
-	var $_enable_csrf			= FALSE;
+	protected $_enable_csrf			= FALSE;
 	/**
 	 * List of all HTTP request headers
 	 *
@@ -85,21 +83,19 @@
 	 */
 	protected $headers			= array();
 
-
 	/**
 	 * Constructor
 	 *
 	 * Sets whether to globally enable the XSS processing
 	 * and whether to allow the $_GET array
-	 *
 	 */
 	public function __construct()
 	{
-		log_message('debug', "Input Class Initialized");
+		log_message('debug', 'Input Class Initialized');
 
 		$this->_allow_get_array	= (config_item('allow_get_array') === TRUE);
-		$this->_enable_xss		= (config_item('global_xss_filtering') === TRUE);
-		$this->_enable_csrf		= (config_item('csrf_protection') === TRUE);
+		$this->_enable_xss	= (config_item('global_xss_filtering') === TRUE);
+		$this->_enable_csrf	= (config_item('csrf_protection') === TRUE);
 
 		global $SEC;
 		$this->security =& $SEC;
@@ -122,7 +118,6 @@
 	 *
 	 * This is a helper function to retrieve values from global arrays
 	 *
-	 * @access	protected
 	 * @param	array
 	 * @param	string
 	 * @param	bool
@@ -148,7 +143,6 @@
 	/**
 	* Fetch an item from the GET array
 	*
-	* @access	public
 	* @param	string
 	* @param	bool
 	* @return	string
@@ -156,7 +150,7 @@
 	public function get($index = NULL, $xss_clean = FALSE)
 	{
 		// Check if a field has been provided
-		if ($index === NULL AND ! empty($_GET))
+		if ($index === NULL && ! empty($_GET))
 		{
 			$get = array();
 
@@ -176,7 +170,6 @@
 	/**
 	* Fetch an item from the POST array
 	*
-	* @access	public
 	* @param	string
 	* @param	bool
 	* @return	string
@@ -184,7 +177,7 @@
 	public function post($index = NULL, $xss_clean = FALSE)
 	{
 		// Check if a field has been provided
-		if ($index === NULL AND ! empty($_POST))
+		if ($index === NULL && ! empty($_POST))
 		{
 			$post = array();
 
@@ -205,21 +198,15 @@
 	/**
 	* Fetch an item from either the GET array or the POST
 	*
-	* @access	public
 	* @param	string	The index key
 	* @param	bool	XSS cleaning
 	* @return	string
 	*/
 	public function get_post($index = '', $xss_clean = FALSE)
 	{
-		if ( ! isset($_POST[$index]) )
-		{
-			return $this->get($index, $xss_clean);
-		}
-		else
-		{
-			return $this->post($index, $xss_clean);
-		}
+		return isset($_POST[$index])
+			? $this->post($index, $xss_clean)
+			: $this->get($index, $xss_clean);
 	}
 
 	// --------------------------------------------------------------------
@@ -227,7 +214,6 @@
 	/**
 	* Fetch an item from the COOKIE array
 	*
-	* @access	public
 	* @param	string
 	* @param	bool
 	* @return	string
@@ -245,7 +231,6 @@
 	* Accepts six parameter, or you can submit an associative
 	* array in the first parameter containing all the values.
 	*
-	* @access	public
 	* @param	mixed
 	* @param	string	the value of the cookie
 	* @param	string	the number of seconds until expiration
@@ -269,19 +254,19 @@
 			}
 		}
 
-		if ($prefix == '' AND config_item('cookie_prefix') != '')
+		if ($prefix == '' && config_item('cookie_prefix') != '')
 		{
 			$prefix = config_item('cookie_prefix');
 		}
-		if ($domain == '' AND config_item('cookie_domain') != '')
+		if ($domain == '' && config_item('cookie_domain') != '')
 		{
 			$domain = config_item('cookie_domain');
 		}
-		if ($path == '/' AND config_item('cookie_path') != '/')
+		if ($path == '/' && config_item('cookie_path') !== '/')
 		{
 			$path = config_item('cookie_path');
 		}
-		if ($secure == FALSE AND config_item('cookie_secure') != FALSE)
+		if ($secure == FALSE && config_item('cookie_secure') != FALSE)
 		{
 			$secure = config_item('cookie_secure');
 		}
@@ -303,7 +288,6 @@
 	/**
 	* Fetch an item from the SERVER array
 	*
-	* @access	public
 	* @param	string
 	* @param	bool
 	* @return	string
@@ -318,7 +302,6 @@
 	/**
 	* Fetch the IP Address
 	*
-	* @access	public
 	* @return	string
 	*/
 	public function ip_address()
@@ -335,11 +318,11 @@
 
 			$this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
 		}
-		elseif (! $this->server('HTTP_CLIENT_IP') AND $this->server('REMOTE_ADDR'))
+		elseif ( ! $this->server('HTTP_CLIENT_IP') && $this->server('REMOTE_ADDR'))
 		{
 			$this->ip_address = $_SERVER['REMOTE_ADDR'];
 		}
-		elseif ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP'))
+		elseif ($this->server('REMOTE_ADDR') && $this->server('HTTP_CLIENT_IP'))
 		{
 			$this->ip_address = $_SERVER['HTTP_CLIENT_IP'];
 		}
@@ -354,8 +337,7 @@
 
 		if ($this->ip_address === FALSE)
 		{
-			$this->ip_address = '0.0.0.0';
-			return $this->ip_address;
+			return $this->ip_address = '0.0.0.0';
 		}
 
 		if (strpos($this->ip_address, ',') !== FALSE)
@@ -366,7 +348,7 @@
 
 		if ( ! $this->valid_ip($this->ip_address))
 		{
-			$this->ip_address = '0.0.0.0';
+			return $this->ip_address = '0.0.0.0';
 		}
 
 		return $this->ip_address;
@@ -379,7 +361,6 @@
 	*
 	* Updated version suggested by Geert De Deckere
 	*
-	* @access	public
 	* @param	string
 	* @return	bool
 	*/
@@ -394,7 +375,7 @@
 		$ip_segments = explode('.', $ip);
 
 		// Always 4 segments needed
-		if (count($ip_segments) != 4)
+		if (count($ip_segments) !== 4)
 		{
 			return FALSE;
 		}
@@ -408,7 +389,7 @@
 		{
 			// IP segments must be digits and can not be
 			// longer than 3 digits or greater then 255
-			if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3)
+			if ($segment == '' OR preg_match('/[^0-9]/', $segment) OR $segment > 255 OR strlen($segment) > 3)
 			{
 				return FALSE;
 			}
@@ -422,7 +403,6 @@
 	/**
 	* User Agent
 	*
-	* @access	public
 	* @return	string
 	*/
 	public function user_agent()
@@ -432,9 +412,7 @@
 			return $this->user_agent;
 		}
 
-		$this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];
-
-		return $this->user_agent;
+		return $this->user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -444,22 +422,20 @@
 	*
 	* This function does the following:
 	*
-	* Unsets $_GET data (if query strings are not enabled)
+	* - Unsets $_GET data (if query strings are not enabled)
+	* - Unsets all globals if register_globals is enabled
+	* - Standardizes newline characters to \n
 	*
-	* Unsets all globals if register_globals is enabled
-	*
-	* Standardizes newline characters to \n
-	*
-	* @access	private
 	* @return	void
 	*/
-	private function _sanitize_globals()
+	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');
+					'_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
@@ -491,19 +467,16 @@
 		{
 			$_GET = array();
 		}
-		else
+		elseif (is_array($_GET) && count($_GET) > 0)
 		{
-			if (is_array($_GET) AND count($_GET) > 0)
+			foreach ($_GET as $key => $val)
 			{
-				foreach ($_GET as $key => $val)
-				{
-					$_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
-				}
+				$_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
 			}
 		}
 
 		// Clean $_POST Data
-		if (is_array($_POST) AND count($_POST) > 0)
+		if (is_array($_POST) && count($_POST) > 0)
 		{
 			foreach ($_POST as $key => $val)
 			{
@@ -512,7 +485,7 @@
 		}
 
 		// Clean $_COOKIE Data
-		if (is_array($_COOKIE) AND count($_COOKIE) > 0)
+		if (is_array($_COOKIE) && count($_COOKIE) > 0)
 		{
 			// Also get rid of specially treated cookies that might be set by a server
 			// or silly application, that are of no use to a CI application anyway
@@ -532,14 +505,13 @@
 		// Sanitize PHP_SELF
 		$_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
 
-
 		// CSRF Protection check
 		if ($this->_enable_csrf == TRUE)
 		{
 			$this->security->csrf_verify();
 		}
 
-		log_message('debug', "Global POST and COOKIE data sanitized");
+		log_message('debug', 'Global POST and COOKIE data sanitized');
 	}
 
 	// --------------------------------------------------------------------
@@ -550,11 +522,10 @@
 	* This is a helper function. It escapes data and
 	* standardizes newline characters to \n
 	*
-	* @access	private
 	* @param	string
 	* @return	string
 	*/
-	private function _clean_input_data($str)
+	protected function _clean_input_data($str)
 	{
 		if (is_array($str))
 		{
@@ -592,12 +563,9 @@
 		}
 
 		// Standardize newlines if needed
-		if ($this->_standardize_newlines == TRUE)
+		if ($this->_standardize_newlines == TRUE && strpos($str, "\r") !== FALSE)
 		{
-			if (strpos($str, "\r") !== FALSE)
-			{
-				$str = str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);
-			}
+			return str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);
 		}
 
 		return $str;
@@ -612,21 +580,21 @@
 	* from trying to exploit keys we make sure that keys are
 	* only named with alpha-numeric text and a few other items.
 	*
-	* @access	private
 	* @param	string
 	* @return	string
 	*/
-	private function _clean_input_keys($str)
+	protected function _clean_input_keys($str)
 	{
-		if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
+		if ( ! preg_match('/^[a-z0-9:_\/-]+$/i', $str))
 		{
+			set_status_header(503);
 			exit('Disallowed Key Characters.');
 		}
 
 		// Clean UTF-8 if supported
 		if (UTF8_ENABLED === TRUE)
 		{
-			$str = $this->uni->clean_string($str);
+			return $this->uni->clean_string($str);
 		}
 
 		return $str;
@@ -640,10 +608,8 @@
 	 * In Apache, you can simply call apache_request_headers(), however for
 	 * people running other webservers the function is undefined.
 	 *
-	 * @access	public
 	 * @param	bool XSS cleaning
-	 *
-	 * @return array
+	 * @return	array
 	 */
 	public function request_headers($xss_clean = FALSE)
 	{
@@ -654,11 +620,11 @@
 		}
 		else
 		{
-			$headers['Content-Type'] = (isset($_SERVER['CONTENT_TYPE'])) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
+			$headers['Content-Type'] = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
 
 			foreach ($_SERVER as $key => $val)
 			{
-				if (strncmp($key, 'HTTP_', 5) === 0)
+				if (strpos($key, 'HTTP_') === 0)
 				{
 					$headers[substr($key, 5)] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);
 				}
@@ -684,10 +650,9 @@
 	 *
 	 * Returns the value of a single member of the headers class member
 	 *
-	 * @access	public
-	 * @param 	string		array key for $this->headers
-	 * @param	boolean		XSS Clean or not
-	 * @return 	mixed		FALSE on failure, string on success
+	 * @param	string	array key for $this->headers
+	 * @param	bool	XSS Clean or not
+	 * @return	mixed	FALSE on failure, string on success
 	 */
 	public function get_request_header($index, $xss_clean = FALSE)
 	{
@@ -701,12 +666,9 @@
 			return FALSE;
 		}
 
-		if ($xss_clean === TRUE)
-		{
-			return $this->security->xss_clean($this->headers[$index]);
-		}
-
-		return $this->headers[$index];
+		return ($xss_clean === TRUE)
+			? $this->security->xss_clean($this->headers[$index])
+			: $this->headers[$index];
 	}
 
 	// --------------------------------------------------------------------
@@ -716,12 +678,11 @@
 	 *
 	 * Test to see if a request contains the HTTP_X_REQUESTED_WITH header
 	 *
-	 * @access	public
-	 * @return 	boolean
+	 * @return 	bool
 	 */
 	public function is_ajax_request()
 	{
-		return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
+		return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
 	}
 
 	// --------------------------------------------------------------------
@@ -731,12 +692,11 @@
 	 *
 	 * Test to see if a request was made from the command line
 	 *
-	 * @access	public
-	 * @return 	boolean
+	 * @return 	bool
 	 */
 	public function is_cli_request()
 	{
-		return (php_sapi_name() == 'cli') or defined('STDIN');
+		return (php_sapi_name() === 'cli' OR defined('STDIN'));
 	}
 
 }
diff --git a/system/core/Lang.php b/system/core/Lang.php
index e03afb0..c40a685 100755
--- a/system/core/Lang.php
+++ b/system/core/Lang.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -43,22 +43,17 @@
 	 *
 	 * @var array
 	 */
-	var $language	= array();
+	public $language	= array();
 	/**
 	 * List of loaded language files
 	 *
 	 * @var array
 	 */
-	var $is_loaded	= array();
+	public $is_loaded	= array();
 
-	/**
-	 * Constructor
-	 *
-	 * @access	public
-	 */
-	function __construct()
+	public function __construct()
 	{
-		log_message('debug', "Language Class Initialized");
+		log_message('debug', 'Language Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -66,7 +61,6 @@
 	/**
 	 * Load a language file
 	 *
-	 * @access	public
 	 * @param	mixed	the name of the language file to be loaded. Can be an array
 	 * @param	string	the language (english, etc.)
 	 * @param	bool	return loaded array of translations
@@ -74,7 +68,7 @@
 	 * @param 	string	alternative path to look for language file
 	 * @return	mixed
 	 */
-	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);
 
@@ -136,7 +130,7 @@
 		}
 
 		$this->is_loaded[] = $langfile;
-		$this->language = $this->language + $lang;
+		$this->language = array_merge($this->language, $lang);
 		unset($lang);
 
 		log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile);
@@ -148,11 +142,10 @@
 	/**
 	 * Fetch a single line of text from the language array
 	 *
-	 * @access	public
 	 * @param	string	$line	the language line
 	 * @return	string
 	 */
-	function line($line = '')
+	public function line($line = '')
 	{
 		$value = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
 
@@ -166,7 +159,6 @@
 	}
 
 }
-// END Language Class
 
 /* End of file Lang.php */
 /* Location: ./system/core/Lang.php */
diff --git a/system/core/Loader.php b/system/core/Loader.php
index 4e14b54..12daaa9 100644
--- a/system/core/Loader.php
+++ b/system/core/Loader.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -45,88 +45,77 @@
 	 * Nesting level of the output buffering mechanism
 	 *
 	 * @var int
-	 * @access protected
 	 */
 	protected $_ci_ob_level;
 	/**
 	 * List of paths to load views from
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_view_paths		= array();
 	/**
 	 * List of paths to load libraries from
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_library_paths	= array();
 	/**
 	 * List of paths to load models from
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_model_paths		= array();
 	/**
 	 * List of paths to load helpers from
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_helper_paths		= array();
 	/**
 	 * List of loaded base classes
-	 * Set by the controller class
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_base_classes		= array(); // Set by the controller class
 	/**
 	 * List of cached variables
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_cached_vars		= array();
 	/**
 	 * List of loaded classes
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_classes			= array();
 	/**
 	 * List of loaded files
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_loaded_files		= array();
 	/**
 	 * List of loaded models
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_models			= array();
 	/**
 	 * List of loaded helpers
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_ci_helpers			= array();
 	/**
 	 * List of class name mappings
 	 *
 	 * @var array
-	 * @access protected
 	 */
-	protected $_ci_varmap			= array('unit_test' => 'unit',
-											'user_agent' => 'agent');
+	protected $_ci_varmap			= array(
+							'unit_test' => 'unit',
+							'user_agent' => 'agent'
+							);
 
 	/**
 	 * Constructor
@@ -141,7 +130,7 @@
 		$this->_ci_model_paths = array(APPPATH);
 		$this->_ci_view_paths = array(VIEWPATH	=> TRUE);
 
-		log_message('debug', "Loader Class Initialized");
+		log_message('debug', 'Loader Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -162,7 +151,6 @@
 		$this->_base_classes =& is_loaded();
 
 		$this->_ci_autoloader();
-
 		return $this;
 	}
 
@@ -262,10 +250,10 @@
 		if (($last_slash = strrpos($model, '/')) !== FALSE)
 		{
 			// The path is in front of the last slash
-			$path = substr($model, 0, $last_slash + 1);
+			$path = substr($model, 0, ++$last_slash);
 
 			// And the model name behind it
-			$model = substr($model, $last_slash + 1);
+			$model = substr($model, $last_slash);
 		}
 
 		if ($name == '')
@@ -311,9 +299,7 @@
 			require_once($mod_path.'models/'.$path.$model.'.php');
 
 			$model = ucfirst($model);
-
 			$CI->$name = new $model();
-
 			$this->_ci_models[] = $name;
 			return;
 		}
@@ -350,7 +336,7 @@
 			return DB($params, $active_record);
 		}
 
-		// Initialize the db variable.  Needed to prevent
+		// Initialize the db variable. Needed to prevent
 		// reference errors with some configurations
 		$CI->db = '';
 
@@ -495,6 +481,20 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Get Variables
+	 *
+	 * Retrieve all loaded variables
+	 *
+	 * @return	array
+	 */
+	public function get_vars()
+	{
+		return $this->_ci_cached_vars;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Load Helper
 	 *
 	 * This function loads the specified helper file.
@@ -702,11 +702,11 @@
 
 		if ($path == '')
 		{
-			$void = array_shift($this->_ci_library_paths);
-			$void = array_shift($this->_ci_model_paths);
-			$void = array_shift($this->_ci_helper_paths);
-			$void = array_shift($this->_ci_view_paths);
-			$void = array_shift($config->_config_paths);
+			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);
 		}
 		else
 		{
@@ -794,7 +794,6 @@
 
 		// This allows anything loaded using $this->load (views, files, etc.)
 		// to become accessible from within the Controller and Model functions.
-
 		$_ci_CI =& get_instance();
 		foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
 		{
@@ -823,22 +822,20 @@
 		 *
 		 * We buffer the output for two reasons:
 		 * 1. Speed. You get a significant speed boost.
-		 * 2. So that the final rendered template can be
-		 * post-processed by the output class.  Why do we
-		 * need post processing?  For one thing, in order to
-		 * show the elapsed page load time.  Unless we
-		 * can intercept the content right before it's sent to
-		 * the browser and then stop the timer it won't be accurate.
+		 * 2. So that the final rendered template can be post-processed by
+		 *    the output class. Why do we need post processing? For one thing,
+		 *    in order to show the elapsed page load time. Unless we can
+		 *    intercept the content right before it's sent to the browser and
+		 *    then stop the timer it won't be accurate.
 		 */
 		ob_start();
 
 		// 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 ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
 		{
-			echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
+			echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
 		}
 		else
 		{
@@ -863,7 +860,6 @@
 		 * we are beyond the first level of output buffering so that
 		 * it can be seen and included properly by the first included
 		 * template and any subsequent ones. Oy!
-		 *
 		 */
 		if (ob_get_level() > $this->_ci_ob_level + 1)
 		{
@@ -901,10 +897,10 @@
 		if (($last_slash = strrpos($class, '/')) !== FALSE)
 		{
 			// Extract the path
-			$subdir = substr($class, 0, $last_slash + 1);
+			$subdir = substr($class, 0, ++$last_slash);
 
 			// Get the filename from the path
-			$class = substr($class, $last_slash + 1);
+			$class = substr($class, $last_slash);
 		}
 
 		// We'll test for both lowercase and capitalized versions of the file name
@@ -919,15 +915,15 @@
 
 				if ( ! file_exists($baseclass))
 				{
-					log_message('error', "Unable to load the requested class: ".$class);
-					show_error("Unable to load the requested class: ".$class);
+					log_message('error', 'Unable to load the requested class: '.$class);
+					show_error('Unable to load the requested class: '.$class);
 				}
 
-				// Safety:  Was the class already loaded by a previous call?
+				// Safety: Was the class already loaded by a previous call?
 				if (in_array($subclass, $this->_ci_loaded_files))
 				{
 					// Before we deem this to be a duplicate request, let's see
-					// if a custom object name is being supplied.  If so, we'll
+					// if a custom object name is being supplied. If so, we'll
 					// return a new instance of the object
 					if ( ! is_null($object_name))
 					{
@@ -939,7 +935,7 @@
 					}
 
 					$is_duplicate = TRUE;
-					log_message('debug', $class." class already loaded. Second attempt ignored.");
+					log_message('debug', $class.' class already loaded. Second attempt ignored.');
 					return;
 				}
 
@@ -956,17 +952,17 @@
 			{
 				$filepath = $path.'libraries/'.$subdir.$class.'.php';
 
-				// Does the file exist?  No?  Bummer...
+				// Does the file exist? No? Bummer...
 				if ( ! file_exists($filepath))
 				{
 					continue;
 				}
 
-				// Safety:  Was the class already loaded by a previous call?
+				// Safety: Was the class already loaded by a previous call?
 				if (in_array($filepath, $this->_ci_loaded_files))
 				{
 					// Before we deem this to be a duplicate request, let's see
-					// if a custom object name is being supplied.  If so, we'll
+					// if a custom object name is being supplied. If so, we'll
 					// return a new instance of the object
 					if ( ! is_null($object_name))
 					{
@@ -978,7 +974,7 @@
 					}
 
 					$is_duplicate = TRUE;
-					log_message('debug', $class." class already loaded. Second attempt ignored.");
+					log_message('debug', $class.' class already loaded. Second attempt ignored.');
 					return;
 				}
 
@@ -989,7 +985,7 @@
 
 		} // END FOREACH
 
-		// One last attempt.  Maybe the library is in a subdirectory, but it wasn't specified?
+		// One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
 		if ($subdir == '')
 		{
 			$path = strtolower($class).'/'.$class;
@@ -1000,8 +996,8 @@
 		// We do not issue errors if the load call failed due to a duplicate request
 		if ($is_duplicate == FALSE)
 		{
-			log_message('error', "Unable to load the requested class: ".$class);
-			show_error("Unable to load the requested class: ".$class);
+			log_message('error', 'Unable to load the requested class: '.$class);
+			show_error('Unable to load the requested class: '.$class);
 		}
 	}
 
@@ -1080,12 +1076,12 @@
 		// Is the class name valid?
 		if ( ! class_exists($name))
 		{
-			log_message('error', "Non-existent class: ".$name);
-			show_error("Non-existent class: ".$class);
+			log_message('error', 'Non-existent class: '.$name);
+			show_error('Non-existent class: '.$class);
 		}
 
 		// Set the variable name we will assign the class to
-		// Was a custom class name supplied?  If so we'll use it
+		// Was a custom class name supplied? If so we'll use it
 		$class = strtolower($class);
 
 		if (is_null($object_name))
@@ -1167,13 +1163,6 @@
 			}
 		}
 
-		// A little tweak to remain backward compatible
-		// The $autoload['core'] item was deprecated
-		if ( ! isset($autoload['libraries']) AND isset($autoload['core']))
-		{
-			$autoload['libraries'] = $autoload['core'];
-		}
-
 		// Load libraries
 		if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
 		{
@@ -1242,13 +1231,13 @@
 	{
 		if ( ! is_array($filename))
 		{
-			return array(strtolower(str_replace('.php', '', str_replace($extension, '', $filename)).$extension));
+			return array(strtolower(str_replace(array($extension, '.php'), '', $filename).$extension));
 		}
 		else
 		{
 			foreach ($filename as $key => $val)
 			{
-				$filename[$key] = strtolower(str_replace('.php', '', str_replace($extension, '', $val)).$extension);
+				$filename[$key] = strtolower(str_replace(array($extension, '.php'), '', $val).$extension);
 			}
 
 			return $filename;
@@ -1257,4 +1246,4 @@
 }
 
 /* End of file Loader.php */
-/* Location: ./system/core/Loader.php */
\ No newline at end of file
+/* Location: ./system/core/Loader.php */
diff --git a/system/core/Model.php b/system/core/Model.php
index c34bab6..a595a6a 100755
--- a/system/core/Model.php
+++ b/system/core/Model.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -38,14 +38,9 @@
  */
 class CI_Model {
 
-	/**
-	 * Constructor
-	 *
-	 * @access public
-	 */
-	function __construct()
+	public function __construct()
 	{
-		log_message('debug', "Model Class Initialized");
+		log_message('debug', 'Model Class Initialized');
 	}
 
 	/**
@@ -55,15 +50,13 @@
 	 * syntax as controllers.
 	 *
 	 * @param	string
-	 * @access private
 	 */
-	function __get($key)
+	public function __get($key)
 	{
 		$CI =& get_instance();
 		return $CI->$key;
 	}
 }
-// END Model Class
 
 /* End of file Model.php */
-/* Location: ./system/core/Model.php */
\ No newline at end of file
+/* Location: ./system/core/Model.php */
diff --git a/system/core/Output.php b/system/core/Output.php
index 9727a18..abd8a0e 100755
--- a/system/core/Output.php
+++ b/system/core/Output.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -44,64 +44,52 @@
 	 * Current output string
 	 *
 	 * @var string
-	 * @access 	protected
 	 */
 	protected $final_output;
 	/**
 	 * Cache expiration time
 	 *
 	 * @var int
-	 * @access 	protected
 	 */
 	protected $cache_expiration	= 0;
 	/**
 	 * List of server headers
 	 *
 	 * @var array
-	 * @access 	protected
 	 */
 	protected $headers			= array();
 	/**
 	 * List of mime types
 	 *
 	 * @var array
-	 * @access 	protected
 	 */
 	protected $mime_types		= array();
 	/**
 	 * Determines wether profiler is enabled
 	 *
 	 * @var book
-	 * @access 	protected
 	 */
 	protected $enable_profiler	= FALSE;
 	/**
 	 * Determines if output compression is enabled
 	 *
 	 * @var bool
-	 * @access 	protected
 	 */
 	protected $_zlib_oc			= FALSE;
 	/**
 	 * List of profiler sections
 	 *
 	 * @var array
-	 * @access 	protected
 	 */
 	protected $_profiler_sections = array();
 	/**
 	 * Whether or not to parse variables like {elapsed_time} and {memory_usage}
 	 *
 	 * @var bool
-	 * @access 	protected
 	 */
 	protected $parse_exec_vars	= TRUE;
 
-	/**
-	 * Constructor
-	 *
-	 */
-	function __construct()
+	public function __construct()
 	{
 		$this->_zlib_oc = @ini_get('zlib.output_compression');
 
@@ -117,8 +105,7 @@
 
 
 		$this->mime_types = $mimes;
-
-		log_message('debug', "Output Class Initialized");
+		log_message('debug', 'Output Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -128,10 +115,9 @@
 	 *
 	 * Returns the current output string
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function get_output()
+	public function get_output()
 	{
 		return $this->final_output;
 	}
@@ -143,14 +129,12 @@
 	 *
 	 * Sets the output string
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
-	function set_output($output)
+	public function set_output($output)
 	{
 		$this->final_output = $output;
-
 		return $this;
 	}
 
@@ -161,11 +145,10 @@
 	 *
 	 * Appends data onto the output string
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
-	function append_output($output)
+	public function append_output($output)
 	{
 		if ($this->final_output == '')
 		{
@@ -189,25 +172,22 @@
 	 * 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...
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param 	bool
 	 * @return	void
 	 */
-	function set_header($header, $replace = TRUE)
+	public function set_header($header, $replace = TRUE)
 	{
 		// If zlib.output_compression is enabled it will compress the output,
 		// 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)
 		{
 			return;
 		}
 
 		$this->headers[] = array($header, $replace);
-
 		return $this;
 	}
 
@@ -216,11 +196,10 @@
 	/**
 	 * Set Content Type Header
 	 *
-	 * @access	public
 	 * @param	string	extension of the file we're outputting
 	 * @return	void
 	 */
-	function set_content_type($mime_type)
+	public function set_content_type($mime_type)
 	{
 		if (strpos($mime_type, '/') === FALSE)
 		{
@@ -241,7 +220,6 @@
 		$header = 'Content-Type: '.$mime_type;
 
 		$this->headers[] = array($header, TRUE);
-
 		return $this;
 	}
 
@@ -251,15 +229,13 @@
 	 * Set HTTP Status Header
 	 * moved to Common procedural functions in 1.7.2
 	 *
-	 * @access	public
 	 * @param	int		the status code
 	 * @param	string
 	 * @return	void
 	 */
-	function set_status_header($code = 200, $text = '')
+	public function set_status_header($code = 200, $text = '')
 	{
 		set_status_header($code, $text);
-
 		return $this;
 	}
 
@@ -268,14 +244,12 @@
 	/**
 	 * Enable/disable Profiler
 	 *
-	 * @access	public
 	 * @param	bool
 	 * @return	void
 	 */
-	function enable_profiler($val = TRUE)
+	public function enable_profiler($val = TRUE)
 	{
 		$this->enable_profiler = (is_bool($val)) ? $val : TRUE;
-
 		return $this;
 	}
 
@@ -286,11 +260,10 @@
 	 *
 	 * Allows override of default / config settings for Profiler section display
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	void
 	 */
-	function set_profiler_sections($sections)
+	public function set_profiler_sections($sections)
 	{
 		foreach ($sections as $section => $enable)
 		{
@@ -305,14 +278,12 @@
 	/**
 	 * Set Cache
 	 *
-	 * @access	public
 	 * @param	integer
 	 * @return	void
 	 */
-	function cache($time)
+	public function cache($time)
 	{
 		$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
-
 		return $this;
 	}
 
@@ -329,11 +300,10 @@
 	 * with any server headers and profile data.  It also stops the
 	 * benchmark timer so the page rendering speed and memory usage can be shown.
 	 *
-	 * @access	public
 	 * @param 	string
 	 * @return	mixed
 	 */
-	function _display($output = '')
+	public function _display($output = '')
 	{
 		// Note:  We use globals because we can't use $CI =& get_instance()
 		// since this function is sometimes called by the caching mechanism,
@@ -375,22 +345,17 @@
 		{
 			$memory	 = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
 
-			$output = str_replace('{elapsed_time}', $elapsed, $output);
-			$output = str_replace('{memory_usage}', $memory, $output);
+			$output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
 		}
 
 		// --------------------------------------------------------------------
 
 		// 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)
 		{
-			if (extension_loaded('zlib'))
-			{
-				if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
-				{
-					ob_start('ob_gzhandler');
-				}
-			}
+			ob_start('ob_gzhandler');
 		}
 
 		// --------------------------------------------------------------------
@@ -412,8 +377,8 @@
 		if ( ! isset($CI))
 		{
 			echo $output;
-			log_message('debug', "Final output sent to browser");
-			log_message('debug', "Total execution time: ".$elapsed);
+			log_message('debug', 'Final output sent to browser');
+			log_message('debug', 'Total execution time: '.$elapsed);
 			return TRUE;
 		}
 
@@ -424,7 +389,6 @@
 		if ($this->enable_profiler == TRUE)
 		{
 			$CI->load->library('profiler');
-
 			if ( ! empty($this->_profiler_sections))
 			{
 				$CI->profiler->set_sections($this->_profiler_sections);
@@ -432,20 +396,13 @@
 
 			// If the output data contains closing </body> and </html> tags
 			// we will remove them and add them back after we insert the profile data
-			if (preg_match("|</body>.*?</html>|is", $output))
+			$output = preg_replace('|</body>.*?</html>|is', '', $output, -1, $count).$CI->profiler->run();
+			if ($count > 0)
 			{
-				$output  = preg_replace("|</body>.*?</html>|is", '', $output);
-				$output .= $CI->profiler->run();
 				$output .= '</body></html>';
 			}
-			else
-			{
-				$output .= $CI->profiler->run();
-			}
 		}
 
-		// --------------------------------------------------------------------
-
 		// Does the controller contain a function named _output()?
 		// If so send the output there.  Otherwise, echo it.
 		if (method_exists($CI, '_output'))
@@ -454,11 +411,11 @@
 		}
 		else
 		{
-			echo $output;  // Send it to the browser!
+			echo $output; // Send it to the browser!
 		}
 
-		log_message('debug', "Final output sent to browser");
-		log_message('debug', "Total execution time: ".$elapsed);
+		log_message('debug', 'Final output sent to browser');
+		log_message('debug', 'Total execution time: '.$elapsed);
 	}
 
 	// --------------------------------------------------------------------
@@ -466,20 +423,18 @@
 	/**
 	 * Write a Cache File
 	 *
-	 * @access	public
 	 * @param 	string
 	 * @return	void
 	 */
-	function _write_cache($output)
+	public function _write_cache($output)
 	{
 		$CI =& get_instance();
 		$path = $CI->config->item('cache_path');
-
 		$cache_path = ($path == '') ? APPPATH.'cache/' : $path;
 
 		if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))
 		{
-			log_message('error', "Unable to write cache file: ".$cache_path);
+			log_message('error', 'Unable to write cache file: '.$cache_path);
 			return;
 		}
 
@@ -491,7 +446,7 @@
 
 		if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE))
 		{
-			log_message('error', "Unable to write cache file: ".$cache_path);
+			log_message('error', 'Unable to write cache file: '.$cache_path);
 			return;
 		}
 
@@ -504,13 +459,13 @@
 		}
 		else
 		{
-			log_message('error', "Unable to secure a file lock for file at: ".$cache_path);
+			log_message('error', 'Unable to secure a file lock for file at: '.$cache_path);
 			return;
 		}
 		fclose($fp);
 		@chmod($cache_path, FILE_WRITE_MODE);
 
-		log_message('debug', "Cache file written: ".$cache_path);
+		log_message('debug', 'Cache file written: '.$cache_path);
 	}
 
 	// --------------------------------------------------------------------
@@ -518,69 +473,51 @@
 	/**
 	 * Update/serve a cached file
 	 *
-	 * @access	public
 	 * @param 	object	config class
 	 * @param 	object	uri class
 	 * @return	void
 	 */
-	function _display_cache(&$CFG, &$URI)
+	public function _display_cache(&$CFG, &$URI)
 	{
 		$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;
-
+		// 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;
 		$filepath = $cache_path.md5($uri);
 
-		if ( ! @file_exists($filepath))
-		{
-			return FALSE;
-		}
-
-		if ( ! $fp = @fopen($filepath, FOPEN_READ))
+		if ( ! @file_exists($filepath) OR ! $fp = @fopen($filepath, FOPEN_READ))
 		{
 			return FALSE;
 		}
 
 		flock($fp, LOCK_SH);
 
-		$cache = '';
-		if (filesize($filepath) > 0)
-		{
-			$cache = fread($fp, filesize($filepath));
-		}
+		$cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : '';
 
 		flock($fp, LOCK_UN);
 		fclose($fp);
 
 		// Strip out the embedded timestamp
-		if ( ! preg_match("/(\d+TS--->)/", $cache, $match))
+		if ( ! preg_match('/(\d+TS--->)/', $cache, $match))
 		{
 			return FALSE;
 		}
 
 		// Has the file expired? If so we'll delete it.
-		if (time() >= trim(str_replace('TS--->', '', $match['1'])))
+		if (time() >= trim(str_replace('TS--->', '', $match[1])) && is_really_writable($cache_path))
 		{
-			if (is_really_writable($cache_path))
-			{
-				@unlink($filepath);
-				log_message('debug', "Cache file has expired. File deleted");
-				return FALSE;
-			}
+			@unlink($filepath);
+			log_message('debug', 'Cache file has expired. File deleted.');
+			return FALSE;
 		}
 
 		// Display the cache
-		$this->_display(str_replace($match['0'], '', $cache));
-		log_message('debug', "Cache file is current. Sending it to browser.");
+		$this->_display(str_replace($match[0], '', $cache));
+		log_message('debug', 'Cache file is current. Sending it to browser.');
 		return TRUE;
 	}
 
-
 }
-// END Output Class
 
 /* End of file Output.php */
-/* Location: ./system/core/Output.php */
\ No newline at end of file
+/* Location: ./system/core/Output.php */
diff --git a/system/core/Router.php b/system/core/Router.php
index 748678d..d213195 100755
--- a/system/core/Router.php
+++ b/system/core/Router.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -44,62 +44,55 @@
 	 * Config class
 	 *
 	 * @var object
-	 * @access public
 	 */
-	var $config;
+	public $config;
 	/**
 	 * List of routes
 	 *
 	 * @var array
-	 * @access public
 	 */
-	var $routes			= array();
+	public $routes			= array();
 	/**
 	 * List of error routes
 	 *
 	 * @var array
-	 * @access public
 	 */
-	var $error_routes	= array();
+	public $error_routes	= array();
 	/**
 	 * Current class name
 	 *
 	 * @var string
-	 * @access public
 	 */
-	var $class			= '';
+	public $class			= '';
 	/**
 	 * Current method name
 	 *
 	 * @var string
-	 * @access public
 	 */
-	var $method			= 'index';
+	public $method			= 'index';
 	/**
 	 * Sub-directory that contains the requested controller class
 	 *
 	 * @var string
-	 * @access public
 	 */
-	var $directory		= '';
+	public $directory		= '';
 	/**
 	 * Default controller (and method if specific)
 	 *
 	 * @var string
-	 * @access public
 	 */
-	var $default_controller;
+	public $default_controller;
 
 	/**
 	 * Constructor
 	 *
 	 * Runs the route mapping function.
 	 */
-	function __construct()
+	public function __construct()
 	{
 		$this->config =& load_class('Config', 'core');
 		$this->uri =& load_class('URI', 'core');
-		log_message('debug', "Router Class Initialized");
+		log_message('debug', 'Router Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -110,12 +103,11 @@
 	 * This function determines what should be served based on the URI request,
 	 * as well as any "routes" that have been set in the routing config file.
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _set_routing()
+	public function _set_routing()
 	{
-		// Are query strings enabled in the config file?  Normally CI doesn't utilize query strings
+		// Are query strings enabled in the config file? Normally CI doesn't utilize query strings
 		// since URI segments are more search-engine friendly, but they can optionally be used.
 		// If this feature is enabled, we will gather the directory/class/method a little differently
 		$segments = array();
@@ -157,7 +149,7 @@
 		// the URI doesn't correlated to a valid controller.
 		$this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);
 
-		// Were there any query string segments?  If so, we'll validate them and bail out since we're done.
+		// Were there any query string segments? If so, we'll validate them and bail out since we're done.
 		if (count($segments) > 0)
 		{
 			return $this->_validate_request($segments);
@@ -172,17 +164,10 @@
 			return $this->_set_default_controller();
 		}
 
-		// Do we need to remove the URL suffix?
-		$this->uri->_remove_url_suffix();
-
-		// Compile the segments into an array
-		$this->uri->_explode_segments();
-
-		// Parse any custom routing that may exist
-		$this->_parse_routes();
-
-		// Re-index the segment array so that it starts with 1 rather than 0
-		$this->uri->_reindex_segments();
+		$this->uri->_remove_url_suffix(); // Remove the URL suffix
+		$this->uri->_explode_segments(); // Compile the segments into an array
+		$this->_parse_routes(); // Parse any custom routing that may exist
+		$this->uri->_reindex_segments(); // Re-index the segment array so that it starts with 1 rather than 0
 	}
 
 	// --------------------------------------------------------------------
@@ -190,20 +175,18 @@
 	/**
 	 * Set the default controller
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _set_default_controller()
+	protected function _set_default_controller()
 	{
 		if ($this->default_controller === FALSE)
 		{
-			show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file.");
+			show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
 		}
 		// Is the method being specified?
 		if (strpos($this->default_controller, '/') !== FALSE)
 		{
 			$x = explode('/', $this->default_controller);
-
 			$this->set_class($x[0]);
 			$this->set_method($x[1]);
 			$this->_set_request($x);
@@ -218,7 +201,7 @@
 		// re-index the routed segments array so it starts with 1 rather than 0
 		$this->uri->_reindex_segments();
 
-		log_message('debug', "No URI present. Default controller set.");
+		log_message('debug', 'No URI present. Default controller set.');
 	}
 
 	// --------------------------------------------------------------------
@@ -229,16 +212,15 @@
 	 * This function takes an array of URI segments as
 	 * input, and sets the current class/method
 	 *
-	 * @access	private
 	 * @param	array
 	 * @param	bool
 	 * @return	void
 	 */
-	function _set_request($segments = array())
+	protected function _set_request($segments = array())
 	{
 		$segments = $this->_validate_request($segments);
 
-		if (count($segments) == 0)
+		if (count($segments) === 0)
 		{
 			return $this->_set_default_controller();
 		}
@@ -269,13 +251,12 @@
 	 * Validates the supplied segments.  Attempts to determine the path to
 	 * the controller.
 	 *
-	 * @access	private
 	 * @param	array
 	 * @return	array
 	 */
-	function _validate_request($segments)
+	protected function _validate_request($segments)
 	{
-		if (count($segments) == 0)
+		if (count($segments) === 0)
 		{
 			return $segments;
 		}
@@ -301,7 +282,6 @@
 					if ( ! empty($this->routes['404_override']))
 					{
 						$x = explode('/', $this->routes['404_override']);
-
 						$this->set_directory('');
 						$this->set_class($x[0]);
 						$this->set_method(isset($x[1]) ? $x[1] : 'index');
@@ -320,7 +300,6 @@
 				if (strpos($this->default_controller, '/') !== FALSE)
 				{
 					$x = explode('/', $this->default_controller);
-
 					$this->set_class($x[0]);
 					$this->set_method($x[1]);
 				}
@@ -344,18 +323,16 @@
 
 
 		// If we've gotten this far it means that the URI does not correlate to a valid
-		// controller class.  We will now see if there is an override
+		// controller class. We will now see if there is an override
 		if ( ! empty($this->routes['404_override']))
 		{
 			$x = explode('/', $this->routes['404_override']);
-
 			$this->set_class($x[0]);
 			$this->set_method(isset($x[1]) ? $x[1] : 'index');
 
 			return $x;
 		}
 
-
 		// Nothing else to do at this point but show a 404
 		show_404($segments[0]);
 	}
@@ -369,10 +346,9 @@
 	 * the config/routes.php file against the URI to
 	 * determine if the class/method need to be remapped.
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _parse_routes()
+	protected function _parse_routes()
 	{
 		// Turn the segment array into a URI string
 		$uri = implode('/', $this->uri->segments);
@@ -387,7 +363,7 @@
 		foreach ($this->routes as $key => $val)
 		{
 			// Convert wild-cards to RegEx
-			$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
+			$key = str_replace(array(':any', ':num'), array('.+', '[0-9]+'), $key);
 
 			// Does the RegEx match?
 			if (preg_match('#^'.$key.'$#', $uri))
@@ -412,11 +388,10 @@
 	/**
 	 * Set the class name
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
-	function set_class($class)
+	public function set_class($class)
 	{
 		$this->class = str_replace(array('/', '.'), '', $class);
 	}
@@ -426,10 +401,9 @@
 	/**
 	 * Fetch the current class
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function fetch_class()
+	public function fetch_class()
 	{
 		return $this->class;
 	}
@@ -439,11 +413,10 @@
 	/**
 	 *  Set the method name
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
-	function set_method($method)
+	public function set_method($method)
 	{
 		$this->method = $method;
 	}
@@ -453,10 +426,9 @@
 	/**
 	 *  Fetch the current method
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function fetch_method()
+	public function fetch_method()
 	{
 		if ($this->method == $this->fetch_class())
 		{
@@ -471,11 +443,10 @@
 	/**
 	 *  Set the directory name
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
-	function set_directory($dir)
+	public function set_directory($dir)
 	{
 		$this->directory = str_replace(array('/', '.'), '', $dir).'/';
 	}
@@ -485,10 +456,9 @@
 	/**
 	 *  Fetch the sub-directory (if any) that contains the requested controller class
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function fetch_directory()
+	public function fetch_directory()
 	{
 		return $this->directory;
 	}
@@ -498,11 +468,10 @@
 	/**
 	 *  Set the controller overrides
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	null
 	 */
-	function _set_overrides($routing)
+	public function _set_overrides($routing)
 	{
 		if ( ! is_array($routing))
 		{
@@ -526,9 +495,7 @@
 		}
 	}
 
-
 }
-// END Router Class
 
 /* End of file Router.php */
-/* Location: ./system/core/Router.php */
\ No newline at end of file
+/* Location: ./system/core/Router.php */
diff --git a/system/core/Security.php b/system/core/Security.php
index 60a64f3..1007f61 100755
--- a/system/core/Security.php
+++ b/system/core/Security.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -42,7 +42,6 @@
 	 * Random Hash for protecting URLs
 	 *
 	 * @var string
-	 * @access protected
 	 */
 	protected $_xss_hash			= '';
 
@@ -50,7 +49,6 @@
 	 * Random Hash for Cross Site Request Forgery Protection Cookie
 	 *
 	 * @var string
-	 * @access protected
 	 */
 	protected $_csrf_hash			= '';
 
@@ -59,7 +57,6 @@
 	 * Defaults to two hours (in seconds)
 	 *
 	 * @var int
-	 * @access protected
 	 */
 	protected $_csrf_expire			= 7200;
 
@@ -67,7 +64,6 @@
 	 * Token name for Cross Site Request Forgery Protection Cookie
 	 *
 	 * @var string
-	 * @access protected
 	 */
 	protected $_csrf_token_name		= 'ci_csrf_token';
 
@@ -75,46 +71,39 @@
 	 * Cookie name for Cross Site Request Forgery Protection Cookie
 	 *
 	 * @var string
-	 * @access protected
 	 */
-	protected $_csrf_cookie_name	= 'ci_csrf_token';
+	protected $_csrf_cookie_name		= 'ci_csrf_token';
 
 	/**
 	 * List of never allowed strings
 	 *
 	 * @var array
-	 * @access protected
 	 */
-
 	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;'
-	);
+						'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
 	 *
 	 * @var array
-	 * @access protected
 	 */
 	protected $_never_allowed_regex = array(
-					"javascript\s*:"			=> '[removed]',
-					"expression\s*(\(|&\#40;)"	=> '[removed]', // CSS and IE
-					"vbscript\s*:"				=> '[removed]', // IE, surprise!
-					"Redirect\s+302"			=> '[removed]'
-	);
+						'javascript\s*:',
+						'expression\s*(\(|&\#40;)', // CSS and IE
+						'vbscript\s*:', // IE, surprise!
+						'Redirect\s+302'
+					);
 
-	/**
-	 * Constructor
-	 */
 	public function __construct()
 	{
 		// CSRF config
@@ -135,7 +124,7 @@
 		// Set the CSRF hash
 		$this->_csrf_set_hash();
 
-		log_message('debug', "Security Class Initialized");
+		log_message('debug', 'Security Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -148,7 +137,7 @@
 	public function csrf_verify()
 	{
 		// If no POST data exists we will set the CSRF cookie
-		if (count($_POST) == 0)
+		if (count($_POST) === 0)
 		{
 			return $this->csrf_set_cookie();
 		}
@@ -164,30 +153,27 @@
 		}
 
 		// 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]))
+		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?
 		{
 			$this->csrf_show_error();
 		}
 
-		// Do the tokens match?
-		if ($_POST[$this->_csrf_token_name] != $_COOKIE[$this->_csrf_cookie_name])
-		{
-			$this->csrf_show_error();
-		}
-
-		// We kill this since we're done and we don't want to
-		// polute the _POST array
+		// We kill this since we're done and we don't want to polute the _POST array
 		unset($_POST[$this->_csrf_token_name]);
 
-		// Nothing should last forever
-		unset($_COOKIE[$this->_csrf_cookie_name]);
-		$this->_csrf_hash = '';
+		// Regenerate on every submission?
+		if (config_item('csrf_regenerate'))
+		{
+			// Nothing should last forever
+			unset($_COOKIE[$this->_csrf_cookie_name]);
+			$this->_csrf_hash = '';
+		}
+
 		$this->_csrf_set_hash();
 		$this->csrf_set_cookie();
 
-		log_message('debug', "CSRF token verified");
-
+		log_message('debug', 'CSRF token verified');
 		return $this;
 	}
 
@@ -203,19 +189,13 @@
 		$expire = time() + $this->_csrf_expire;
 		$secure_cookie = (bool) config_item('cookie_secure');
 
-		if ($secure_cookie)
+		if ($secure_cookie && ( ! isset($_SERVER['HTTPS']) OR $_SERVER['HTTPS'] == 'off' OR ! $_SERVER['HTTPS']))
 		{
-			$req = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : FALSE;
-
-			if ( ! $req OR $req == 'off')
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
 
 		setcookie($this->_csrf_cookie_name, $this->_csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), $secure_cookie);
-
-		log_message('debug', "CRSF cookie Set");
+		log_message('debug', 'CRSF cookie Set');
 
 		return $this;
 	}
@@ -253,7 +233,7 @@
 	 *
 	 * Getter Method
 	 *
-	 * @return 	string 	self::csrf_token_name
+	 * @return 	string 	self::_csrf_token_name
 	 */
 	public function get_csrf_token_name()
 	{
@@ -273,7 +253,7 @@
 	 * the filter.
 	 *
 	 * Note: This function should only be used to deal with data
-	 * upon submission.  It's not something that should
+	 * upon submission. It's not something that should
 	 * be used for general runtime processing.
 	 *
 	 * This function was based in part on some code and ideas I
@@ -290,10 +270,7 @@
 	 */
 	public function xss_clean($str, $is_image = FALSE)
 	{
-		/*
-		 * Is the string an array?
-		 *
-		 */
+		// Is the string an array?
 		if (is_array($str))
 		{
 			while (list($key) = each($str))
@@ -304,13 +281,8 @@
 			return $str;
 		}
 
-		/*
-		 * Remove Invisible Characters
-		 */
-		$str = remove_invisible_characters($str);
-
-		// Validate Entities in URLs
-		$str = $this->_validate_entities($str);
+		// Remove Invisible Characters and validate entities in URLs
+		$str = $this->_validate_entities(remove_invisible_characters($str));
 
 		/*
 		 * URL Decode
@@ -320,7 +292,6 @@
 		 * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a>
 		 *
 		 * Note: Use rawurldecode() so it does not remove plus signs
-		 *
 		 */
 		$str = rawurldecode($str);
 
@@ -330,16 +301,11 @@
 		 * This permits our tests below to work reliably.
 		 * We only convert entities that are within tags since
 		 * these are the ones that will pose security problems.
-		 *
 		 */
-
 		$str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str);
+		$str = preg_replace_callback('/<\w+.*?(?=>|<|$)/si', array($this, '_decode_entity'), $str);
 
-		$str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_decode_entity'), $str);
-
-		/*
-		 * Remove Invisible Characters Again!
-		 */
+		// Remove Invisible Characters Again!
 		$str = remove_invisible_characters($str);
 
 		/*
@@ -350,15 +316,9 @@
 		 * NOTE: preg_replace was found to be amazingly slow here on
 		 * large blocks of data, so we use str_replace.
 		 */
+		$str = str_replace("\t", ' ', $str);
 
-		if (strpos($str, "\t") !== FALSE)
-		{
-			$str = str_replace("\t", ' ', $str);
-		}
-
-		/*
-		 * Capture converted string for later comparison
-		 */
+		// Capture converted string for later comparison
 		$converted_string = $str;
 
 		// Remove Strings that are never allowed
@@ -378,7 +338,7 @@
 			// Images have a tendency to have the PHP short opening and
 			// closing tags every so often so we skip those and only
 			// do the long opening tags.
-			$str = preg_replace('/<\?(php)/i', "&lt;?\\1", $str);
+			$str = preg_replace('/<\?(php)/i', '&lt;?\\1', $str);
 		}
 		else
 		{
@@ -415,19 +375,19 @@
 		{
 			$original = $str;
 
-			if (preg_match("/<a/i", $str))
+			if (preg_match('/<a/i', $str))
 			{
-				$str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str);
+				$str = preg_replace_callback('#<a\s+([^>]*?)(>|$)#si', array($this, '_js_link_removal'), $str);
 			}
 
-			if (preg_match("/<img/i", $str))
+			if (preg_match('/<img/i', $str))
 			{
-				$str = preg_replace_callback("#<img\s+([^>]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str);
+				$str = preg_replace_callback('#<img\s+([^>]*?)(\s?/?>|$)#si', array($this, '_js_img_removal'), $str);
 			}
 
-			if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str))
+			if (preg_match('/(script|xss)/i', $str))
 			{
-				$str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str);
+				$str = preg_replace('#<(/*)(script|xss)(.*?)\>#si', '[removed]', $str);
 			}
 		}
 		while($original != $str);
@@ -454,14 +414,16 @@
 		 *
 		 * Similar to above, only instead of looking for
 		 * tags it looks for PHP and JavaScript commands
-		 * that are disallowed.  Rather than removing the
+		 * that are disallowed. Rather than removing the
 		 * code, it simply converts the parenthesis to entities
 		 * rendering the code un-executable.
 		 *
 		 * For example:	eval('some code')
-		 * Becomes:		eval&#40;'some code'&#41;
+		 * Becomes:	eval&#40;'some code'&#41;
 		 */
-		$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2&#40;\\3&#41;", $str);
+		$str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si',
+					'\\1\\2&#40;\\3&#41;',
+					$str);
 
 
 		// Final clean up
@@ -478,13 +440,12 @@
 		 * string post-removal of XSS, then it fails, as there was unwanted XSS
 		 * code found and removed/changed during processing.
 		 */
-
 		if ($is_image === TRUE)
 		{
-			return ($str === $converted_string) ? TRUE : FALSE;
+			return ($str === $converted_string);
 		}
 
-		log_message('debug', "XSS Filtering completed");
+		log_message('debug', 'XSS Filtering completed');
 		return $str;
 	}
 
@@ -516,7 +477,7 @@
 	 * The reason we are not using html_entity_decode() by itself is because
 	 * while it is not technically correct to leave out the semicolon
 	 * at the end of an entity most browsers will still interpret the entity
-	 * correctly.  html_entity_decode() does not convert entities without
+	 * correctly. html_entity_decode() does not convert entities without
 	 * semicolons, so we are left with our own little solution here. Bummer.
 	 *
 	 * @param	string
@@ -552,38 +513,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)
 		{
@@ -636,26 +582,26 @@
 		if ($is_image === TRUE)
 		{
 			/*
-			 * Adobe Photoshop puts XML metadata into JFIF images, 
+			 * Adobe Photoshop puts XML metadata into JFIF images,
 			 * including namespacing, so we have to allow this for images.
 			 */
 			unset($evil_attributes[array_search('xmlns', $evil_attributes)]);
 		}
-		
+
 		do {
 			$count = 0;
 			$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], '/');
 			}
-			
+
 			// find occurrences of illegal attribute strings with quotes (042 and 047 are octal quotes)
-			preg_match_all("/(".implode('|', $evil_attributes).")\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is",  $str, $matches, PREG_SET_ORDER);
+			preg_match_all('/('.implode('|', $evil_attributes).')\s*=\s*(\042|\047)([^\\2]*?)(\\2)/is',  $str, $matches, PREG_SET_ORDER);
 
 			foreach ($matches as $attr)
 			{
@@ -665,11 +611,11 @@
 			// 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$2$4$5', $str, -1, $count);
 			}
-			
+
 		} while ($count);
-		
+
 		return $str;
 	}
 
@@ -685,14 +631,9 @@
 	 */
 	protected function _sanitize_naughty_html($matches)
 	{
-		// encode opening brace
-		$str = '&lt;'.$matches[1].$matches[2].$matches[3];
-
-		// encode captured opening or closing brace to prevent recursive vectors
-		$str .= str_replace(array('>', '<'), array('&gt;', '&lt;'),
-							$matches[4]);
-
-		return $str;
+		return '&lt;'.$matches[1].$matches[2].$matches[3] // encode opening brace
+			// encode captured opening or closing brace to prevent recursive vectors:
+			. str_replace(array('>', '<'), array('&gt;', '&lt;'), $matches[4]);
 	}
 
 	// --------------------------------------------------------------------
@@ -710,9 +651,12 @@
 	 */
 	protected function _js_link_removal($match)
 	{
-		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
-
-		return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);
+		return str_replace($match[1],
+					preg_replace('#href=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
+							'',
+							$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
+					),
+					$match[0]);
 	}
 
 	// --------------------------------------------------------------------
@@ -730,9 +674,12 @@
 	 */
 	protected function _js_img_removal($match)
 	{
-		$attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]));
-
-		return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]);
+		return str_replace($match[1],
+					preg_replace('#src=.*?(alert\(|alert&\#40;|javascript\:|livescript\:|mocha\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si',
+							'',
+							$this->_filter_attributes(str_replace(array('<', '>'), '', $match[1]))
+					),
+					$match[0]);
 	}
 
 	// --------------------------------------------------------------------
@@ -763,12 +710,11 @@
 	protected function _filter_attributes($str)
 	{
 		$out = '';
-
 		if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches))
 		{
 			foreach ($matches[0] as $match)
 			{
-				$out .= preg_replace("#/\*.*?\*/#s", '', $match);
+				$out .= preg_replace('#/\*.*?\*/#s', '', $match);
 			}
 		}
 
@@ -806,33 +752,28 @@
 		 * Protect GET variables in URLs
 		 */
 
-		 // 901119URL5918AMP18930PROTECT8198
-
-		$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash()."\\1=\\2", $str);
+		// 901119URL5918AMP18930PROTECT8198
+		$str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash().'\\1=\\2', $str);
 
 		/*
 		 * Validate standard character entities
 		 *
 		 * Add a semicolon if missing.  We do this to enable
 		 * the conversion of entities to ASCII later.
-		 *
 		 */
-		$str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str);
+		$str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', '\\1;\\2', $str);
 
 		/*
 		 * Validate UTF16 two byte encoding (x00)
 		 *
 		 * Just as above, adds a semicolon if missing.
-		 *
 		 */
-		$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str);
+		$str = preg_replace('#(&\#x?)([0-9A-F]+);?#i', '\\1\\2;', $str);
 
 		/*
 		 * Un-Protect GET variables in URLs
 		 */
-		$str = str_replace($this->xss_hash(), '&', $str);
-
-		return $str;
+		return str_replace($this->xss_hash(), '&', $str);
 	}
 
 	// ----------------------------------------------------------------------
@@ -847,14 +788,11 @@
 	 */
 	protected function _do_never_allowed($str)
 	{
-		foreach ($this->_never_allowed_str as $key => $val)
-		{
-			$str = str_replace($key, $val, $str);
-		}
+		$str = str_replace(array_keys($this->_never_allowed_str), $this->_never_allowed_str, $str);
 
-		foreach ($this->_never_allowed_regex as $key => $val)
+		foreach ($this->_never_allowed_regex as $regex)
 		{
-			$str = preg_replace("#".$key."#i", $val, $str);
+			$str = preg_replace('#'.$regex.'#i', '[removed]', $str);
 		}
 
 		return $str;
@@ -891,4 +829,4 @@
 }
 
 /* End of file Security.php */
-/* Location: ./system/core/Security.php */
\ No newline at end of file
+/* Location: ./system/core/Security.php */
diff --git a/system/core/URI.php b/system/core/URI.php
index 7ab3a9e..d9f4e3b 100755
--- a/system/core/URI.php
+++ b/system/core/URI.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,11 +18,10 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
 // ------------------------------------------------------------------------
@@ -44,59 +43,53 @@
 	 * List of cached uri segments
 	 *
 	 * @var array
-	 * @access public
 	 */
-	var	$keyval			= array();
+	public $keyval		= array();
 	/**
 	 * Current uri string
 	 *
 	 * @var string
-	 * @access public
 	 */
-	var $uri_string;
+	public $uri_string;
 	/**
 	 * List of uri segments
 	 *
 	 * @var array
-	 * @access public
 	 */
-	var $segments		= array();
+	public $segments	= array();
 	/**
 	 * Re-indexed list of uri segments
 	 * Starts at 1 instead of 0
 	 *
 	 * @var array
-	 * @access public
 	 */
-	var $rsegments		= array();
+	public $rsegments	= array();
 
 	/**
 	 * Constructor
 	 *
-	 * Simply globalizes the $RTR object.  The front
+	 * Simply globalizes the $RTR object. The front
 	 * loads the Router class early on so it's not available
 	 * normally as other classes are.
-	 *
-	 * @access	public
 	 */
-	function __construct()
+	public function __construct()
 	{
 		$this->config =& load_class('Config', 'core');
-		log_message('debug', "URI Class Initialized");
+		log_message('debug', 'URI Class Initialized');
 	}
 
-
 	// --------------------------------------------------------------------
 
 	/**
 	 * Get the URI String
 	 *
-	 * @access	private
-	 * @return	string
+	 * Called by CI_Router
+	 *
+	 * @return	void
 	 */
-	function _fetch_uri_string()
+	public function _fetch_uri_string()
 	{
-		if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
+		if (strtoupper($this->config->item('uri_protocol')) === 'AUTO')
 		{
 			// Is the request coming from the command line?
 			if ($this->_is_cli_request())
@@ -115,14 +108,14 @@
 			// 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)
+			if (trim($path, '/') != '' && $path !== '/'.SELF)
 			{
 				$this->_set_uri_string($path);
 				return;
 			}
 
 			// No PATH_INFO?... What about QUERY_STRING?
-			$path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
+			$path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
 			if (trim($path, '/') != '')
 			{
 				$this->_set_uri_string($path);
@@ -130,7 +123,7 @@
 			}
 
 			// 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;
@@ -143,12 +136,12 @@
 
 		$uri = strtoupper($this->config->item('uri_protocol'));
 
-		if ($uri == 'REQUEST_URI')
+		if ($uri === 'REQUEST_URI')
 		{
 			$this->_set_uri_string($this->_detect_uri());
 			return;
 		}
-		elseif ($uri == 'CLI')
+		elseif ($uri === 'CLI')
 		{
 			$this->_set_uri_string($this->_parse_cli_args());
 			return;
@@ -163,17 +156,16 @@
 	/**
 	 * Set the URI String
 	 *
-	 * @access	public
 	 * @param 	string
-	 * @return	string
+	 * @return	void
 	 */
-	function _set_uri_string($str)
+	public function _set_uri_string($str)
 	{
 		// Filter out control characters
 		$str = remove_invisible_characters($str, FALSE);
 
 		// If the URI contains only a slash we'll kill it
-		$this->uri_string = ($str == '/') ? '' : $str;
+		$this->uri_string = ($str === '/') ? '' : $str;
 	}
 
 	// --------------------------------------------------------------------
@@ -184,7 +176,6 @@
 	 * This function will detect the URI automatically and fix the query string
 	 * if necessary.
 	 *
-	 * @access	private
 	 * @return	string
 	 */
 	protected function _detect_uri()
@@ -223,7 +214,7 @@
 			$_GET = array();
 		}
 
-		if ($uri == '/' || empty($uri))
+		if ($uri == '/' OR empty($uri))
 		{
 			return '/';
 		}
@@ -256,13 +247,11 @@
 	 *
 	 * Take each command line argument and assume it is a URI segment.
 	 *
-	 * @access	private
 	 * @return	string
 	 */
 	protected function _parse_cli_args()
 	{
 		$args = array_slice($_SERVER['argv'], 1);
-
 		return $args ? '/' . implode('/', $args) : '';
 	}
 
@@ -271,27 +260,28 @@
 	/**
 	 * Filter segments for malicious characters
 	 *
-	 * @access	private
+	 * Called by CI_Router
+	 *
 	 * @param	string
 	 * @return	string
 	 */
-	function _filter_uri($str)
+	public function _filter_uri($str)
 	{
 		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
-			if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str))
+			if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', $str))
 			{
 				show_error('The URI you submitted has disallowed characters.', 400);
 			}
 		}
 
-		// Convert programatic characters to entities
-		$bad	= array('$',		'(',		')',		'%28',		'%29');
-		$good	= array('&#36;',	'&#40;',	'&#41;',	'&#40;',	'&#41;');
-
-		return str_replace($bad, $good, $str);
+		// Convert programatic characters to entities and return
+		return str_replace(
+					array('$',     '(',     ')',     '%28',   '%29'), // Bad
+					array('&#36;', '&#40;', '&#41;', '&#40;', '&#41;'), // Good
+					$str);
 	}
 
 	// --------------------------------------------------------------------
@@ -299,14 +289,15 @@
 	/**
 	 * Remove the suffix from the URL if needed
 	 *
-	 * @access	private
+	 * Called by CI_Router
+	 *
 	 * @return	void
 	 */
-	function _remove_url_suffix()
+	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);
+			$this->uri_string = preg_replace('|'.preg_quote($this->config->item('url_suffix')).'$|', '', $this->uri_string);
 		}
 	}
 
@@ -316,12 +307,13 @@
 	 * Explode the URI Segments. The individual segments will
 	 * be stored in the $this->segments array.
 	 *
-	 * @access	private
+	 * Called by CI_Router
+	 *
 	 * @return	void
 	 */
-	function _explode_segments()
+	public function _explode_segments()
 	{
-		foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
+		foreach (explode('/', preg_replace('|/*(.+?)/*$|', '\\1', $this->uri_string)) as $val)
 		{
 			// Filter segments for security
 			$val = trim($this->_filter_uri($val));
@@ -338,14 +330,15 @@
 	 * Re-index Segments
 	 *
 	 * This function re-indexes the $this->segment array so that it
-	 * starts at 1 rather than 0.  Doing so makes it simpler to
+	 * starts at 1 rather than 0. Doing so makes it simpler to
 	 * use functions like $this->uri->segment(n) since there is
 	 * a 1:1 relationship between the segment array and the actual segments.
 	 *
-	 * @access	private
+	 * Called by CI_Router
+	 *
 	 * @return	void
 	 */
-	function _reindex_segments()
+	public function _reindex_segments()
 	{
 		array_unshift($this->segments, NULL);
 		array_unshift($this->rsegments, NULL);
@@ -360,12 +353,11 @@
 	 *
 	 * This function returns the URI segment based on the number provided.
 	 *
-	 * @access	public
 	 * @param	integer
 	 * @param	bool
 	 * @return	string
 	 */
-	function segment($n, $no_result = FALSE)
+	public function segment($n, $no_result = FALSE)
 	{
 		return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
 	}
@@ -379,12 +371,11 @@
 	 * based on the number provided.  If there is no routing this function returns the
 	 * same result as $this->segment()
 	 *
-	 * @access	public
 	 * @param	integer
 	 * @param	bool
 	 * @return	string
 	 */
-	function rsegment($n, $no_result = FALSE)
+	public function rsegment($n, $no_result = FALSE)
 	{
 		return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
 	}
@@ -407,25 +398,22 @@
 	 *			gender => male
 	 *		 )
 	 *
-	 * @access	public
 	 * @param	integer	the starting segment number
 	 * @param	array	an array of default values
 	 * @return	array
 	 */
-	function uri_to_assoc($n = 3, $default = array())
+	public function uri_to_assoc($n = 3, $default = array())
 	{
 		return $this->_uri_to_assoc($n, $default, 'segment');
 	}
 	/**
 	 * Identical to above only it uses the re-routed segment array
 	 *
-	 * @access 	public
 	 * @param 	integer	the starting segment number
 	 * @param 	array	an array of default values
 	 * @return 	array
-	 *
 	 */
-	function ruri_to_assoc($n = 3, $default = array())
+	public function ruri_to_assoc($n = 3, $default = array())
 	{
 		return $this->_uri_to_assoc($n, $default, 'rsegment');
 	}
@@ -435,25 +423,13 @@
 	/**
 	 * Generate a key value pair from the URI string or Re-routed URI string
 	 *
-	 * @access	private
 	 * @param	integer	the starting segment number
 	 * @param	array	an array of default values
 	 * @param	string	which array we should use
 	 * @return	array
 	 */
-	function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
+	protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
 	{
-		if ($which == 'segment')
-		{
-			$total_segments = 'total_segments';
-			$segment_array = 'segment_array';
-		}
-		else
-		{
-			$total_segments = 'total_rsegments';
-			$segment_array = 'rsegment_array';
-		}
-
 		if ( ! is_numeric($n))
 		{
 			return $default;
@@ -464,23 +440,30 @@
 			return $this->keyval[$n];
 		}
 
+		if ($which === 'segment')
+		{
+			$total_segments = 'total_segments';
+			$segment_array = 'segment_array';
+		}
+		else
+		{
+			$total_segments = 'total_rsegments';
+			$segment_array = 'rsegment_array';
+		}
+
 		if ($this->$total_segments() < $n)
 		{
-			if (count($default) == 0)
+			if (count($default) === 0)
 			{
 				return array();
 			}
 
-			$retval = array();
-			foreach ($default as $val)
-			{
-				$retval[$val] = FALSE;
-			}
-			return $retval;
+			return function_exists('array_fill_keys')
+				? array_fill_keys($default, FALSE)
+				: array_combine($default, array_fill(0, count($default), FALSE));
 		}
 
 		$segments = array_slice($this->$segment_array(), ($n - 1));
-
 		$i = 0;
 		$lastval = '';
 		$retval  = array();
@@ -521,11 +504,10 @@
 	 * Generate a URI string from an associative array
 	 *
 	 *
-	 * @access	public
 	 * @param	array	an associative array of key/values
 	 * @return	array
 	 */
-	function assoc_to_uri($array)
+	public function assoc_to_uri($array)
 	{
 		$temp = array();
 		foreach ((array)$array as $key => $val)
@@ -542,12 +524,11 @@
 	/**
 	 * Fetch a URI Segment and add a trailing slash
 	 *
-	 * @access	public
 	 * @param	integer
 	 * @param	string
 	 * @return	string
 	 */
-	function slash_segment($n, $where = 'trailing')
+	public function slash_segment($n, $where = 'trailing')
 	{
 		return $this->_slash_segment($n, $where, 'segment');
 	}
@@ -557,12 +538,11 @@
 	/**
 	 * Fetch a URI Segment and add a trailing slash
 	 *
-	 * @access	public
 	 * @param	integer
 	 * @param	string
 	 * @return	string
 	 */
-	function slash_rsegment($n, $where = 'trailing')
+	public function slash_rsegment($n, $where = 'trailing')
 	{
 		return $this->_slash_segment($n, $where, 'rsegment');
 	}
@@ -572,22 +552,20 @@
 	/**
 	 * Fetch a URI Segment and add a trailing slash - helper function
 	 *
-	 * @access	private
 	 * @param	integer
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	function _slash_segment($n, $where = 'trailing', $which = 'segment')
+	protected function _slash_segment($n, $where = 'trailing', $which = 'segment')
 	{
-		$leading	= '/';
-		$trailing	= '/';
+		$leading = $trailing = '/';
 
-		if ($where == 'trailing')
+		if ($where === 'trailing')
 		{
 			$leading	= '';
 		}
-		elseif ($where == 'leading')
+		elseif ($where === 'leading')
 		{
 			$trailing	= '';
 		}
@@ -600,10 +578,9 @@
 	/**
 	 * Segment Array
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function segment_array()
+	public function segment_array()
 	{
 		return $this->segments;
 	}
@@ -613,10 +590,9 @@
 	/**
 	 * Routed Segment Array
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function rsegment_array()
+	public function rsegment_array()
 	{
 		return $this->rsegments;
 	}
@@ -626,10 +602,9 @@
 	/**
 	 * Total number of segments
 	 *
-	 * @access	public
 	 * @return	integer
 	 */
-	function total_segments()
+	public function total_segments()
 	{
 		return count($this->segments);
 	}
@@ -639,10 +614,9 @@
 	/**
 	 * Total number of routed segments
 	 *
-	 * @access	public
 	 * @return	integer
 	 */
-	function total_rsegments()
+	public function total_rsegments()
 	{
 		return count($this->rsegments);
 	}
@@ -652,10 +626,9 @@
 	/**
 	 * Fetch the entire URI string
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function uri_string()
+	public function uri_string()
 	{
 		return $this->uri_string;
 	}
@@ -666,16 +639,14 @@
 	/**
 	 * Fetch the entire Re-routed URI string
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function ruri_string()
+	public function ruri_string()
 	{
 		return '/'.implode('/', $this->rsegment_array());
 	}
 
 }
-// END URI Class
 
 /* End of file URI.php */
-/* Location: ./system/core/URI.php */
\ No newline at end of file
+/* Location: ./system/core/URI.php */
diff --git a/system/core/Utf8.php b/system/core/Utf8.php
index 7abe4e4..0e180d3 100644
--- a/system/core/Utf8.php
+++ b/system/core/Utf8.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -44,24 +44,22 @@
 	 * Constructor
 	 *
 	 * Determines if UTF-8 support is to be enabled
-	 *
 	 */
-	function __construct()
+	public function __construct()
 	{
-		log_message('debug', "Utf8 Class Initialized");
+		log_message('debug', 'Utf8 Class Initialized');
 
 		global $CFG;
 
 		if (
-			preg_match('/./u', 'é') === 1					// PCRE must support UTF-8
-			AND function_exists('iconv')					// iconv must be installed
-			AND ini_get('mbstring.func_overload') != 1		// Multibyte string function overloading cannot be enabled
-			AND $CFG->item('charset') == 'UTF-8'			// Application charset must be UTF-8
+			@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
+			&& $CFG->item('charset') === 'UTF-8'		// Application charset must be UTF-8
 			)
 		{
-			log_message('debug', "UTF-8 Support Enabled");
-
 			define('UTF8_ENABLED', TRUE);
+			log_message('debug', 'UTF-8 Support Enabled');
 
 			// set internal encoding for multibyte string functions if necessary
 			// and set a flag so we don't have to repeatedly use extension_loaded()
@@ -78,8 +76,8 @@
 		}
 		else
 		{
-			log_message('debug', "UTF-8 Support Disabled");
 			define('UTF8_ENABLED', FALSE);
+			log_message('debug', 'UTF-8 Support Disabled');
 		}
 	}
 
@@ -90,11 +88,10 @@
 	 *
 	 * Ensures strings are UTF-8
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function clean_string($str)
+	public function clean_string($str)
 	{
 		if ($this->_is_ascii($str) === FALSE)
 		{
@@ -113,11 +110,10 @@
 	 * line feeds, and carriage returns, as all others can cause
 	 * problems in XML
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function safe_ascii_for_xml($str)
+	public function safe_ascii_for_xml($str)
 	{
 		return remove_invisible_characters($str, FALSE);
 	}
@@ -129,27 +125,22 @@
 	 *
 	 * Attempts to convert a string to UTF-8
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string	- input encoding
 	 * @return	string
 	 */
-	function convert_to_utf8($str, $encoding)
+	public function convert_to_utf8($str, $encoding)
 	{
 		if (function_exists('iconv'))
 		{
-			$str = @iconv($encoding, 'UTF-8', $str);
+			return @iconv($encoding, 'UTF-8', $str);
 		}
 		elseif (function_exists('mb_convert_encoding'))
 		{
-			$str = @mb_convert_encoding($str, 'UTF-8', $encoding);
-		}
-		else
-		{
-			return FALSE;
+			return @mb_convert_encoding($str, 'UTF-8', $encoding);
 		}
 
-		return $str;
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -159,19 +150,15 @@
 	 *
 	 * Tests if a string is standard 7-bit ASCII or not
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
-	function _is_ascii($str)
+	protected function _is_ascii($str)
 	{
-		return (preg_match('/[^\x00-\x7F]/S', $str) == 0);
+		return (preg_match('/[^\x00-\x7F]/S', $str) === 0);
 	}
 
-	// --------------------------------------------------------------------
-
 }
-// End Utf8 Class
 
 /* End of file Utf8.php */
-/* Location: ./system/core/Utf8.php */
\ No newline at end of file
+/* Location: ./system/core/Utf8.php */
diff --git a/system/database/DB.php b/system/database/DB.php
index 5c90f44..d06ffb4 100755
--- a/system/database/DB.php
+++ b/system/database/DB.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Initialize the database
  *
@@ -42,17 +40,15 @@
 	if (is_string($params) AND strpos($params, '://') === FALSE)
 	{
 		// Is the config file in the environment folder?
-		if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php'))
+		if (( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php'))
+			AND ! file_exists($file_path = APPPATH.'config/database.php'))
 		{
-			if ( ! file_exists($file_path = APPPATH.'config/database.php'))
-			{
-				show_error('The configuration file database.php does not exist.');
-			}
+			show_error('The configuration file database.php does not exist.');
 		}
 
 		include($file_path);
 
-		if ( ! isset($db) OR count($db) == 0)
+		if ( ! isset($db) OR count($db) === 0)
 		{
 			show_error('No database connection settings were found in the database config file.');
 		}
@@ -78,33 +74,32 @@
 		 *  parameter. DSNs must have this prototype:
 		 *  $dsn = 'driver://username:password@hostname/database';
 		 */
-
 		if (($dns = @parse_url($params)) === FALSE)
 		{
 			show_error('Invalid DB Connection String');
 		}
 
 		$params = array(
-							'dbdriver'	=> $dns['scheme'],
-							'hostname'	=> (isset($dns['host'])) ? rawurldecode($dns['host']) : '',
-							'username'	=> (isset($dns['user'])) ? rawurldecode($dns['user']) : '',
-							'password'	=> (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '',
-							'database'	=> (isset($dns['path'])) ? rawurldecode(substr($dns['path'], 1)) : ''
-						);
+				'dbdriver'	=> $dns['scheme'],
+				'hostname'	=> (isset($dns['host'])) ? rawurldecode($dns['host']) : '',
+				'port'		=> (isset($dns['port'])) ? rawurldecode($dns['port']) : '',
+				'username'	=> (isset($dns['user'])) ? rawurldecode($dns['user']) : '',
+				'password'	=> (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '',
+				'database'	=> (isset($dns['path'])) ? rawurldecode(substr($dns['path'], 1)) : ''
+			);
 
 		// were additional config items set?
 		if (isset($dns['query']))
 		{
 			parse_str($dns['query'], $extra);
-
 			foreach ($extra as $key => $val)
 			{
 				// booleans please
-				if (strtoupper($val) == "TRUE")
+				if (strtoupper($val) === 'TRUE')
 				{
 					$val = TRUE;
 				}
-				elseif (strtoupper($val) == "FALSE")
+				elseif (strtoupper($val) === 'FALSE')
 				{
 					$val = FALSE;
 				}
@@ -114,17 +109,15 @@
 		}
 	}
 
-	// No DB specified yet?  Beat them senseless...
+	// No DB specified yet? Beat them senseless...
 	if ( ! isset($params['dbdriver']) OR $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 active record 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.
-	// Kudos to Paul for discovering this clever use of eval()
-
 	if ($active_record_override !== NULL)
 	{
 		$active_record = $active_record_override;
@@ -135,18 +128,14 @@
 	if ( ! isset($active_record) OR $active_record == TRUE)
 	{
 		require_once(BASEPATH.'database/DB_active_rec.php');
-
 		if ( ! class_exists('CI_DB'))
 		{
-			eval('class CI_DB extends CI_DB_active_record { }');
+			class CI_DB extends CI_DB_active_record { }
 		}
 	}
-	else
+	elseif ( ! class_exists('CI_DB'))
 	{
-		if ( ! class_exists('CI_DB'))
-		{
-			eval('class CI_DB extends CI_DB_driver { }');
-		}
+		class CI_DB extends CI_DB_driver { }
 	}
 
 	require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php');
@@ -168,7 +157,5 @@
 	return $DB;
 }
 
-
-
 /* End of file DB.php */
-/* Location: ./system/database/DB.php */
\ No newline at end of file
+/* Location: ./system/database/DB.php */
diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php
index 1f77e41..575f097 100644
--- a/system/database/DB_active_rec.php
+++ b/system/database/DB_active_rec.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -40,44 +40,44 @@
  */
 class CI_DB_active_record extends CI_DB_driver {
 
-	protected $return_delete_sql	= FALSE;
-	protected $reset_delete_data	= FALSE;
-	
+	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_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_keys			= array();
+	protected $ar_limit			= FALSE;
 	protected $ar_offset			= FALSE;
-	protected $ar_order				= FALSE;
+	protected $ar_order			= FALSE;
 	protected $ar_orderby			= array();
-	protected $ar_set				= array();
+	protected $ar_set			= array();
 	protected $ar_wherein			= array();
-	protected $ar_aliased_tables	= array();
+	protected $ar_aliased_tables		= array();
 	protected $ar_store_array		= array();
+	protected $ar_where_group_started	= FALSE;
+	protected $ar_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();
-	
-	protected $ar_no_escape 		= array();
-	protected $ar_cache_no_escape	= array();
+	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();
 
-	// --------------------------------------------------------------------
+	protected $ar_no_escape 			= array();
+	protected $ar_cache_no_escape			= array();
 
 	/**
 	 * Select
@@ -111,6 +111,7 @@
 				}
 			}
 		}
+
 		return $this;
 	}
 
@@ -186,7 +187,7 @@
 	 *	select_max()
 	 *	select_min()
 	 *	select_avg()
-	 *  select_sum()
+	 *	select_sum()
 	 *
 	 * @param	string	the field
 	 * @param	string	an alias
@@ -212,7 +213,6 @@
 		}
 
 		$sql = $this->_protect_identifiers($type.'('.trim($select).')').' AS '.$this->_protect_identifiers(trim($alias));
-
 		$this->ar_select[] = $sql;
 		$this->ar_no_escape[] = NULL;
 
@@ -237,7 +237,8 @@
 	{
 		if (strpos($item, '.') !== FALSE)
 		{
-			return end(explode('.', $item));
+			$item = explode('.', $item);
+			return end($item);
 		}
 
 		return $item;
@@ -279,30 +280,27 @@
 				{
 					$v = trim($v);
 					$this->_track_aliases($v);
-
-					$this->ar_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
+					$v = $this->ar_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
 
 					if ($this->ar_caching === TRUE)
 					{
-						$this->ar_cache_from[] = $this->_protect_identifiers($v, TRUE, NULL, FALSE);
+						$this->ar_cache_from[] = $v;
 						$this->ar_cache_exists[] = 'from';
 					}
 				}
-
 			}
 			else
 			{
 				$val = trim($val);
 
-				// Extract any aliases that might exist.  We use this information
+				// Extract any aliases that might exist. We use this information
 				// in the _protect_identifiers to know whether to add a table prefix
 				$this->_track_aliases($val);
-
-				$this->ar_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
+				$this->ar_from[] = $val = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
 
 				if ($this->ar_caching === TRUE)
 				{
-					$this->ar_cache_from[] = $this->_protect_identifiers($val, TRUE, NULL, FALSE);
+					$this->ar_cache_from[] = $val;
 					$this->ar_cache_exists[] = 'from';
 				}
 			}
@@ -339,23 +337,19 @@
 			}
 		}
 
-		// Extract any aliases that might exist.  We use this information
+		// Extract any aliases that might exist. We use this information
 		// in the _protect_identifiers to know whether to add a table prefix
 		$this->_track_aliases($table);
 
 		// Strip apart the condition and protect the identifiers
 		if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match))
 		{
-			$match[1] = $this->_protect_identifiers($match[1]);
-			$match[3] = $this->_protect_identifiers($match[3]);
-
-			$cond = $match[1].$match[2].$match[3];
+			$cond = $this->_protect_identifiers($match[1]).$match[2].$this->_protect_identifiers($match[3]);
 		}
 
 		// Assemble the JOIN statement
-		$join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;
+		$this->ar_join[] = $join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond;
 
-		$this->ar_join[] = $join;
 		if ($this->ar_caching === TRUE)
 		{
 			$this->ar_cache_join[] = $join;
@@ -413,6 +407,8 @@
 	 */
 	protected function _where($key, $value = NULL, $type = 'AND ', $escape = NULL)
 	{
+		$type = $this->_group_get_type($type);
+
 		if ( ! is_array($key))
 		{
 			$key = array($key => $value);
@@ -426,7 +422,7 @@
 
 		foreach ($key as $k => $v)
 		{
-			$prefix = (count($this->ar_where) == 0 AND count($this->ar_cache_where) == 0) ? '' : $type;
+			$prefix = (count($this->ar_where) === 0 AND count($this->ar_cache_where) === 0) ? '' : $type;
 
 			if (is_null($v) && ! $this->_has_operator($k))
 			{
@@ -439,10 +435,9 @@
 				if ($escape === TRUE)
 				{
 					$k = $this->_protect_identifiers($k, FALSE, $escape);
-
 					$v = ' '.$this->escape($v);
 				}
-				
+
 				if ( ! $this->_has_operator($k))
 				{
 					$k .= ' = ';
@@ -454,7 +449,6 @@
 			}
 
 			$this->ar_where[] = $prefix.$k.$v;
-
 			if ($this->ar_caching === TRUE)
 			{
 				$this->ar_cache_where[] = $prefix.$k.$v;
@@ -554,6 +548,8 @@
 			return;
 		}
 
+		$type = $this->_group_get_type($type);
+
 		if ( ! is_array($values))
 		{
 			$values = array($values);
@@ -566,11 +562,9 @@
 			$this->ar_wherein[] = $this->escape($value);
 		}
 
-		$prefix = (count($this->ar_where) == 0) ? '' : $type;
+		$prefix = (count($this->ar_where) === 0) ? '' : $type;
+		$this->ar_where[] = $where_in = $prefix.$this->_protect_identifiers($key).$not.' IN ('.implode(', ', $this->ar_wherein).') ';
 
-		$where_in = $prefix . $this->_protect_identifiers($key) . $not . " IN (" . implode(", ", $this->ar_wherein) . ") ";
-
-		$this->ar_where[] = $where_in;
 		if ($this->ar_caching === TRUE)
 		{
 			$this->ar_cache_where[] = $where_in;
@@ -664,6 +658,8 @@
 	 */
 	protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '')
 	{
+		$type = $this->_group_get_type($type);
+
 		if ( ! is_array($field))
 		{
 			$field = array($field => $match);
@@ -672,20 +668,18 @@
 		foreach ($field as $k => $v)
 		{
 			$k = $this->_protect_identifiers($k);
-
-			$prefix = (count($this->ar_like) == 0) ? '' : $type;
-
+			$prefix = (count($this->ar_like) === 0) ? '' : $type;
 			$v = $this->escape_like_str($v);
 
-			if ($side == 'none')
+			if ($side === 'none')
 			{
 				$like_statement = $prefix." $k $not LIKE '{$v}'";
 			}
-			elseif ($side == 'before')
+			elseif ($side === 'before')
 			{
 				$like_statement = $prefix." $k $not LIKE '%{$v}'";
 			}
-			elseif ($side == 'after')
+			elseif ($side === 'after')
 			{
 				$like_statement = $prefix." $k $not LIKE '{$v}%'";
 			}
@@ -708,12 +702,114 @@
 			}
 
 		}
+
 		return $this;
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
+	 * Starts a query group.
+	 *
+	 * @param	string (Internal use only)
+	 * @param	string (Internal use only)
+	 * @return	object
+	 */
+	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 AND 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->ar_cache_where[] = $value;
+		}
+
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Starts a query group, but ORs the group
+	 *
+	 * @return	object
+	 */
+	public function or_group_start()
+	{
+		return $this->group_start('', 'OR ');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Starts a query group, but NOTs the group
+	 *
+	 * @return	object
+	 */
+	public function not_group_start()
+	{
+		return $this->group_start('NOT ', 'AND ');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Starts a query group, but OR NOTs the group
+	 *
+	 * @return	object
+	 */
+	public function or_not_group_start()
+	{
+		return $this->group_start('NOT ', 'OR ');
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Ends a query group
+	 *
+	 * @return	object
+	 */
+	public function group_end()
+	{
+		$this->ar_where_group_started = FALSE;
+		$this->ar_where[] = $value = str_repeat(' ', $this->ar_where_group_count--) . ')';
+
+		if ($this->ar_caching)
+		{
+			$this->ar_cache_where[] = $value;
+		}
+
+		return $this;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Group_get_type
+	 *
+	 * Called by group_start(), _like(), _where() and _where_in()
+	 *
+	 * @param	string
+	 * @return	string
+	 */
+	protected function _group_get_type($type)
+	{
+		if ($this->ar_where_group_started)
+		{
+			$type = '';
+			$this->ar_where_group_started = FALSE;
+		}
+
+		return $type;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * GROUP BY
 	 *
 	 * @param	string
@@ -732,15 +828,16 @@
 
 			if ($val != '')
 			{
-				$this->ar_groupby[] = $this->_protect_identifiers($val);
+				$this->ar_groupby[] = $val = $this->_protect_identifiers($val);
 
 				if ($this->ar_caching === TRUE)
 				{
-					$this->ar_cache_groupby[] = $this->_protect_identifiers($val);
+					$this->ar_cache_groupby[] = $val;
 					$this->ar_cache_exists[] = 'groupby';
 				}
 			}
 		}
+
 		return $this;
 	}
 
@@ -796,7 +893,7 @@
 
 		foreach ($key as $k => $v)
 		{
-			$prefix = (count($this->ar_having) == 0) ? '' : $type;
+			$prefix = (count($this->ar_having) === 0) ? '' : $type;
 
 			if ($escape === TRUE)
 			{
@@ -836,7 +933,7 @@
 	 */
 	public function order_by($orderby, $direction = '', $escape = TRUE)
 	{
-		if (strtolower($direction) == 'random')
+		if (strtolower($direction) === 'random')
 		{
 			$orderby = ''; // Random results want or don't need a field name
 			$direction = $this->_random_keyword;
@@ -847,7 +944,7 @@
 		}
 
 
-		if ((strpos($orderby, ',') !== FALSE) && ($escape === TRUE))
+		if ((strpos($orderby, ',') !== FALSE) && $escape === TRUE)
 		{
 			$temp = array();
 			foreach (explode(',', $orderby) as $part)
@@ -863,7 +960,7 @@
 
 			$orderby = implode(', ', $temp);
 		}
-		else if ($direction != $this->_random_keyword)
+		elseif ($direction != $this->_random_keyword)
 		{
 			if ($escape === TRUE)
 			{
@@ -871,9 +968,8 @@
 			}
 		}
 
-		$orderby_statement = $orderby.$direction;
+		$this->ar_orderby[] = $orderby_statement = $orderby.$direction;
 
-		$this->ar_orderby[] = $orderby_statement;
 		if ($this->ar_caching === TRUE)
 		{
 			$this->ar_cache_orderby[] = $orderby_statement;
@@ -951,7 +1047,7 @@
 
 		return $this;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -964,24 +1060,24 @@
 	 * @param	boolean	TRUE: resets AR values; FALSE: leave AR vaules alone
 	 * @return	string
 	 */
-	public function get_compiled_select($table = '', $reset = TRUE) 
+	public function get_compiled_select($table = '', $reset = TRUE)
 	{
 		if ($table != '')
 		{
 			$this->_track_aliases($table);
 			$this->from($table);
 		}
-		
+
 		$select =  $this->_compile_select();
-		
+
 		if ($reset === TRUE)
 		{
 			$this->_reset_select();
 		}
-		
+
 		return $select;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1008,9 +1104,7 @@
 			$this->limit($limit, $offset);
 		}
 
-		$sql = $this->_compile_select();
-
-		$result = $this->query($sql);
+		$result = $this->query($this->_compile_select());
 		$this->_reset_select();
 		return $result;
 	}
@@ -1032,20 +1126,17 @@
 			$this->from($table);
 		}
 
-		$sql = $this->_compile_select($this->_count_string . $this->_protect_identifiers('numrows'));
-
-		$query = $this->query($sql);
+		$result = $this->query($this->_compile_select($this->_count_string.$this->_protect_identifiers('numrows')));
 		$this->_reset_select();
 
-		if ($query->num_rows() == 0)
+		if ($result->num_rows() === 0)
 		{
 			return 0;
 		}
 
-		$row = $query->row();
+		$row = $result->row();
 		return (int) $row->numrows;
 	}
-
 	// --------------------------------------------------------------------
 
 	/**
@@ -1075,9 +1166,7 @@
 			$this->limit($limit, $offset);
 		}
 
-		$sql = $this->_compile_select();
-
-		$result = $this->query($sql);
+		$result = $this->query($this->_compile_select());
 		$this->_reset_select();
 		return $result;
 	}
@@ -1100,11 +1189,11 @@
 			$this->set_insert_batch($set);
 		}
 
-		if (count($this->ar_set) == 0)
+		if (count($this->ar_set) === 0)
 		{
 			if ($this->db_debug)
 			{
-				//No valid data array.  Folds in cases where keys and values did not match up
+				// No valid data array. Folds in cases where keys and values did not match up
 				return $this->display_error('db_must_use_set');
 			}
 			return FALSE;
@@ -1114,30 +1203,19 @@
 		{
 			if ( ! isset($this->ar_from[0]))
 			{
-				if ($this->db_debug)
-				{
-					return $this->display_error('db_must_set_table');
-				}
-				return FALSE;
+				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
 			$table = $this->ar_from[0];
 		}
 
 		// Batch this baby
-		for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
+		for ($i = 0, $total = count($this->ar_set); $i < $total; $i += 100)
 		{
-
-			$sql = $this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100));
-
-			//echo $sql;
-
-			$this->query($sql);
+			$this->query($this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100)));
 		}
 
 		$this->_reset_write();
-
-
 		return TRUE;
 	}
 
@@ -1181,7 +1259,6 @@
 			else
 			{
 				$clean = array();
-
 				foreach ($row as $value)
 				{
 					$clean[] = $this->escape($value);
@@ -1198,7 +1275,7 @@
 
 		return $this;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1212,25 +1289,25 @@
 	 * @return	string
 	 */
 	public function get_compiled_insert($table = '', $reset = TRUE)
-	{	
+	{
 		if ($this->_validate_insert($table) === FALSE)
 		{
 			return FALSE;
 		}
-		
+
 		$sql = $this->_insert(
 			$this->_protect_identifiers(
 				$this->ar_from[0], TRUE, NULL, FALSE
 			),
-			array_keys($this->ar_set), 
+			array_keys($this->ar_set),
 			array_values($this->ar_set)
 		);
-		
+
 		if ($reset === TRUE)
 		{
 			$this->_reset_write();
 		}
-		
+
 		return $sql;
 	}
 
@@ -1252,24 +1329,24 @@
 		{
 			$this->set($set);
 		}
-		
+
 		if ($this->_validate_insert($table) === FALSE)
 		{
 			return FALSE;
 		}
-		
+
 		$sql = $this->_insert(
 			$this->_protect_identifiers(
 				$this->ar_from[0], TRUE, NULL, FALSE
-			), 
-			array_keys($this->ar_set), 
+			),
+			array_keys($this->ar_set),
 			array_values($this->ar_set)
 		);
 
 		$this->_reset_write();
 		return $this->query($sql);
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1283,33 +1360,25 @@
 	 * @param	string	the table to insert data into
 	 * @return	string
 	 */
-	protected function _validate_insert($table = '') 
+	protected function _validate_insert($table = '')
 	{
-		if (count($this->ar_set) == 0)
+		if (count($this->ar_set) === 0)
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_must_use_set');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
 		}
 
 		if ($table == '')
 		{
 			if ( ! isset($this->ar_from[0]))
 			{
-				if ($this->db_debug)
-				{
-					return $this->display_error('db_must_set_table');
-				}
-				return FALSE;
+				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 		}
 		else
 		{
 			$this->ar_from[0] = $table;
 		}
-		
+
 		return TRUE;
 	}
 
@@ -1331,35 +1400,26 @@
 			$this->set($set);
 		}
 
-		if (count($this->ar_set) == 0)
+		if (count($this->ar_set) === 0)
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_must_use_set');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
 		}
 
 		if ($table == '')
 		{
 			if ( ! isset($this->ar_from[0]))
 			{
-				if ($this->db_debug)
-				{
-					return $this->display_error('db_must_set_table');
-				}
-				return FALSE;
+				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
 			$table = $this->ar_from[0];
 		}
 
 		$sql = $this->_replace($this->_protect_identifiers($table, TRUE, NULL, FALSE), array_keys($this->ar_set), array_values($this->ar_set));
-
 		$this->_reset_write();
 		return $this->query($sql);
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1376,22 +1436,22 @@
 	{
 		// Combine any cached components with the current statements
 		$this->_merge_cache();
-	
+
 		if ($this->_validate_update($table) === FALSE)
 		{
 			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);
-		
+
 		if ($reset === TRUE)
 		{
 			$this->_reset_write();
 		}
-		
+
 		return $sql;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1430,11 +1490,10 @@
 		}
 
 		$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);
-
 		$this->_reset_write();
 		return $this->query($sql);
 	}
-		
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1446,36 +1505,30 @@
 	 *
 	 * @access	public
 	 * @param	string	the table to update data on
-	 * @return	string
+	 * @return	bool
 	 */
 	protected function _validate_update($table = '')
 	{
 		if (count($this->ar_set) == 0)
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_must_use_set');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
 		}
 
 		if ($table == '')
 		{
 			if ( ! isset($this->ar_from[0]))
 			{
-				if ($this->db_debug)
-				{
-					return $this->display_error('db_must_set_table');
-				}
-				return FALSE;
+				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 		}
 		else
 		{
 			$this->ar_from[0] = $table;
 		}
+
+		return TRUE;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1486,7 +1539,7 @@
 	 * @param	string	the table to retrieve the results from
 	 * @param	array	an associative array of update values
 	 * @param	string	the where key
-	 * @return	object
+	 * @return	bool
 	 */
 	public function update_batch($table = '', $set = NULL, $index = NULL)
 	{
@@ -1495,12 +1548,7 @@
 
 		if (is_null($index))
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_must_use_index');
-			}
-
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_must_use_index') : FALSE;
 		}
 
 		if ( ! is_null($set))
@@ -1508,39 +1556,29 @@
 			$this->set_update_batch($set, $index);
 		}
 
-		if (count($this->ar_set) == 0)
+		if (count($this->ar_set) === 0)
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_must_use_set');
-			}
-
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_must_use_set') : FALSE;
 		}
 
 		if ($table == '')
 		{
 			if ( ! isset($this->ar_from[0]))
 			{
-				if ($this->db_debug)
-				{
-					return $this->display_error('db_must_set_table');
-				}
-				return FALSE;
+				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
 			$table = $this->ar_from[0];
 		}
 
 		// Batch this baby
-		for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100)
+		for ($i = 0, $total = count($this->ar_set); $i < $total; $i += 100)
 		{
-			$sql = $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($sql);
+			$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->_reset_write();
+		return TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -1566,7 +1604,6 @@
 		{
 			$index_set = FALSE;
 			$clean = array();
-
 			foreach ($v as $k2 => $v2)
 			{
 				if ($k2 == $index)
@@ -1578,14 +1615,7 @@
 					$not[] = $k.'-'.$v;
 				}
 
-				if ($escape === FALSE)
-				{
-					$clean[$this->_protect_identifiers($k2)] = $v2;
-				}
-				else
-				{
-					$clean[$this->_protect_identifiers($k2)] = $this->escape($v2);
-				}
+				$clean[$this->_protect_identifiers($k2)] = ($escape === FALSE) ? $v2 : $this->escape($v2);
 			}
 
 			if ($index_set == FALSE)
@@ -1615,11 +1645,7 @@
 		{
 			if ( ! isset($this->ar_from[0]))
 			{
-				if ($this->db_debug)
-				{
-					return $this->display_error('db_must_set_table');
-				}
-				return FALSE;
+				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
 			$table = $this->ar_from[0];
@@ -1630,9 +1656,7 @@
 		}
 
 		$sql = $this->_delete($table);
-
 		$this->_reset_write();
-
 		return $this->query($sql);
 	}
 
@@ -1654,11 +1678,7 @@
 		{
 			if ( ! isset($this->ar_from[0]))
 			{
-				if ($this->db_debug)
-				{
-					return $this->display_error('db_must_set_table');
-				}
-				return FALSE;
+				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
 			$table = $this->ar_from[0];
@@ -1669,12 +1689,10 @@
 		}
 
 		$sql = $this->_truncate($table);
-
 		$this->_reset_write();
-
 		return $this->query($sql);
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1694,7 +1712,7 @@
 		$this->return_delete_sql = FALSE;
 		return $sql;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1717,11 +1735,7 @@
 		{
 			if ( ! isset($this->ar_from[0]))
 			{
-				if ($this->db_debug)
-				{
-					return $this->display_error('db_must_set_table');
-				}
-				return FALSE;
+				return ($this->db_debug) ? $this->display_error('db_must_set_table') : FALSE;
 			}
 
 			$table = $this->ar_from[0];
@@ -1751,31 +1765,20 @@
 			$this->limit($limit);
 		}
 
-		if (count($this->ar_where) == 0 && count($this->ar_wherein) == 0 && count($this->ar_like) == 0)
+		if (count($this->ar_where) === 0 && count($this->ar_wherein) === 0 && count($this->ar_like) === 0)
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_del_must_use_where');
-			}
-
-			return FALSE;
+			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);
-
 		if ($reset_data)
 		{
 			$this->_reset_write();
 		}
-		
-		if ($this->return_delete_sql === true)
-		{
-			return $sql;
-		}
 
-		return $this->query($sql);
+		return ($this->return_delete_sql === TRUE) ? $sql : $this->query($sql);
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1840,13 +1843,13 @@
 		}
 
 		// if a table alias is used we can recognize it by a space
-		if (strpos($table, " ") !== FALSE)
+		if (strpos($table, ' ') !== FALSE)
 		{
 			// if the alias is written with the AS keyword, remove it
 			$table = preg_replace('/ AS /i', ' ', $table);
 
 			// Grab the alias
-			$table = trim(strrchr($table, " "));
+			$table = trim(strrchr($table, ' '));
 
 			// Store the alias, if it doesn't already exist
 			if ( ! in_array($table, $this->ar_aliased_tables))
@@ -1855,7 +1858,7 @@
 			}
 		}
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1871,10 +1874,7 @@
 		// Combine any cached components with the current statements
 		$this->_merge_cache();
 
-		// ----------------------------------------------------------------
-
 		// Write the "select" portion of the query
-
 		if ($select_override !== FALSE)
 		{
 			$sql = $select_override;
@@ -1883,7 +1883,7 @@
 		{
 			$sql = ( ! $this->ar_distinct) ? 'SELECT ' : 'SELECT DISTINCT ';
 
-			if (count($this->ar_select) == 0)
+			if (count($this->ar_select) === 0)
 			{
 				$sql .= '*';
 			}
@@ -1902,32 +1902,19 @@
 			}
 		}
 
-		// ----------------------------------------------------------------
-
 		// Write the "FROM" portion of the query
-
 		if (count($this->ar_from) > 0)
 		{
-			$sql .= "\nFROM ";
-
-			$sql .= $this->_from_tables($this->ar_from);
+			$sql .= "\nFROM ".$this->_from_tables($this->ar_from);
 		}
 
-		// ----------------------------------------------------------------
-
 		// Write the "JOIN" portion of the query
-
 		if (count($this->ar_join) > 0)
 		{
-			$sql .= "\n";
-
-			$sql .= implode("\n", $this->ar_join);
+			$sql .= "\n".implode("\n", $this->ar_join);
 		}
 
-		// ----------------------------------------------------------------
-
 		// Write the "WHERE" portion of the query
-
 		if (count($this->ar_where) > 0 OR count($this->ar_like) > 0)
 		{
 			$sql .= "\nWHERE ";
@@ -1935,10 +1922,7 @@
 
 		$sql .= implode("\n", $this->ar_where);
 
-		// ----------------------------------------------------------------
-
 		// Write the "LIKE" portion of the query
-
 		if (count($this->ar_like) > 0)
 		{
 			if (count($this->ar_where) > 0)
@@ -1949,50 +1933,32 @@
 			$sql .= implode("\n", $this->ar_like);
 		}
 
-		// ----------------------------------------------------------------
-
 		// Write the "GROUP BY" portion of the query
-
 		if (count($this->ar_groupby) > 0)
 		{
-			$sql .= "\nGROUP BY ";
-
-			$sql .= implode(', ', $this->ar_groupby);
+			$sql .= "\nGROUP BY ".implode(', ', $this->ar_groupby);
 		}
 
-		// ----------------------------------------------------------------
-
 		// Write the "HAVING" portion of the query
-
 		if (count($this->ar_having) > 0)
 		{
-			$sql .= "\nHAVING ";
-			$sql .= implode("\n", $this->ar_having);
+			$sql .= "\nHAVING ".implode("\n", $this->ar_having);
 		}
 
-		// ----------------------------------------------------------------
-
 		// Write the "ORDER BY" portion of the query
-
 		if (count($this->ar_orderby) > 0)
 		{
-			$sql .= "\nORDER BY ";
-			$sql .= implode(', ', $this->ar_orderby);
-
+			$sql .= "\nORDER BY ".implode(', ', $this->ar_orderby);
 			if ($this->ar_order !== FALSE)
 			{
 				$sql .= ($this->ar_order == 'desc') ? ' DESC' : ' ASC';
 			}
 		}
 
-		// ----------------------------------------------------------------
-
 		// Write the "LIMIT" portion of the query
-
 		if (is_numeric($this->ar_limit))
 		{
-			$sql .= "\n";
-			$sql = $this->_limit($sql, $this->ar_limit, $this->ar_offset);
+			return $this->_limit($sql."\n", $this->ar_limit, $this->ar_offset);
 		}
 
 		return $sql;
@@ -2052,14 +2018,12 @@
 		foreach ($fields as $val)
 		{
 			// There are some built in keys we need to ignore for this conversion
-			if ($val != '_parent_name')
+			if ($val !== '_parent_name')
 			{
-
 				$i = 0;
 				foreach ($out[$val] as $data)
 				{
-					$array[$i][$val] = $data;
-					$i++;
+					$array[$i++][$val] = $data;
 				}
 			}
 		}
@@ -2134,7 +2098,7 @@
 	 */
 	protected function _merge_cache()
 	{
-		if (count($this->ar_cache_exists) == 0)
+		if (count($this->ar_cache_exists) === 0)
 		{
 			return;
 		}
@@ -2144,7 +2108,7 @@
 			$ar_variable	= 'ar_'.$val;
 			$ar_cache_var	= 'ar_cache_'.$val;
 
-			if (count($this->$ar_cache_var) == 0)
+			if (count($this->$ar_cache_var) === 0)
 			{
 				continue;
 			}
@@ -2161,15 +2125,14 @@
 
 		$this->ar_no_escape = $this->ar_cache_no_escape;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
 	 * Reset Active Record values.
-	 * 
+	 *
 	 * Publicly-visible method to reset the AR values.
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function reset_query()
@@ -2206,25 +2169,24 @@
 	 */
 	protected function _reset_select()
 	{
-		$ar_reset_items = 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,
-		);
-
-		$this->_reset_run($ar_reset_items);
+		$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
+					)
+				);
 	}
 
 	// --------------------------------------------------------------------
@@ -2238,20 +2200,20 @@
 	 */
 	protected function _reset_write()
 	{
-		$ar_reset_items = 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
-		);
-
-		$this->_reset_run($ar_reset_items);
+		$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
+					)
+				);
 	}
+
 }
 
 /* End of file DB_active_rec.php */
-/* Location: ./system/database/DB_active_rec.php */
\ No newline at end of file
+/* Location: ./system/database/DB_active_rec.php */
diff --git a/system/database/DB_cache.php b/system/database/DB_cache.php
index 6c1ffc0..79651fc 100644
--- a/system/database/DB_cache.php
+++ b/system/database/DB_cache.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Database Cache Class
  *
@@ -36,19 +34,12 @@
  */
 class CI_DB_Cache {
 
-	var $CI;
-	var $db;	// allows passing of db object so that multiple database connections and returned db objects can be supported
+	public $CI;
+	public $db;	// allows passing of db object so that multiple database connections and returned db objects can be supported
 
-	/**
-	 * Constructor
-	 *
-	 * Grabs the CI super object instance so we can access it.
-	 *
-	 */
-	function __construct(&$db)
+	public function __construct(&$db)
 	{
-		// Assign the main CI object to $this->CI
-		// and load the file helper since we use it a lot
+		// Assign the main CI object to $this->CI and load the file helper since we use it a lot
 		$this->CI =& get_instance();
 		$this->db =& $db;
 		$this->CI->load->helper('file');
@@ -59,11 +50,10 @@
 	/**
 	 * Set Cache Directory Path
 	 *
-	 * @access	public
 	 * @param	string	the path to the cache directory
 	 * @return	bool
 	 */
-	function check_path($path = '')
+	public function check_path($path = '')
 	{
 		if ($path == '')
 		{
@@ -76,7 +66,7 @@
 		}
 
 		// Add a trailing slash to the path if needed
-		$path = preg_replace("/(.+?)\/*$/", "\\1/",  $path);
+		$path = preg_replace('/(.+?)\/*$/', '\\1/',  $path);
 
 		if ( ! is_dir($path) OR ! is_really_writable($path))
 		{
@@ -96,10 +86,9 @@
 	 * The URI being requested will become the name of the cache sub-folder.
 	 * An MD5 hash of the SQL statement will become the cache file name
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function read($sql)
+	public function read($sql)
 	{
 		if ( ! $this->check_path())
 		{
@@ -107,9 +96,7 @@
 		}
 
 		$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
-
 		$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)))
@@ -125,10 +112,9 @@
 	/**
 	 * Write a query to a cache file
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function write($sql, $object)
+	public function write($sql, $object)
 	{
 		if ( ! $this->check_path())
 		{
@@ -136,11 +122,8 @@
 		}
 
 		$segment_one = ($this->CI->uri->segment(1) == FALSE) ? 'default' : $this->CI->uri->segment(1);
-
 		$segment_two = ($this->CI->uri->segment(2) == FALSE) ? 'index' : $this->CI->uri->segment(2);
-
 		$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
-
 		$filename = md5($sql);
 
 		if ( ! @is_dir($dir_path))
@@ -167,10 +150,9 @@
 	/**
 	 * Delete cache files within a particular directory
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function delete($segment_one = '', $segment_two = '')
+	public function delete($segment_one = '', $segment_two = '')
 	{
 		if ($segment_one == '')
 		{
@@ -183,7 +165,6 @@
 		}
 
 		$dir_path = $this->db->cachedir.$segment_one.'+'.$segment_two.'/';
-
 		delete_files($dir_path, TRUE);
 	}
 
@@ -192,16 +173,14 @@
 	/**
 	 * Delete all existing cache files
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function delete_all()
+	public function delete_all()
 	{
 		delete_files($this->db->cachedir, TRUE);
 	}
 
 }
 
-
 /* End of file DB_cache.php */
-/* Location: ./system/database/DB_cache.php */
\ No newline at end of file
+/* Location: ./system/database/DB_cache.php */
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index 9d92f2f..e403efb 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -81,8 +81,7 @@
 	var $stmt_id;
 	var $curs_id;
 	var $limit_used;
-
-
+	
 
 	/**
 	 * Constructor.  Accepts one parameter containing the database
@@ -108,11 +107,9 @@
 	/**
 	 * Initialize Database Settings
 	 *
-	 * @access	private Called by the constructor
-	 * @param	mixed
-	 * @return	void
+	 * @return	bool
 	 */
-	function initialize()
+	public function initialize()
 	{
 		// If an existing connection resource is available
 		// there is no need to connect and select the database
@@ -126,7 +123,7 @@
 		// Connect to the database and set the connection ID
 		$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
+		// No connection resource? Check if there is a failover else throw an error
 		if ( ! $this->conn_id)
 		{
 			// Check if there is a failover set
@@ -168,31 +165,19 @@
 		// ----------------------------------------------------------------
 
 		// Select the DB... assuming a database name is specified in the config file
-		if ($this->database != '')
+		if ($this->database !== '' && ! $this->db_select())
 		{
-			if ( ! $this->db_select())
-			{
-				log_message('error', 'Unable to select database: '.$this->database);
+			log_message('error', 'Unable to select database: '.$this->database);
 
-				if ($this->db_debug)
-				{
-					$this->display_error('db_unable_to_select', $this->database);
-				}
-				return FALSE;
-			}
-			else
+			if ($this->db_debug)
 			{
-				// We've selected the DB. Now we set the character set
-				if ( ! $this->db_set_charset($this->char_set, $this->dbcollat))
-				{
-					return FALSE;
-				}
-
-				return TRUE;
+				$this->display_error('db_unable_to_select', $this->database);
 			}
+			return FALSE;
 		}
 
-		return TRUE;
+		// Now we set the character set and that's all
+		return $this->db_set_charset($this->char_set, $this->dbcollat);
 	}
 
 	// --------------------------------------------------------------------
@@ -200,20 +185,19 @@
 	/**
 	 * Set client character set
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
-	 * @return	resource
+	 * @return	bool
 	 */
-	function db_set_charset($charset, $collation)
+	public function db_set_charset($charset, $collation = '')
 	{
-		if ( ! $this->_db_set_charset($this->char_set, $this->dbcollat))
+		if (method_exists($this, '_db_set_charset') && ! $this->_db_set_charset($charset, $collation))
 		{
-			log_message('error', 'Unable to set database connection charset: '.$this->char_set);
+			log_message('error', 'Unable to set database connection charset: '.$charset);
 
 			if ($this->db_debug)
 			{
-				$this->display_error('db_unable_to_set_charset', $this->char_set);
+				$this->display_error('db_unable_to_set_charset', $charset);
 			}
 
 			return FALSE;
@@ -238,36 +222,40 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Database Version Number.  Returns a string containing the
-	 * version of the database being used
+	 * Database version number
 	 *
-	 * @access	public
+	 * Returns a string containing the version of the database being used.
+	 * Most drivers will override this method.
+	 *
 	 * @return	string
 	 */
-	function version()
+	public function version()
 	{
+		if (isset($this->data_cache['version']))
+		{
+			return $this->data_cache['version'];
+		}
+
 		if (FALSE === ($sql = $this->_version()))
 		{
-			if ($this->db_debug)
-			{
-				return $this->display_error('db_unsupported_function');
-			}
-			return FALSE;
+			return ($this->db_debug) ? $this->display_error('db_unsupported_function') : FALSE;
 		}
 
-		// Some DBs have functions that return the version, and don't run special
-		// SQL queries per se. In these instances, just return the result.
-		$driver_version_exceptions = array('oci8', 'sqlite', 'cubrid', 'pdo');
+		$query = $this->query($sql);
+		$query = $query->row();
+		return $this->data_cache['version'] = $query->ver;
+	}
 
-		if (in_array($this->dbdriver, $driver_version_exceptions))
-		{
-			return $sql;
-		}
-		else
-		{
-			$query = $this->query($sql);
-			return $query->row('ver');
-		}
+	// --------------------------------------------------------------------
+
+	/**
+	 * Version number query string
+	 *
+	 * @return	string
+	 */
+	protected function _version()
+	{
+		return 'SELECT VERSION() AS ver';
 	}
 
 	// --------------------------------------------------------------------
@@ -305,6 +293,12 @@
 			$sql = preg_replace("/(\W)".$this->swap_pre."(\S+?)/", "\\1".$this->dbprefix."\\2", $sql);
 		}
 
+		// Compile binds if needed
+		if ($binds !== FALSE)
+		{
+			$sql = $this->compile_binds($sql, $binds);
+		}
+
 		// 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
@@ -320,12 +314,6 @@
 			}
 		}
 
-		// Compile binds if needed
-		if ($binds !== FALSE)
-		{
-			$sql = $this->compile_binds($sql, $binds);
-		}
-
 		// Save the  query for debugging
 		if ($this->save_queries == TRUE)
 		{
@@ -346,30 +334,28 @@
 			// This will trigger a rollback if transactions are being used
 			$this->_trans_status = FALSE;
 
-			// Grab the error number and message now, as we might run some
-			// additional queries before displaying the error
-			$error_no = $this->_error_number();
-			$error_msg = $this->_error_message();
+			// Grab the error now, as we might run some additional queries before displaying the error
+			$error = $this->error();
 
 			// Log errors
-			log_message('error', 'Query error: '.$error_msg);
+			log_message('error', 'Query error: '.$error['message']);
 
 			if ($this->db_debug)
 			{
 				// We call this function in order to roll-back queries
-				// if transactions are enabled.  If we don't call this here
+				// if transactions are enabled. If we don't call this here
 				// the error message will trigger an exit, causing the
 				// transactions to remain in limbo.
 				$this->trans_complete();
 
 				// Display errors
 				return $this->display_error(
-										array(
-												'Error Number: '.$error_no,
-												$error_msg,
-												$sql
-											)
-										);
+								array(
+									'Error Number: '.$error['code'],
+									$error['message'],
+									$sql
+								)
+							);
 			}
 
 			return FALSE;
@@ -660,17 +646,12 @@
 	/**
 	 * Determines if a query is a "write" type.
 	 *
-	 * @access	public
 	 * @param	string	An SQL query string
-	 * @return	boolean
+	 * @return	bool
 	 */
-	function is_write_type($sql)
+	public function is_write_type($sql)
 	{
-		if ( ! preg_match('/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD DATA|COPY|ALTER|GRANT|REVOKE|LOCK|UNLOCK)\s+/i', $sql))
-		{
-			return FALSE;
-		}
-		return TRUE;
+		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);
 	}
 
 	// --------------------------------------------------------------------
@@ -814,20 +795,23 @@
 
 		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)
 			{
-				if (isset($row['TABLE_NAME']))
-				{
-					$retval[] = $row['TABLE_NAME'];
-				}
-				else
-				{
-					$retval[] = array_shift($row);
-				}
+				$table = array_key_exists('TABLE_NAME', $row) ? 'TABLE_NAME' : 'table_name';
+			}
+
+			foreach ($rows as $row)
+			{
+				$retval[] = ( ! $table) ? current($row) : $row[$table];
 			}
 		}
 
 		$this->data_cache['table_names'] = $retval;
+		
 		return $this->data_cache['table_names'];
 	}
 
@@ -1436,10 +1420,23 @@
 
 		return $item.$alias;
 	}
+	
+	// --------------------------------------------------------------------
 
+	/**
+	 * Dummy method that allows Active Record class to be disabled
+	 *
+	 * This function is used extensively by every db driver.
+	 *
+	 * @access	private
+	 * @return	void
+	 */
+	protected function _reset_select()
+	{
+	
+	}
 
 }
 
-
 /* End of file DB_driver.php */
 /* Location: ./system/database/DB_driver.php */
diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php
index 78bf77a..336e949 100644
--- a/system/database/DB_forge.php
+++ b/system/database/DB_forge.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -36,23 +36,17 @@
  */
 class CI_DB_forge {
 
-	var $fields			= array();
-	var $keys			= array();
-	var $primary_keys	= array();
-	var $db_char_set	=	'';
+	public $fields		= array();
+	public $keys		= array();
+	public $primary_keys	= array();
+	public $db_char_set	=	'';
 
-	/**
-	 * Constructor
-	 *
-	 * Grabs the CI super object instance so we can access it.
-	 *
-	 */
-	function __construct()
+	public function __construct()
 	{
 		// Assign the main database object to $this->db
 		$CI =& get_instance();
 		$this->db =& $CI->db;
-		log_message('debug', "Database Forge Class Initialized");
+		log_message('debug', 'Database Forge Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -60,20 +54,13 @@
 	/**
 	 * Create database
 	 *
-	 * @access	public
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function create_database($db_name)
+	public function create_database($db_name)
 	{
 		$sql = $this->_create_database($db_name);
-
-		if (is_bool($sql))
-		{
-			return $sql;
-		}
-
-		return $this->db->query($sql);
+		return is_bool($sql) ? $sql : $this->db->query($sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -81,20 +68,13 @@
 	/**
 	 * Drop database
 	 *
-	 * @access	public
 	 * @param	string	the database name
 	 * @return	bool
 	 */
-	function drop_database($db_name)
+	public function drop_database($db_name)
 	{
 		$sql = $this->_drop_database($db_name);
-
-		if (is_bool($sql))
-		{
-			return $sql;
-		}
-
-		return $this->db->query($sql);
+		return is_bool($sql) ? $sql : $this->db->query($sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -102,12 +82,11 @@
 	/**
 	 * Add Key
 	 *
-	 * @access	public
 	 * @param	string	key
 	 * @param	string	type
-	 * @return	void
+	 * @return	object
 	 */
-	function add_key($key = '', $primary = FALSE)
+	public function add_key($key = '', $primary = FALSE)
 	{
 		if (is_array($key))
 		{
@@ -132,6 +111,8 @@
 		{
 			$this->keys[] = $key;
 		}
+
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -139,11 +120,10 @@
 	/**
 	 * Add Field
 	 *
-	 * @access	public
 	 * @param	string	collation
-	 * @return	void
+	 * @return	object
 	 */
-	function add_field($field = '')
+	public function add_field($field = '')
 	{
 		if ($field == '')
 		{
@@ -152,15 +132,15 @@
 
 		if (is_string($field))
 		{
-			if ($field == 'id')
+			if ($field === 'id')
 			{
 				$this->add_field(array(
-										'id' => array(
-													'type' => 'INT',
-													'constraint' => 9,
-													'auto_increment' => TRUE
-													)
-								));
+					'id' => array(
+						'type' => 'INT',
+						'constraint' => 9,
+						'auto_increment' => TRUE
+					)
+				));
 				$this->add_key('id', TRUE);
 			}
 			else
@@ -179,6 +159,7 @@
 			$this->fields = array_merge($this->fields, $field);
 		}
 
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -186,32 +167,24 @@
 	/**
 	 * Create Table
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	bool
 	 */
-	function create_table($table = '', $if_not_exists = FALSE)
+	public function create_table($table = '', $if_not_exists = FALSE)
 	{
 		if ($table == '')
 		{
 			show_error('A table name is required for that operation.');
 		}
 
-		if (count($this->fields) == 0)
+		if (count($this->fields) === 0)
 		{
 			show_error('Field information is required.');
 		}
 
 		$sql = $this->_create_table($this->db->dbprefix.$table, $this->fields, $this->primary_keys, $this->keys, $if_not_exists);
-
 		$this->_reset();
-
-		if (is_bool($sql))
-		{
-			return $sql;
-		}
-
-		return $this->db->query($sql);
+		return is_bool($sql) ? $sql : $this->db->query($sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -219,20 +192,13 @@
 	/**
 	 * Drop Table
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	bool
 	 */
-	function drop_table($table_name)
+	public function drop_table($table_name)
 	{
 		$sql = $this->_drop_table($this->db->dbprefix.$table_name);
-
-		if (is_bool($sql))
-		{
-			return $sql;
-		}
-
-		return $this->db->query($sql);
+		return is_bool($sql) ? $sql : $this->db->query($sql);
 	}
 
 	// --------------------------------------------------------------------
@@ -240,20 +206,18 @@
 	/**
 	 * Rename Table
 	 *
-	 * @access	public
 	 * @param	string	the old table name
 	 * @param	string	the new table name
 	 * @return	bool
 	 */
-	function rename_table($table_name, $new_table_name)
+	public function rename_table($table_name, $new_table_name)
 	{
 		if ($table_name == '' OR $new_table_name == '')
 		{
 			show_error('A table name is required for that operation.');
 		}
 
-		$sql = $this->_rename_table($this->db->dbprefix.$table_name, $this->db->dbprefix.$new_table_name);
-		return $this->db->query($sql);
+		return $this->db->query($this->_rename_table($this->db->dbprefix.$table_name, $this->db->dbprefix.$new_table_name));
 	}
 
 	// --------------------------------------------------------------------
@@ -261,13 +225,12 @@
 	/**
 	 * Column Add
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	string	the column name
 	 * @param	string	the column definition
 	 * @return	bool
 	 */
-	function add_column($table = '', $field = array(), $after_field = '')
+	public function add_column($table = '', $field = array(), $after_field = '')
 	{
 		if ($table == '')
 		{
@@ -276,8 +239,7 @@
 
 		// add field info into field array, but we can only do one at a time
 		// so we cycle through
-
-		foreach ($field as $k => $v)
+		foreach (array_keys($field) as $k)
 		{
 			$this->add_field(array($k => $field[$k]));
 
@@ -287,7 +249,6 @@
 			}
 
 			$sql = $this->_alter_table('ADD', $this->db->dbprefix.$table, $this->fields, $after_field);
-
 			$this->_reset();
 
 			if ($this->db->query($sql) === FALSE)
@@ -297,7 +258,6 @@
 		}
 
 		return TRUE;
-
 	}
 
 	// --------------------------------------------------------------------
@@ -305,14 +265,12 @@
 	/**
 	 * Column Drop
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	string	the column name
 	 * @return	bool
 	 */
-	function drop_column($table = '', $column_name = '')
+	public function drop_column($table = '', $column_name = '')
 	{
-
 		if ($table == '')
 		{
 			show_error('A table name is required for that operation.');
@@ -323,9 +281,7 @@
 			show_error('A column name is required for that operation.');
 		}
 
-		$sql = $this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name);
-
-		return $this->db->query($sql);
+		return $this->db->query($this->_alter_table('DROP', $this->db->dbprefix.$table, $column_name));
 	}
 
 	// --------------------------------------------------------------------
@@ -333,13 +289,12 @@
 	/**
 	 * Column Modify
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	string	the column name
 	 * @param	string	the column definition
 	 * @return	bool
 	 */
-	function modify_column($table = '', $field = array())
+	public function modify_column($table = '', $field = array())
 	{
 		if ($table == '')
 		{
@@ -348,8 +303,7 @@
 
 		// add field info into field array, but we can only do one at a time
 		// so we cycle through
-
-		foreach ($field as $k => $v)
+		foreach (array_keys($field) as $k)
 		{
 			// If no name provided, use the current name
 			if ( ! isset($field[$k]['name']))
@@ -358,14 +312,12 @@
 			}
 
 			$this->add_field(array($k => $field[$k]));
-
-			if (count($this->fields) == 0)
+			if (count($this->fields) === 0)
 			{
 				show_error('Field information is required.');
 			}
 
 			$sql = $this->_alter_table('CHANGE', $this->db->dbprefix.$table, $this->fields);
-
 			$this->_reset();
 
 			if ($this->db->query($sql) === FALSE)
@@ -384,17 +336,14 @@
 	 *
 	 * Resets table creation vars
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _reset()
+	protected function _reset()
 	{
-		$this->fields		= array();
-		$this->keys			= array();
-		$this->primary_keys	= array();
+		$this->fields = $this->keys = $this->primary_keys = array();
 	}
 
 }
 
 /* End of file DB_forge.php */
-/* Location: ./system/database/DB_forge.php */
\ No newline at end of file
+/* Location: ./system/database/DB_forge.php */
diff --git a/system/database/DB_result.php b/system/database/DB_result.php
index 9f0b018..7304432 100644
--- a/system/database/DB_result.php
+++ b/system/database/DB_result.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Database Result Class
  *
@@ -40,27 +38,25 @@
  */
 class CI_DB_result {
 
-	var $conn_id				= NULL;
-	var $result_id				= NULL;
-	var $result_array			= array();
-	var $result_object			= array();
-	var $custom_result_object	= array();
-	var $current_row			= 0;
-	var $num_rows				= 0;
-	var $row_data				= NULL;
-
+	public $conn_id				= NULL;
+	public $result_id			= NULL;
+	public $result_array			= array();
+	public $result_object			= array();
+	public $custom_result_object		= array();
+	public $current_row			= 0;
+	public $num_rows			= 0;
+	public $row_data			= NULL;
 
 	/**
 	 * Query result.  Acts as a wrapper function for the following functions.
 	 *
-	 * @access	public
 	 * @param	string	can be "object" or "array"
 	 * @return	mixed	either a result object or array
 	 */
 	public function result($type = 'object')
 	{
-		if ($type == 'array') return $this->result_array();
-		else if ($type == 'object') return $this->result_object();
+		if ($type === 'array') return $this->result_array();
+		elseif ($type === 'object') return $this->result_object();
 		else return $this->custom_result_object($type);
 	}
 
@@ -69,8 +65,8 @@
 	/**
 	 * Custom query result.
 	 *
-	 * @param class_name A string that represents the type of object you want back
-	 * @return array of objects
+	 * @param	string	A string that represents the type of object you want back
+	 * @return	array	of objects
 	 */
 	public function custom_result_object($class_name)
 	{
@@ -91,7 +87,6 @@
 		while ($row = $this->_fetch_object())
 		{
 			$object = new $class_name();
-
 			foreach ($row as $key => $value)
 			{
 				$object->$key = $value;
@@ -109,7 +104,6 @@
 	/**
 	 * Query result.  "object" version.
 	 *
-	 * @access	public
 	 * @return	object
 	 */
 	public function result_object()
@@ -141,7 +135,6 @@
 	/**
 	 * Query result.  "array" version.
 	 *
-	 * @access	public
 	 * @return	array
 	 */
 	public function result_array()
@@ -173,7 +166,6 @@
 	/**
 	 * Query result.  Acts as a wrapper function for the following functions.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string	can be "object" or "array"
 	 * @return	mixed	either a result object or array
@@ -197,8 +189,8 @@
 			$n = 0;
 		}
 
-		if ($type == 'object') return $this->row_object($n);
-		else if ($type == 'array') return $this->row_array($n);
+		if ($type === 'object') return $this->row_object($n);
+		elseif ($type === 'array') return $this->row_array($n);
 		else return $this->custom_row_object($n, $type);
 	}
 
@@ -207,8 +199,7 @@
 	/**
 	 * Assigns an item into a particular column slot
 	 *
-	 * @access	public
-	 * @return	object
+	 * @return	void
 	 */
 	public function set_row($key, $value = NULL)
 	{
@@ -224,7 +215,6 @@
 			{
 				$this->row_data[$k] = $v;
 			}
-
 			return;
 		}
 
@@ -239,14 +229,12 @@
 	/**
 	 * Returns a single result row - custom object version
 	 *
-	 * @access	public
 	 * @return	object
 	 */
 	public function custom_row_object($n, $type)
 	{
 		$result = $this->custom_result_object($type);
-
-		if (count($result) == 0)
+		if (count($result) === 0)
 		{
 			return $result;
 		}
@@ -262,14 +250,12 @@
 	/**
 	 * Returns a single result row - object version
 	 *
-	 * @access	public
 	 * @return	object
 	 */
 	public function row_object($n = 0)
 	{
 		$result = $this->result_object();
-
-		if (count($result) == 0)
+		if (count($result) === 0)
 		{
 			return $result;
 		}
@@ -287,14 +273,12 @@
 	/**
 	 * Returns a single result row - array version
 	 *
-	 * @access	public
 	 * @return	array
 	 */
 	public function row_array($n = 0)
 	{
 		$result = $this->result_array();
-
-		if (count($result) == 0)
+		if (count($result) === 0)
 		{
 			return $result;
 		}
@@ -313,18 +297,12 @@
 	/**
 	 * Returns the "first" row
 	 *
-	 * @access	public
 	 * @return	object
 	 */
 	public function first_row($type = 'object')
 	{
 		$result = $this->result($type);
-
-		if (count($result) == 0)
-		{
-			return $result;
-		}
-		return $result[0];
+		return (count($result) === 0) ? $result : $result[0];
 	}
 
 	// --------------------------------------------------------------------
@@ -332,18 +310,12 @@
 	/**
 	 * Returns the "last" row
 	 *
-	 * @access	public
 	 * @return	object
 	 */
 	public function last_row($type = 'object')
 	{
 		$result = $this->result($type);
-
-		if (count($result) == 0)
-		{
-			return $result;
-		}
-		return $result[count($result) -1];
+		return (count($result) === 0) ? $result : $result[count($result) - 1];
 	}
 
 	// --------------------------------------------------------------------
@@ -351,14 +323,12 @@
 	/**
 	 * Returns the "next" row
 	 *
-	 * @access	public
 	 * @return	object
 	 */
 	public function next_row($type = 'object')
 	{
 		$result = $this->result($type);
-
-		if (count($result) == 0)
+		if (count($result) === 0)
 		{
 			return $result;
 		}
@@ -376,14 +346,12 @@
 	/**
 	 * Returns the "previous" row
 	 *
-	 * @access	public
 	 * @return	object
 	 */
 	public function previous_row($type = 'object')
 	{
 		$result = $this->result($type);
-
-		if (count($result) == 0)
+		if (count($result) === 0)
 		{
 			return $result;
 		}
@@ -416,7 +384,6 @@
 	protected function _fetch_object() { return array(); }
 
 }
-// END DB_result class
 
 /* End of file DB_result.php */
 /* Location: ./system/database/DB_result.php */
diff --git a/system/database/DB_utility.php b/system/database/DB_utility.php
index 60ecb52..4c881d8 100644
--- a/system/database/DB_utility.php
+++ b/system/database/DB_utility.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Database Utility Class
  *
@@ -36,22 +34,15 @@
  */
 class CI_DB_utility extends CI_DB_forge {
 
-	var $db;
-	var $data_cache		= array();
+	public $db;
+	public $data_cache		= array();
 
-	/**
-	 * Constructor
-	 *
-	 * Grabs the CI super object instance so we can access it.
-	 *
-	 */
-	function __construct()
+	public function __construct()
 	{
 		// Assign the main database object to $this->db
 		$CI =& get_instance();
 		$this->db =& $CI->db;
-
-		log_message('debug', "Database Utility Class Initialized");
+		log_message('debug', 'Database Utility Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -59,10 +50,9 @@
 	/**
 	 * List databases
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function list_databases()
+	public function list_databases()
 	{
 		// Is there a cached result?
 		if (isset($this->data_cache['db_names']))
@@ -80,8 +70,7 @@
 			}
 		}
 
-		$this->data_cache['db_names'] = $dbs;
-		return $this->data_cache['db_names'];
+		return $this->data_cache['db_names'] = $dbs;
 	}
 
 	// --------------------------------------------------------------------
@@ -89,11 +78,10 @@
 	/**
 	 * Determine if a particular database exists
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	boolean
 	 */
-	function database_exists($database_name)
+	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
@@ -114,17 +102,17 @@
 	/**
 	 * Optimize Table
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	bool
 	 */
-	function optimize_table($table_name)
+	public function optimize_table($table_name)
 	{
 		$sql = $this->_optimize_table($table_name);
 
 		if (is_bool($sql))
 		{
-				show_error('db_must_use_set');
+			show_error('db_must_use_set');
+			return FALSE;
 		}
 
 		$query = $this->db->query($sql);
@@ -140,10 +128,9 @@
 	/**
 	 * Optimize Database
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function optimize_database()
+	public function optimize_database()
 	{
 		$result = array();
 		foreach ($this->db->list_tables() as $table_name)
@@ -177,11 +164,10 @@
 	/**
 	 * Repair Table
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	bool
 	 */
-	function repair_table($table_name)
+	public function repair_table($table_name)
 	{
 		$sql = $this->_repair_table($table_name);
 
@@ -203,14 +189,13 @@
 	/**
 	 * Generate CSV from a query result object
 	 *
-	 * @access	public
 	 * @param	object	The query result object
 	 * @param	string	The delimiter - comma by default
 	 * @param	string	The newline character - \n by default
 	 * @param	string	The enclosure - double quote by default
 	 * @return	string
 	 */
-	function csv_from_result($query, $delim = ",", $newline = "\n", $enclosure = '"')
+	public function csv_from_result($query, $delim = ',', $newline = "\n", $enclosure = '"')
 	{
 		if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
 		{
@@ -218,15 +203,13 @@
 		}
 
 		$out = '';
-
 		// First generate the headings from the table column names
 		foreach ($query->list_fields() as $name)
 		{
 			$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $name).$enclosure.$delim;
 		}
 
-		$out = rtrim($out);
-		$out .= $newline;
+		$out = rtrim($out).$newline;
 
 		// Next blast through the result array and build out the rows
 		foreach ($query->result_array() as $row)
@@ -235,8 +218,7 @@
 			{
 				$out .= $enclosure.str_replace($enclosure, $enclosure.$enclosure, $item).$enclosure.$delim;
 			}
-			$out = rtrim($out);
-			$out .= $newline;
+			$out = rtrim($out).$newline;
 		}
 
 		return $out;
@@ -247,12 +229,11 @@
 	/**
 	 * Generate XML data from a query result object
 	 *
-	 * @access	public
 	 * @param	object	The query result object
 	 * @param	array	Any preferences
 	 * @return	string
 	 */
-	function xml_from_result($query, $params = array())
+	public function xml_from_result($query, $params = array())
 	{
 		if ( ! is_object($query) OR ! method_exists($query, 'list_fields'))
 		{
@@ -280,16 +261,14 @@
 		foreach ($query->result_array() as $row)
 		{
 			$xml .= $tab."<{$element}>".$newline;
-
 			foreach ($row as $key => $val)
 			{
 				$xml .= $tab.$tab."<{$key}>".xml_convert($val)."</{$key}>".$newline;
 			}
 			$xml .= $tab."</{$element}>".$newline;
 		}
-		$xml .= "</$root>".$newline;
 
-		return $xml;
+		return $xml .= "</$root>".$newline;
 	}
 
 	// --------------------------------------------------------------------
@@ -297,10 +276,9 @@
 	/**
 	 * Database Backup
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function backup($params = array())
+	public function backup($params = array())
 	{
 		// If the parameters have not been submitted as an
 		// array then we know that it is simply the table
@@ -314,14 +292,14 @@
 
 		// Set up our default preferences
 		$prefs = array(
-							'tables'		=> array(),
-							'ignore'		=> array(),
-							'filename'		=> '',
-							'format'		=> 'gzip', // gzip, zip, txt
-							'add_drop'		=> TRUE,
-							'add_insert'	=> TRUE,
-							'newline'		=> "\n"
-						);
+				'tables'		=> array(),
+				'ignore'		=> array(),
+				'filename'		=> '',
+				'format'		=> 'gzip', // gzip, zip, txt
+				'add_drop'		=> TRUE,
+				'add_insert'		=> TRUE,
+				'newline'		=> "\n"
+			);
 
 		// Did the user submit any preferences? If so set them....
 		if (count($params) > 0)
@@ -335,29 +313,23 @@
 			}
 		}
 
-		// ------------------------------------------------------
-
 		// Are we backing up a complete database or individual tables?
 		// If no table names were submitted we'll fetch the entire table list
-		if (count($prefs['tables']) == 0)
+		if (count($prefs['tables']) === 0)
 		{
 			$prefs['tables'] = $this->db->list_tables();
 		}
 
-		// ------------------------------------------------------
-
 		// Validate the format
 		if ( ! in_array($prefs['format'], array('gzip', 'zip', 'txt'), TRUE))
 		{
 			$prefs['format'] = 'txt';
 		}
 
-		// ------------------------------------------------------
-
-		// Is the encoder supported?  If not, we'll either issue an
+		// 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' AND ! @function_exists('gzencode'))
+			OR ($prefs['format'] === 'zip'  AND ! @function_exists('gzcompress')))
 		{
 			if ($this->db->db_debug)
 			{
@@ -367,60 +339,49 @@
 			$prefs['format'] = 'txt';
 		}
 
-		// ------------------------------------------------------
-
-		// Set the filename if not provided - Only needed with Zip files
-		if ($prefs['filename'] == '' AND $prefs['format'] == 'zip')
-		{
-			$prefs['filename'] = (count($prefs['tables']) == 1) ? $prefs['tables'] : $this->db->database;
-			$prefs['filename'] .= '_'.date('Y-m-d_H-i', time());
-		}
-
-		// ------------------------------------------------------
-
-		// Was a Gzip file requested?
-		if ($prefs['format'] == 'gzip')
-		{
-			return gzencode($this->_backup($prefs));
-		}
-
-		// ------------------------------------------------------
-
-		// Was a text file requested?
-		if ($prefs['format'] == 'txt')
-		{
-			return $this->_backup($prefs);
-		}
-
-		// ------------------------------------------------------
-
 		// Was a Zip file requested?
-		if ($prefs['format'] == 'zip')
+		if ($prefs['format'] === 'zip')
 		{
-			// If they included the .zip file extension we'll remove it
-			if (preg_match("|.+?\.zip$|", $prefs['filename']))
+			// Set the filename if not provided (only needed with Zip files)
+			if ($prefs['filename'] == '')
 			{
-				$prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
+				$prefs['filename'] = (count($prefs['tables']) === 1 ? $prefs['tables'] : $this->db->database)
+							.date('Y-m-d_H-i', time()).'.sql';
 			}
-
-			// Tack on the ".sql" file extension if needed
-			if ( ! preg_match("|.+?\.sql$|", $prefs['filename']))
+			else
 			{
-				$prefs['filename'] .= '.sql';
+				// If they included the .zip file extension we'll remove it
+				if (preg_match('|.+?\.zip$|', $prefs['filename']))
+				{
+					$prefs['filename'] = str_replace('.zip', '', $prefs['filename']);
+				}
+
+				// Tack on the ".sql" file extension if needed
+				if ( ! preg_match('|.+?\.sql$|', $prefs['filename']))
+				{
+					$prefs['filename'] .= '.sql';
+				}
 			}
 
 			// Load the Zip class and output it
-
 			$CI =& get_instance();
 			$CI->load->library('zip');
 			$CI->zip->add_data($prefs['filename'], $this->_backup($prefs));
 			return $CI->zip->get_zip();
 		}
+		elseif ($prefs['format'] == 'txt') // Was a text file requested?
+		{
+			return $this->_backup($prefs);
+		}
+		elseif ($prefs['format'] === 'gzip') // Was a Gzip file requested?
+		{
+			return gzencode($this->_backup($prefs));
+		}
 
+		return;
 	}
 
 }
 
-
 /* End of file DB_utility.php */
-/* Location: ./system/database/DB_utility.php */
\ No newline at end of file
+/* Location: ./system/database/DB_utility.php */
diff --git a/system/database/drivers/cubrid/cubrid_driver.php b/system/database/drivers/cubrid/cubrid_driver.php
index 8181bd6..afdaef3 100644
--- a/system/database/drivers/cubrid/cubrid_driver.php
+++ b/system/database/drivers/cubrid/cubrid_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -156,37 +156,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Set client character set
+	 * Database version number
 	 *
-	 * @access	public
-	 * @param	string
-	 * @param	string
-	 * @return	resource
-	 */
-	function db_set_charset($charset, $collation)
-	{
-		// In CUBRID, there is no need to set charset or collation.
-		// This is why returning true will allow the application continue
-		// its normal process.
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Version number query string
-	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function _version()
+	public function version()
 	{
-		// To obtain the CUBRID Server version, no need to run the SQL query.
-		// CUBRID PHP API provides a function to determin this value.
-		// This is why we also need to add 'cubrid' value to the list of
-		// $driver_version_exceptions array in DB_driver class in
-		// version() function.
-		return cubrid_get_server_info($this->conn_id);
+		return isset($this->data_cache['version'])
+			? $this->data_cache['version']
+			: $this->data_cache['version'] = cubrid_get_server_info($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -362,12 +340,11 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
-		return @cubrid_affected_rows($this->conn_id);
+		return @cubrid_affected_rows();
 	}
 
 	// --------------------------------------------------------------------
@@ -472,31 +449,18 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		return cubrid_error($this->conn_id);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		return cubrid_errno($this->conn_id);
+		return array('code' => cubrid_errno($this->conn_id), 'message' => cubrid_error($this->conn_id));
 	}
 
-	// --------------------------------------------------------------------
-
 	/**
 	 * Escape the SQL Identifiers
 	 *
@@ -801,4 +765,4 @@
 
 
 /* End of file cubrid_driver.php */
-/* Location: ./system/database/drivers/cubrid/cubrid_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/cubrid/cubrid_driver.php */
diff --git a/system/database/drivers/cubrid/cubrid_forge.php b/system/database/drivers/cubrid/cubrid_forge.php
index 410d065..85e7400 100644
--- a/system/database/drivers/cubrid/cubrid_forge.php
+++ b/system/database/drivers/cubrid/cubrid_forge.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/cubrid/cubrid_result.php b/system/database/drivers/cubrid/cubrid_result.php
index b2f1bcf..4c0fede 100644
--- a/system/database/drivers/cubrid/cubrid_result.php
+++ b/system/database/drivers/cubrid/cubrid_result.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/cubrid/cubrid_utility.php b/system/database/drivers/cubrid/cubrid_utility.php
index 1fa0390..750c0d8 100644
--- a/system/database/drivers/cubrid/cubrid_utility.php
+++ b/system/database/drivers/cubrid/cubrid_utility.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/interbase/index.html b/system/database/drivers/interbase/index.html
new file mode 100644
index 0000000..c942a79
--- /dev/null
+++ b/system/database/drivers/interbase/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/interbase/interbase_driver.php b/system/database/drivers/interbase/interbase_driver.php
new file mode 100644
index 0000000..f4bd9e2
--- /dev/null
+++ b/system/database/drivers/interbase/interbase_driver.php
@@ -0,0 +1,627 @@
+<?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 3.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Firebird/Interbase Database Adapter Class
+ *
+ * Note: _DB is an extender class that the app controller
+ * creates dynamically based on whether the active record
+ * class is being used or not.
+ *
+ * @package		CodeIgniter
+ * @subpackage	Drivers
+ * @category	Database
+ * @author		EllisLab Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_interbase_driver extends CI_DB {
+
+	public $dbdriver = 'interbase';
+
+	// The character used to escape with
+	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()'; // database specific random keyword
+
+	// Keeps track of the resource for the current transaction
+	protected $trans;
+
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @return	resource
+	 */
+	public function db_connect()
+	{
+		return @ibase_connect($this->hostname.':'.$this->database, $this->username, $this->password, $this->char_set);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Persistent database connection
+	 *
+	 * @return	resource
+	 */
+	public function db_pconnect()
+	{
+		return @ibase_pconnect($this->hostname.':'.$this->database, $this->username, $this->password, $this->char_set);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Reconnect
+	 *
+	 * Keep / reestablish the db connection if no queries have been
+	 * sent for a length of time exceeding the server's idle timeout
+	 *
+	 * @return	void
+	 */
+	public function reconnect()
+	{
+		// not implemented in Interbase/Firebird
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Select the database
+	 *
+	 * @return	bool
+	 */
+	public function db_select()
+	{
+		// Connection selects the database
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Database version number
+	 *
+	 * @return	string
+	 */
+	public function version()
+	{
+		if (isset($this->data_cache['version']))
+		{
+			return $this->data_cache['version'];
+		}
+
+		if (($service = ibase_service_attach($this->hostname, $this->username, $this->password)))
+		{
+			$this->data_cache['version'] = ibase_server_info($service, IBASE_SVC_SERVER_VERSION);
+
+			// Don't keep the service open
+			ibase_service_detach($service);
+			return $this->data_cache['version'];
+		}
+
+		return FALSE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Execute the query
+	 *
+	 * @param	string	an SQL query
+	 * @return	resource
+	 */
+	protected function _execute($sql)
+	{
+		$sql = $this->_prep_query($sql);
+		return @ibase_query($this->conn_id, $sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Begin Transaction
+	 *
+	 * @return	bool
+	 */
+	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)
+		{
+			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) ? TRUE : FALSE;
+
+		$this->trans = @ibase_trans($this->conn_id);
+
+		return TRUE;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Commit Transaction
+	 *
+	 * @return	bool
+	 */
+	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)
+		{
+			return TRUE;
+		}
+
+		return @ibase_commit($this->trans);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Rollback Transaction
+	 *
+	 * @return	bool
+	 */
+	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)
+		{
+			return TRUE;
+		}
+
+		return @ibase_rollback($this->trans);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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;
+		}
+
+		// escape LIKE condition wildcards
+		if ($like === TRUE)
+		{
+			$str = 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	integer
+	 */
+	public function affected_rows()
+	{
+		return @ibase_affected_rows($this->conn_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Insert ID
+	 *
+	 * @param	string $generator_name
+	 * @param	integer $inc_by
+	 * @return	integer
+	 */
+	public function insert_id($generator_name, $inc_by=0)
+	{
+		//If a generator hasn't been used before it will return 0
+		return ibase_gen_id('"'.$generator_name.'"', $inc_by);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * "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
+	 *
+	 * @param	boolean
+	 * @return	string
+	 */
+	protected function _list_tables($prefix_limit = FALSE)
+	{
+		$sql = <<<SQL
+			SELECT "RDB\$RELATION_NAME" FROM "RDB\$RELATIONS" 
+			WHERE "RDB\$RELATION_NAME" NOT LIKE 'RDB$%'
+			AND "RDB\$RELATION_NAME" NOT LIKE 'MON$%'
+SQL;
+
+		if ($prefix_limit !== FALSE AND $this->dbprefix != '')
+		{
+			$sql .= ' AND "RDB$RELATION_NAME" LIKE \''.$this->escape_like_str($this->dbprefix)."%' ".sprintf($this->_like_escape_str, $this->_like_escape_chr);
+		}
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 = '')
+	{
+		return <<<SQL
+			SELECT "RDB\$FIELD_NAME" FROM "RDB\$RELATION_FIELDS" 
+			WHERE "RDB\$RELATION_NAME"='{$table}';
+SQL;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Field data query
+	 *
+	 * Generates a platform-specific query so that the column data can be retrieved
+	 *
+	 * @param	string	the table name
+	 * @return	object
+	 */
+	protected function _field_data($table)
+	{
+		// Need to find a more efficient way to do this
+		// but Interbase/Firebird seems to lack the
+		// limit clause
+		return "SELECT * FROM {$table}";
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Error
+	 *
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
+	 *
+	 * @return	array
+	 */
+	public function error()
+	{
+		return array('code' => ibase_errcode(), 'message' => ibase_errmsg());
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+			{
+				$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 public function implicitly groups FROM tables so there is no confusion
+	 * about operator precedence in harmony with SQL standards
+	 *
+	 * @param	type
+	 * @return	type
+	 */
+	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).')';
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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;
+
+		return $sql;
+	}
+
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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"
+	 *
+	 * @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 string
+	 *
+	 * Generates a platform-specific LIMIT clause
+	 *
+	 * @param	string	the sql query string
+	 * @param	integer	the number of rows to limit the query to
+	 * @param	integer	the offset value
+	 * @return	string
+	 */
+	protected function _limit($sql, $limit, $offset)
+	{
+		// Keep the current sql string safe for a moment
+		$orig_sql = $sql;
+
+		// Limit clause depends on if Interbase or Firebird
+		if (stripos($this->version(), 'firebird') !== FALSE)
+		{
+			$sql = 'FIRST '. (int) $limit;
+
+			if ($offset > 0)
+			{
+				$sql .= ' SKIP '. (int) $offset;
+			}
+		}
+		else
+		{
+			$sql = 'ROWS ' . (int) $limit;
+
+			if ($offset > 0)
+			{
+				$sql = 'ROWS '. (int) $offset . ' TO ' . ($limit + $offset);
+			}
+		}
+
+		return preg_replace('`SELECT`i', "SELECT {$sql}", $orig_sql);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Close DB Connection
+	 *
+	 * @param	resource
+	 * @return	void
+	 */
+	protected function _close($conn_id)
+	{
+		@ibase_close($conn_id);
+	}
+
+}
+
+/* End of file interbase_driver.php */
+/* Location: ./system/database/drivers/interbase/interbase_driver.php */
diff --git a/system/database/drivers/interbase/interbase_forge.php b/system/database/drivers/interbase/interbase_forge.php
new file mode 100644
index 0000000..023d278
--- /dev/null
+++ b/system/database/drivers/interbase/interbase_forge.php
@@ -0,0 +1,243 @@
+<?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 3.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Interbase/Firebird Forge Class
+ *
+ * @category	Database
+ * @author		EllisLab Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_interbase_forge extends CI_DB_forge {
+
+	/**
+	 * Create database
+	 *
+	 * @param	string	the database name
+	 * @return	string
+	 */
+	protected function _create_database($filename='')
+	{
+		// Firebird databases are flat files, so a path is required 
+		// Hostname is needed for remote access
+		return 'CREATE DATABASE "'.$this->hostname.':'.$filename.'"';
+		
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop database
+	 *
+	 * @param	string	the database name - not used in this driver 
+	 *	- the current db is dropped
+	 * @return	bool
+	 */
+	protected function _drop_database($name='')
+	{
+		return ibase_drop_db($this->conn_id);
+	}
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	boolean	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)."(";
+		$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->protect_identifiers($field);
+
+				$sql .=  ' '.$attributes['TYPE'];
+
+				if (array_key_exists('CONSTRAINT', $attributes))
+				{
+					$sql .= '('.$attributes['CONSTRAINT'].')';
+				}
+
+				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
+				{
+					$sql .= ' UNSIGNED';
+				}
+
+				if (array_key_exists('DEFAULT', $attributes))
+				{
+					$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 .= ' 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)
+		{
+			$primary_keys = $this->db->protect_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));
+				}
+
+				$sql .= ",\n\tUNIQUE (" . implode(', ', $key) . ")";
+			}
+		}
+
+		$sql .= "\n)";
+
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Drop Table
+	 *
+	 * @return	string
+	 */
+	protected function _drop_table($table)
+	{
+		return 'DROP TABLE '.$name;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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	boolean	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;
+
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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 */
+/* Location: ./system/database/drivers/interbase/interbase_forge.php */
\ No newline at end of file
diff --git a/system/database/drivers/interbase/interbase_result.php b/system/database/drivers/interbase/interbase_result.php
new file mode 100644
index 0000000..4b15eee
--- /dev/null
+++ b/system/database/drivers/interbase/interbase_result.php
@@ -0,0 +1,294 @@
+<?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 3.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Interbase/Firebird Result Class
+ *
+ * This class extends the parent result class: CI_DB_result
+ *
+ * @category	Database
+ * @author		EllisLab Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+class CI_DB_interbase_result extends CI_DB_result {
+
+	public $num_rows;
+
+	/**
+	 * Number of rows in the result set
+	 *
+	 * @return	integer
+	 */
+	public function num_rows()
+	{
+		if( ! is_null($this->num_rows))
+		{
+			return $this->num_rows;
+		}
+		
+		//Get the results so that you can get an accurate rowcount
+		$this->result();
+		
+		return $this->num_rows;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Number of fields in the result set
+	 *
+	 * @return	integer
+	 */
+	public function num_fields()
+	{
+		return @ibase_num_fields($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Fetch Field Names
+	 *
+	 * Generates an array of column names
+	 *
+	 * @return	array
+	 */
+	public function list_fields()
+	{
+		$field_names = array();
+		for ($i = 0, $num_fields = $this->num_fields(); $i < $num_fields; $i++)
+		{
+			$info = ibase_field_info($this->result_id, $i);
+			$field_names[] = $info['name'];
+		}
+
+		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, $num_fields = $this->num_fields(); $i < $num_fields; $i++)
+		{
+			$info = ibase_field_info($this->result_id, $i);
+		
+			$F				= new stdClass();
+			$F->name		= $info['name'];
+			$F->type		= $info['type'];
+			$F->max_length	= $info['length'];
+			$F->primary_key = 0;
+			$F->default		= '';
+
+			$retval[] = $F;
+		}
+
+		return $retval;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Free the result
+	 *
+	 * @return	null
+	 */
+	public function free_result()
+	{
+		@ibase_free_result($this->result_id);
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * 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)
+	{
+		//Set the row count to 0
+		$this->num_rows = 0;
+	
+		//Interbase driver doesn't implement a suitable function
+		return FALSE;	
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - associative array
+	 *
+	 * Returns the result set as an array
+	 *
+	 * @return	array
+	 */
+	protected function _fetch_assoc()
+	{
+		if (($row = @ibase_fetch_assoc($this->result_id, IBASE_FETCH_BLOBS)) !== FALSE)
+		{
+			//Increment row count
+			$this->num_rows++;
+		}
+	
+		return $row;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Result - object
+	 *
+	 * Returns the result set as an object
+	 *
+	 * @return	object
+	 */
+	protected function _fetch_object()
+	{
+		if (($row = @ibase_fetch_object($this->result_id, IBASE_FETCH_BLOBS)) !== FALSE)
+		{
+			//Increment row count
+			$this->num_rows++;
+		}
+		
+		return $row;
+	}
+	
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  "object" version.
+	 *
+	 * @return	object
+	 */
+	public function result_object()
+	{
+		if (count($this->result_object) > 0)
+		{
+			return $this->result_object;
+		}
+		
+		// Convert result array to object so that 
+		// We don't have to get the result again
+		if (count($this->result_array) > 0)
+		{
+			$i = 0;
+		
+			foreach ($this->result_array as $array)
+			{
+				$this->result_object[$i] = new StdClass();
+			
+				foreach ($array as $key => $val)
+				{
+					$this->result_object[$i]->{$key} = $val;
+				}
+				
+				++$i;
+			}
+			
+			return $this->result_object;
+		}
+
+		// 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)
+		{
+			return array();
+		}
+
+		$this->num_rows = 0;
+		while ($row = $this->_fetch_object())
+		{
+			$this->result_object[] = $row;
+		}
+
+		return $this->result_object;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Query result.  "array" version.
+	 *
+	 * @return	array
+	 */
+	public function result_array()
+	{
+		if (count($this->result_array) > 0)
+		{
+			return $this->result_array;
+		}
+		
+		// Since the object and array are really similar, just case
+		// the result object to an array  if need be
+		if (count($this->result_object) > 0)
+		{
+			foreach ($this->result_object as $obj)
+			{
+				$this->result_array[] = (array) $obj;
+			}
+		
+			return $this->result_array;
+		}
+
+		// 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)
+		{
+			return array();
+		}
+
+		$this->num_rows = 0;
+		while ($row = $this->_fetch_assoc())
+		{
+			$this->result_array[] = $row;
+		}
+
+		return $this->result_array;
+	}
+
+}
+
+/* End of file interbase_result.php */
+/* Location: ./system/database/drivers/interbase/interbase_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/interbase/interbase_utility.php b/system/database/drivers/interbase/interbase_utility.php
new file mode 100644
index 0000000..76a0497
--- /dev/null
+++ b/system/database/drivers/interbase/interbase_utility.php
@@ -0,0 +1,115 @@
+<?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 3.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Interbase/Firebird Utility Class
+ *
+ * @category	Database
+ * @author		EllisLab Dev Team
+ * @link		http://codeigniter.com/user_guide/database/
+ */
+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;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Interbase/Firebird Export
+	 *
+	 * @param	string	$filename
+	 * @return	mixed
+	 */
+	public 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	
+			ibase_service_detach($service);
+			
+			return $res;
+		}
+		else
+		{
+			return FALSE;
+		}
+	}
+}
+
+/* End of file interbase_utility.php */
+/* Location: ./system/database/drivers/interbase/interbase_utility.php */
\ No newline at end of file
diff --git a/system/database/drivers/mssql/mssql_driver.php b/system/database/drivers/mssql/mssql_driver.php
index 87e7c9d..147c634 100644
--- a/system/database/drivers/mssql/mssql_driver.php
+++ b/system/database/drivers/mssql/mssql_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -114,30 +114,25 @@
 	/**
 	 * Select the database
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @param	string	database name
+	 * @return	bool
 	 */
-	function db_select()
+	public function db_select($database = '')
 	{
+		if ($database === '')
+		{
+			$database = $this->database;
+		}
+
 		// Note: The brackets are required in the event that the DB name
 		// contains reserved characters
-		return @mssql_select_db('['.$this->database.']', $this->conn_id);
-	}
+		if (@mssql_select_db('['.$database.']', $this->conn_id))
+		{
+			$this->database = $database;
+			return TRUE;
+		}
 
-	// --------------------------------------------------------------------
-
-	/**
-	 * Set client character set
-	 *
-	 * @access	public
-	 * @param	string
-	 * @param	string
-	 * @return	resource
-	 */
-	function db_set_charset($charset, $collation)
-	{
-		// @todo - add support if needed
-		return TRUE;
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -344,12 +339,11 @@
 	/**
 	* Version number query string
 	*
-	* @access public
-	* @return string
+	* @return	string
 	*/
-	function _version()
+	protected function _version()
 	{
-		return "SELECT @@VERSION AS ver";
+		return 'SELECT @@VERSION AS ver';
 	}
 
 	// --------------------------------------------------------------------
@@ -443,28 +437,18 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		return mssql_get_last_message();
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		// Are error numbers supported?
-		return '';
+		$query = $this->query('SELECT @@ERROR AS code');
+		$query = $query->row();
+		return array('code' => $query->code, 'message' => mssql_get_last_message());
 	}
 
 	// --------------------------------------------------------------------
@@ -676,4 +660,4 @@
 
 
 /* End of file mssql_driver.php */
-/* Location: ./system/database/drivers/mssql/mssql_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mssql/mssql_driver.php */
diff --git a/system/database/drivers/mssql/mssql_forge.php b/system/database/drivers/mssql/mssql_forge.php
index 0a893f6..dd8aa34 100644
--- a/system/database/drivers/mssql/mssql_forge.php
+++ b/system/database/drivers/mssql/mssql_forge.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/mssql/mssql_result.php b/system/database/drivers/mssql/mssql_result.php
index a8cd7c9..bba2e62 100644
--- a/system/database/drivers/mssql/mssql_result.php
+++ b/system/database/drivers/mssql/mssql_result.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/mssql/mssql_utility.php b/system/database/drivers/mssql/mssql_utility.php
index 576d13f..be6ed5b 100644
--- a/system/database/drivers/mssql/mssql_utility.php
+++ b/system/database/drivers/mssql/mssql_utility.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php
index 6ded6e5..7fd08a6 100644
--- a/system/database/drivers/mysql/mysql_driver.php
+++ b/system/database/drivers/mysql/mysql_driver.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MySQL Database Adapter Class
  *
@@ -42,46 +40,47 @@
  */
 class CI_DB_mysql_driver extends CI_DB {
 
-	var $dbdriver = 'mysql';
+	public $dbdriver = 'mysql';
 
 	// The character used for escaping
-	var	$_escape_char = '`';
+	protected $_escape_char = '`';
 
 	// clause and character used for LIKE escape sequences - not used in MySQL
-	var $_like_escape_str = '';
-	var $_like_escape_chr = '';
-
-	/**
-	 * Whether to use the MySQL "delete hack" which allows the number
-	 * of affected rows to be shown. Uses a preg_replace when enabled,
-	 * adding a bit more processing to all queries.
-	 */
-	var $delete_hack = TRUE;
+	protected $_like_escape_str = '';
+	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.
 	 */
-	var $_count_string = 'SELECT COUNT(*) AS ';
-	var $_random_keyword = ' RAND()'; // database specific random keyword
-
-	// whether SET NAMES must be used to set the character set
-	var $use_set_names;
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' RAND()'; // database specific random keyword
 
 	/**
-	 * Non-persistent database connection
-	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * Whether to use the MySQL "delete hack" which allows the number
+	 * of affected rows to be shown. Uses a preg_replace when enabled,
+	 * adding a bit more processing to all queries.
 	 */
-	function db_connect()
+	public $delete_hack = TRUE;
+
+	public function __construct($params)
 	{
+		parent::__construct($params);
+
 		if ($this->port != '')
 		{
 			$this->hostname .= ':'.$this->port;
 		}
+	}
 
+	/**
+	 * Non-persistent database connection
+	 *
+	 * @return	resource
+	 */
+	public function db_connect()
+	{
 		return @mysql_connect($this->hostname, $this->username, $this->password, TRUE);
 	}
 
@@ -90,16 +89,10 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
 	 * @return	resource
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		if ($this->port != '')
-		{
-			$this->hostname .= ':'.$this->port;
-		}
-
 		return @mysql_pconnect($this->hostname, $this->username, $this->password);
 	}
 
@@ -111,10 +104,9 @@
 	 * Keep / reestablish the db connection if no queries have been
 	 * sent for a length of time exceeding the server's idle timeout
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function reconnect()
+	public function reconnect()
 	{
 		if (mysql_ping($this->conn_id) === FALSE)
 		{
@@ -127,12 +119,23 @@
 	/**
 	 * Select the database
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @param	string	database name
+	 * @return	bool
 	 */
-	function db_select()
+	public function db_select($database = '')
 	{
-		return @mysql_select_db($this->database, $this->conn_id);
+		if ($database === '')
+		{
+			$database = $this->database;
+		}
+
+		if (@mysql_select_db($database, $this->conn_id))
+		{
+			$this->database = $database;
+			return TRUE;
+		}
+
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -140,12 +143,11 @@
 	/**
 	 * Set client character set
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
-	 * @return	resource
+	 * @return	bool
 	 */
-	function db_set_charset($charset, $collation)
+	protected function _db_set_charset($charset, $collation)
 	{
 		return function_exists('mysql_set_charset')
 			? @mysql_set_charset($charset, $this->conn_id)
@@ -155,14 +157,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Version number query string
+	 * Database version number
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function _version()
+	public function version()
 	{
-		return "SELECT version() AS ver";
+		return isset($this->data_cache['version'])
+			? $this->data_cache['version']
+			: $this->data_cache['version'] = @mysql_get_server_info($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -170,14 +173,12 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
-	 * @return	resource
+	 * @return	mixed
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
-		return @mysql_query($sql, $this->conn_id);
+		return @mysql_query($this->_prep_query($sql), $this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -187,20 +188,16 @@
 	 *
 	 * If needed, each database adapter can prep the query string
 	 *
-	 * @access	private called by execute()
 	 * @param	string	an SQL query
 	 * @return	string
 	 */
-	function _prep_query($sql)
+	protected function _prep_query($sql)
 	{
-		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies
-		// the query so that it returns the number of affected rows
-		if ($this->delete_hack === TRUE)
+		// mysql_affected_rows() returns 0 for "DELETE FROM TABLE" queries. This hack
+		// modifies the query so that it a proper number of affected rows is returned.
+		if ($this->delete_hack === TRUE && preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
 		{
-			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
-			{
-				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
-			}
+			return preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', 'DELETE FROM \\1 WHERE 1=1', $sql);
 		}
 
 		return $sql;
@@ -211,18 +208,12 @@
 	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	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;
 		}
@@ -230,7 +221,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('SET AUTOCOMMIT=0');
 		$this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
@@ -242,18 +233,12 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	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;
 		}
@@ -268,18 +253,12 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	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;
 		}
@@ -294,12 +273,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		if (is_array($str))
 		{
@@ -311,7 +289,7 @@
 	   		return $str;
 	   	}
 
-		if (function_exists('mysql_real_escape_string') AND is_resource($this->conn_id))
+		if (function_exists('mysql_real_escape_string') && is_resource($this->conn_id))
 		{
 			$str = mysql_real_escape_string($str, $this->conn_id);
 		}
@@ -327,7 +305,7 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+			return str_replace(array('%', '_'), array('\\%', '\\_'), $str);
 		}
 
 		return $str;
@@ -338,10 +316,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @mysql_affected_rows($this->conn_id);
 	}
@@ -351,10 +328,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		return @mysql_insert_id($this->conn_id);
 	}
@@ -367,27 +343,25 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function count_all($table = '')
+	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));
-
+		$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();
+		$query = $query->row();
 		$this->_reset_select();
-		return (int) $row->numrows;
+		return (int) $query->numrows;
 	}
 
 	// --------------------------------------------------------------------
@@ -397,17 +371,16 @@
 	 *
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
-	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;
+		$sql = 'SHOW TABLES FROM '.$this->_escape_char.$this->database.$this->_escape_char;
 
-		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;
@@ -420,55 +393,61 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	public function _list_columns($table = '')
 	{
-		return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
+		return 'SHOW COLUMNS FROM '.$this->protect_identifiers($table, TRUE, NULL, FALSE);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Field data query
+	 * Returns an object with field data
 	 *
-	 * Generates a platform-specific query so that the column data can be retrieved
-	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	object
 	 */
-	function _field_data($table)
+	public function field_data($table = '')
 	{
-		return "DESCRIBE ".$table;
+		if ($table == '')
+		{
+			return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
+		}
+
+		$query = $this->query('DESCRIBE '.$this->_protect_identifiers($table, TRUE, NULL, FALSE));
+		$query = $query->result_object();
+
+		$retval = array();
+		for ($i = 0, $c = count($query); $i < $c; $i++)
+		{
+			preg_match('/([a-z]+)(\(\d+\))?/', $query[$i]->Type, $matches);
+
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $query[$i]->Field;
+			$retval[$i]->type		= empty($matches[1]) ? NULL : $matches[1];
+			$retval[$i]->default		= $query[$i]->Default;
+			$retval[$i]->max_length		= empty($matches[2]) ? NULL : preg_replace('/[^\d]/', '', $matches[2]);
+			$retval[$i]->primary_key	= (int) ($query[$i]->Key === 'PRI');
+		}
+
+		return $retval;
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		return mysql_error($this->conn_id);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		return mysql_errno($this->conn_id);
+		return array('code' => mysql_errno($this->conn_id), 'message' => mysql_error($this->conn_id));
 	}
 
 	// --------------------------------------------------------------------
@@ -478,11 +457,10 @@
 	 *
 	 * This function escapes column and table names
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	function _escape_identifiers($item)
+	public function _escape_identifiers($item)
 	{
 		if ($this->_escape_char == '')
 		{
@@ -493,24 +471,20 @@
 		{
 			if (strpos($item, '.'.$id) !== FALSE)
 			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
+				$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, $str);
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
 			}
 		}
 
 		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;
+			$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, $str);
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
 	}
 
 	// --------------------------------------------------------------------
@@ -521,11 +495,10 @@
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	string	table name
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -542,15 +515,14 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert($table, $keys, $values)
+	protected function _insert($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -561,15 +533,14 @@
 	 *
 	 * Generates a platform-specific replace string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _replace($table, $keys, $values)
+	protected function _replace($table, $keys, $values)
 	{
-		return "REPLACE INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -579,15 +550,14 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert_batch($table, $keys, $values)
+	protected function _insert_batch($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
 	}
 
 	// --------------------------------------------------------------------
@@ -598,7 +568,6 @@
 	 *
 	 * Generates a platform-specific update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
@@ -606,34 +575,22 @@
 	 * @param	array	the limit clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE, $like = array())
 	{
 		foreach ($values as $key => $val)
 		{
-			$valstr[] = $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) : '';
-		
-		if (count($like) > 0) 
+		$where = ($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '';
+		if (count($like) > 0)
 		{
-			$sql .= ($where == '' AND count($where) <1) ? " WHERE " : ' AND ';
-			
-			foreach ($like as $st_like) 
-			{
-				$sql .= " " . $st_like;	
-			}
+			$where .= ($where == '' ? ' WHERE ' : ' AND ').implode(' ', $like);
 		}
 
-		$sql .= $orderby.$limit;
-
-		return $sql;
+		return 'UPDATE '.$table.' SET '.implode(', ', $valstr).$where
+			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
+			.( ! $limit ? '' : ' LIMIT '.$limit);
 	}
 
 	// --------------------------------------------------------------------
@@ -644,17 +601,14 @@
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
 	 * @return	string
 	 */
-	function _update_batch($table, $values, $index, $where = NULL)
+	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];
@@ -668,30 +622,21 @@
 			}
 		}
 
-		$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)."\n"
+				.'ELSE '.$k.' END, ';
 		}
 
-		$sql .= substr($cases, 0, -2);
-
-		$sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
-
-		return $sql;
+		return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
+			.' WHERE '.(($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
+			.$index.' IN('.implode(',', $ids).')';
 	}
 
 	// --------------------------------------------------------------------
 
-
 	/**
 	 * Truncate statement
 	 *
@@ -699,13 +644,12 @@
 	 * If the database does not support the truncate() command
 	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return "TRUNCATE ".$table;
+		return 'TRUNCATE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -715,31 +659,27 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	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);
+			$conditions = "\nWHERE ".implode("\n", $this->ar_where);
 
 			if (count($where) > 0 && count($like) > 0)
 			{
-				$conditions .= " AND ";
+				$conditions .= ' AND ';
 			}
 			$conditions .= implode("\n", $like);
 		}
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit);
 	}
 
 	// --------------------------------------------------------------------
@@ -749,24 +689,14 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
-		if ($offset == 0)
-		{
-			$offset = '';
-		}
-		else
-		{
-			$offset .= ", ";
-		}
-
-		return $sql."LIMIT ".$offset.$limit;
+		return $sql.' LIMIT '.($offset == 0 ? '' : $offset.', ').$limit;
 	}
 
 	// --------------------------------------------------------------------
@@ -774,17 +704,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@mysql_close($conn_id);
 	}
 
 }
 
-
 /* End of file mysql_driver.php */
-/* Location: ./system/database/drivers/mysql/mysql_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mysql/mysql_driver.php */
diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php
index 89aaf5d..0f251b0 100644
--- a/system/database/drivers/mysql/mysql_forge.php
+++ b/system/database/drivers/mysql/mysql_forge.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MySQL Forge Class
  *
@@ -39,13 +37,12 @@
 	/**
 	 * Create database
 	 *
-	 * @access	private
 	 * @param	string	the database name
-	 * @return	bool
+	 * @return	string
 	 */
-	function _create_database($name)
+	public function _create_database($name)
 	{
-		return "CREATE DATABASE ".$name;
+		return 'CREATE DATABASE '.$name;
 	}
 
 	// --------------------------------------------------------------------
@@ -53,13 +50,12 @@
 	/**
 	 * Drop database
 	 *
-	 * @access	private
 	 * @param	string	the database name
-	 * @return	bool
+	 * @return	string
 	 */
-	function _drop_database($name)
+	public function _drop_database($name)
 	{
-		return "DROP DATABASE ".$name;
+		return 'DROP DATABASE '.$name;
 	}
 
 	// --------------------------------------------------------------------
@@ -67,83 +63,57 @@
 	/**
 	 * Process Fields
 	 *
-	 * @access	private
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	function _process_fields($fields)
+	private function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
 
-		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->protect_identifiers($field)
+					.( ! empty($attributes['NAME']) ? ' '.$this->db->protect_identifiers($attributes['NAME']).' ' : '');
 
-				if (array_key_exists('NAME', $attributes))
-				{
-					$sql .= ' '.$this->db->_protect_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;
-
+								break;
 							case 'enum':
 							case 'set':
 								$sql .= '("'.implode('","', $attributes['CONSTRAINT']).'")';
-							break;
-
+								break;
 							default:
 								$sql .= '('.$attributes['CONSTRAINT'].')';
 						}
 					}
 				}
 
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
-				{
-					$sql .= ' UNSIGNED';
-				}
-
-				if (array_key_exists('DEFAULT', $attributes))
-				{
-					$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 .= ' AUTO_INCREMENT';
-				}
+				$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' : '');
 			}
 
 			// don't add a comma on the end of the last field
@@ -161,15 +131,14 @@
 	/**
 	 * Create Table
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @param	mixed	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	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -178,15 +147,12 @@
 			$sql .= 'IF NOT EXISTS ';
 		}
 
-		$sql .= $this->db->_escape_identifiers($table)." (";
-
-		$sql .= $this->_process_fields($fields);
+		$sql .= $this->db->protect_identifiers($table).' ('.$this->_process_fields($fields);
 
 		if (count($primary_keys) > 0)
 		{
 			$key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));
-			$primary_keys = $this->db->_protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";
+			$sql .= ",\n\tPRIMARY KEY ".$key_name.' ('.implode(', ', $this->db->protect_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
@@ -204,13 +170,11 @@
 					$key = array($key_name);
 				}
 
-				$sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tKEY ".$key_name.' ('.implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";
-
-		return $sql;
+		return $sql."\n) DEFAULT CHARACTER SET ".$this->db->char_set.' COLLATE '.$this->db->dbcollat.';';
 	}
 
 	// --------------------------------------------------------------------
@@ -218,12 +182,12 @@
 	/**
 	 * Drop Table
 	 *
-	 * @access	private
+	 * @param	string	table name
 	 * @return	string
 	 */
-	function _drop_table($table)
+	public function _drop_table($table)
 	{
-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
+		return 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -232,33 +196,26 @@
 	 * Alter table query
 	 *
 	 * Generates a platform-specific query so that a table can be altered
-	 * Called by add_column(), drop_column(), and column_alter(),
+	 * Called by add_column(), drop_column() and column_alter()
 	 *
-	 * @access	private
 	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
 	 * @param	string	the column name
 	 * @param	array	fields
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $fields, $after_field = '')
+	public function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";
+		$sql = 'ALTER TABLE '.$this->db->protect_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->protect_identifiers($fields);
 		}
 
-		$sql .= $this->_process_fields($fields);
-
-		if ($after_field != '')
-		{
-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
-		}
-
-		return $sql;
+		return $sql.$this->_process_fields($fields)
+			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -268,18 +225,16 @@
 	 *
 	 * Generates a platform-specific query so that a table can be renamed
 	 *
-	 * @access	private
 	 * @param	string	the old table name
 	 * @param	string	the new table name
 	 * @return	string
 	 */
-	function _rename_table($table_name, $new_table_name)
+	public function _rename_table($table_name, $new_table_name)
 	{
-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
-		return $sql;
+		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
 	}
 
 }
 
 /* End of file mysql_forge.php */
-/* Location: ./system/database/drivers/mysql/mysql_forge.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mysql/mysql_forge.php */
diff --git a/system/database/drivers/mysql/mysql_result.php b/system/database/drivers/mysql/mysql_result.php
index 29297b6..5a65d9c 100644
--- a/system/database/drivers/mysql/mysql_result.php
+++ b/system/database/drivers/mysql/mysql_result.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// --------------------------------------------------------------------
-
 /**
  * MySQL Result Class
  *
@@ -41,10 +39,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		return @mysql_num_rows($this->result_id);
 	}
@@ -54,10 +51,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return @mysql_num_fields($this->result_id);
 	}
@@ -69,10 +65,9 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		$field_names = array();
 		while ($field = mysql_fetch_field($this->result_id))
@@ -90,27 +85,19 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
-		while ($field = mysql_fetch_object($this->result_id))
+		for ($i = 0, $c = $this->num_fields(); $i < $c; $i++)
 		{
-			preg_match('/([a-zA-Z]+)(\(\d+\))?/', $field->Type, $matches);
-
-			$type = (array_key_exists(1, $matches)) ? $matches[1] : NULL;
-			$length = (array_key_exists(2, $matches)) ? preg_replace('/[^\d]/', '', $matches[2]) : NULL;
-
-			$F				= new stdClass();
-			$F->name		= $field->Field;
-			$F->type		= $type;
-			$F->default		= $field->Default;
-			$F->max_length	= $length;
-			$F->primary_key = ( $field->Key == 'PRI' ? 1 : 0 );
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= mysql_field_name($this->result_id, $i);
+			$retval[$i]->type		= mysql_field_type($this->result_id, $i);
+			$retval[$i]->max_length		= mysql_field_len($this->result_id, $i);
+			$retval[$i]->primary_key	= (strpos(mysql_field_flags($this->result_id, $i), 'primary_key') === FALSE) ? 0 : 1;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -121,9 +108,9 @@
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_resource($this->result_id))
 		{
@@ -137,14 +124,13 @@
 	/**
 	 * 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
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return mysql_data_seek($this->result_id, $n);
 	}
@@ -156,10 +142,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return mysql_fetch_assoc($this->result_id);
 	}
@@ -171,16 +156,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return mysql_fetch_object($this->result_id);
 	}
 
 }
 
-
 /* End of file mysql_result.php */
-/* Location: ./system/database/drivers/mysql/mysql_result.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mysql/mysql_result.php */
diff --git a/system/database/drivers/mysql/mysql_utility.php b/system/database/drivers/mysql/mysql_utility.php
index 9cb6645..952f887 100644
--- a/system/database/drivers/mysql/mysql_utility.php
+++ b/system/database/drivers/mysql/mysql_utility.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MySQL Utility Class
  *
@@ -39,12 +37,11 @@
 	/**
 	 * List databases
 	 *
-	 * @access	private
-	 * @return	bool
+	 * @return	string
 	 */
-	function _list_databases()
+	public function _list_databases()
 	{
-		return "SHOW DATABASES";
+		return 'SHOW DATABASES';
 	}
 
 	// --------------------------------------------------------------------
@@ -54,13 +51,12 @@
 	 *
 	 * Generates a platform-specific query so that a table can be optimized
 	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _optimize_table($table)
+	public function _optimize_table($table)
 	{
-		return "OPTIMIZE TABLE ".$this->db->_escape_identifiers($table);
+		return 'OPTIMIZE TABLE '.$this->db->protect_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -70,26 +66,24 @@
 	 *
 	 * Generates a platform-specific query so that a table can be repaired
 	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _repair_table($table)
+	public function _repair_table($table)
 	{
-		return "REPAIR TABLE ".$this->db->_escape_identifiers($table);
+		return 'REPAIR TABLE '.$this->db->protect_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
 	/**
 	 * MySQL Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	public function _backup($params = array())
 	{
-		if (count($params) == 0)
+		if (count($params) === 0)
 		{
 			return FALSE;
 		}
@@ -99,16 +93,16 @@
 
 		// Build the output
 		$output = '';
-		foreach ((array)$tables as $table)
+		foreach ( (array) $tables as $table)
 		{
 			// Is the table in the "ignore" list?
-			if (in_array($table, (array)$ignore, TRUE))
+			if (in_array($table, (array) $ignore, TRUE))
 			{
 				continue;
 			}
 
 			// Get the table schema
-			$query = $this->db->query("SHOW CREATE TABLE `".$this->db->database.'`.`'.$table.'`');
+			$query = $this->db->query('SHOW CREATE TABLE '.$this->db->protect_identifiers($this->db->database).'.'.$this->db->protect_identifiers($table));
 
 			// No result means the table name was invalid
 			if ($query === FALSE)
@@ -121,7 +115,7 @@
 
 			if ($add_drop == TRUE)
 			{
-				$output .= 'DROP TABLE IF EXISTS '.$table.';'.$newline.$newline;
+				$output .= 'DROP TABLE IF EXISTS '.$this->db->protect_identifiers($table).';'.$newline.$newline;
 			}
 
 			$i = 0;
@@ -141,7 +135,7 @@
 			}
 
 			// Grab all the data from the current table
-			$query = $this->db->query("SELECT * FROM $table");
+			$query = $this->db->query('SELECT * FROM '.$this->db->protect_identifiers($table));
 
 			if ($query->num_rows() == 0)
 			{
@@ -149,7 +143,7 @@
 			}
 
 			// Fetch the field names and determine if the field is an
-			// integer type.  We use this info to decide whether to
+			// integer type. We use this info to decide whether to
 			// surround the data with quotes or not
 
 			$i = 0;
@@ -158,20 +152,17 @@
 			while ($field = mysql_fetch_field($query->result_id))
 			{
 				// Most versions of MySQL store timestamp as a string
-				$is_int[$i] = (in_array(
-										strtolower(mysql_field_type($query->result_id, $i)),
-										array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'),
-										TRUE)
-										) ? TRUE : FALSE;
+				$is_int[$i] = in_array(strtolower(mysql_field_type($query->result_id, $i)),
+							array('tinyint', 'smallint', 'mediumint', 'int', 'bigint'), //, 'timestamp'),
+							TRUE);
 
 				// Create a string of field names
-				$field_str .= '`'.$field->name.'`, ';
+				$field_str .= $this->db->protect_identifiers($field->name).', ';
 				$i++;
 			}
 
 			// Trim off the end comma
-			$field_str = preg_replace( "/, $/" , "" , $field_str);
-
+			$field_str = preg_replace('/, $/' , '', $field_str);
 
 			// Build the insert string
 			foreach ($query->result_array() as $row)
@@ -189,14 +180,7 @@
 					else
 					{
 						// Escape the data if it's not an integer
-						if ($is_int[$i] == FALSE)
-						{
-							$val_str .= $this->db->escape($v);
-						}
-						else
-						{
-							$val_str .= $v;
-						}
+						$val_str .= ($is_int[$i] == FALSE) ? $this->db->escape($v) : $v;
 					}
 
 					// Append a comma
@@ -205,10 +189,10 @@
 				}
 
 				// Remove the comma at the end of the string
-				$val_str = preg_replace( "/, $/" , "" , $val_str);
+				$val_str = preg_replace('/, $/' , '', $val_str);
 
 				// Build the INSERT string
-				$output .= 'INSERT INTO '.$table.' ('.$field_str.') VALUES ('.$val_str.');'.$newline;
+				$output .= 'INSERT INTO '.$this->db->protect_identifiers($table).' ('.$field_str.') VALUES ('.$val_str.');'.$newline;
 			}
 
 			$output .= $newline.$newline;
@@ -216,7 +200,8 @@
 
 		return $output;
 	}
+
 }
 
 /* End of file mysql_utility.php */
-/* Location: ./system/database/drivers/mysql/mysql_utility.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mysql/mysql_utility.php */
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index fb5953b..25b6cec 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,17 +18,15 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
- * MySQLi Database Adapter Class - MySQLi only works with PHP 5
+ * MySQLi Database Adapter Class
  *
  * Note: _DB is an extender class that the app controller
  * creates dynamically based on whether the active record
@@ -42,52 +40,40 @@
  */
 class CI_DB_mysqli_driver extends CI_DB {
 
-	var $dbdriver = 'mysqli';
+	public $dbdriver = 'mysqli';
 
 	// The character used for escaping
-	var $_escape_char = '`';
+	protected $_escape_char = '`';
 
 	// clause and character used for LIKE escape sequences - not used in MySQL
-	var $_like_escape_str = '';
-	var $_like_escape_chr = '';
+	protected $_like_escape_str = '';
+	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.
 	 */
-	var $_count_string = "SELECT COUNT(*) AS ";
-	var $_random_keyword = ' RAND()'; // database specific random keyword
+	protected $_count_string = 'SELECT COUNT(*) AS ';
+	protected $_random_keyword = ' RAND()'; // database specific random keyword
 
 	/**
 	 * Whether to use the MySQL "delete hack" which allows the number
 	 * of affected rows to be shown. Uses a preg_replace when enabled,
 	 * adding a bit more processing to all queries.
 	 */
-	var $delete_hack = TRUE;
-
-	// whether SET NAMES must be used to set the character set
-	var $use_set_names;
-
-	// --------------------------------------------------------------------
+	public $delete_hack = TRUE;
 
 	/**
 	 * Non-persistent database connection
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @return	object
 	 */
-	function db_connect()
+	public function db_connect()
 	{
-		if ($this->port != '')
-		{
-			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port);
-		}
-		else
-		{
-			return @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
-		}
-
+		return ($this->port != '')
+			? @mysqli_connect($this->hostname, $this->username, $this->password, $this->database, $this->port)
+			: @mysqli_connect($this->hostname, $this->username, $this->password, $this->database);
 	}
 
 	// --------------------------------------------------------------------
@@ -95,12 +81,19 @@
 	/**
 	 * Persistent database connection
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @return	object
 	 */
-	function db_pconnect()
+	public function db_pconnect()
 	{
-		return $this->db_connect();
+		// Persistent connection support was added in PHP 5.3.0
+		if ( ! is_php('5.3'))
+		{
+			return $this->db_connect();
+		}
+
+		return ($this->port != '')
+			? @mysqli_connect('p:'.$this->hostname, $this->username, $this->password, $this->database, $this->port)
+			: @mysqli_connect('p:'.$this->hostname, $this->username, $this->password, $this->database);
 	}
 
 	// --------------------------------------------------------------------
@@ -111,10 +104,9 @@
 	 * Keep / reestablish the db connection if no queries have been
 	 * sent for a length of time exceeding the server's idle timeout
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function reconnect()
+	public function reconnect()
 	{
 		if (mysqli_ping($this->conn_id) === FALSE)
 		{
@@ -127,12 +119,23 @@
 	/**
 	 * Select the database
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @param	string	database name
+	 * @return	bool
 	 */
-	function db_select()
+	public function db_select($database = '')
 	{
-		return @mysqli_select_db($this->conn_id, $this->database);
+		if ($database === '')
+		{
+			$database = $this->database;
+		}
+
+		if (@mysqli_select_db($this->conn_id, $database))
+		{
+			$this->database = $database;
+			return TRUE;
+		}
+
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -140,12 +143,11 @@
 	/**
 	 * Set client character set
 	 *
-	 * @access	private
 	 * @param	string
 	 * @param	string
-	 * @return	resource
+	 * @return	bool
 	 */
-	function _db_set_charset($charset, $collation)
+	protected function _db_set_charset($charset, $collation)
 	{
 		return function_exists('mysqli_set_charset')
 			? @mysqli_set_charset($this->conn_id, $charset)
@@ -155,14 +157,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Version number query string
+	 * Database version number
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function _version()
+	public function version()
 	{
-		return "SELECT version() AS ver";
+		return isset($this->data_cache['version'])
+			? $this->data_cache['version']
+			: $this->data_cache['version'] = @mysqli_get_server_info($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -170,15 +173,12 @@
 	/**
 	 * Execute the query
 	 *
-	 * @access	private called by the base class
 	 * @param	string	an SQL query
-	 * @return	resource
+	 * @return	mixed
 	 */
-	function _execute($sql)
+	protected function _execute($sql)
 	{
-		$sql = $this->_prep_query($sql);
-		$result = @mysqli_query($this->conn_id, $sql);
-		return $result;
+		return @mysqli_query($this->conn_id, $this->_prep_query($sql));
 	}
 
 	// --------------------------------------------------------------------
@@ -188,20 +188,16 @@
 	 *
 	 * If needed, each database adapter can prep the query string
 	 *
-	 * @access	private called by execute()
 	 * @param	string	an SQL query
 	 * @return	string
 	 */
-	function _prep_query($sql)
+	protected function _prep_query($sql)
 	{
-		// "DELETE FROM TABLE" returns 0 affected rows This hack modifies
-		// the query so that it returns the number of affected rows
-		if ($this->delete_hack === TRUE)
+		// mysqli_affected_rows() returns 0 for "DELETE FROM TABLE" queries. This hack
+		// modifies the query so that it a proper number of affected rows is returned.
+		if ($this->delete_hack === TRUE && preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
 		{
-			if (preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql))
-			{
-				$sql = preg_replace("/^\s*DELETE\s+FROM\s+(\S+)\s*$/", "DELETE FROM \\1 WHERE 1=1", $sql);
-			}
+			return preg_replace('/^\s*DELETE\s+FROM\s+(\S+)\s*$/', 'DELETE FROM \\1 WHERE 1=1', $sql);
 		}
 
 		return $sql;
@@ -212,18 +208,12 @@
 	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	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;
 		}
@@ -231,7 +221,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('SET AUTOCOMMIT=0');
 		$this->simple_query('START TRANSACTION'); // can also be BEGIN or BEGIN WORK
@@ -243,18 +233,12 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	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;
 		}
@@ -269,18 +253,12 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	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;
 		}
@@ -295,12 +273,11 @@
 	/**
 	 * Escape String
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
 	 * @return	string
 	 */
-	function escape_str($str, $like = FALSE)
+	public function escape_str($str, $like = FALSE)
 	{
 		if (is_array($str))
 		{
@@ -312,7 +289,7 @@
 			return $str;
 		}
 
-		if (function_exists('mysqli_real_escape_string') AND is_object($this->conn_id))
+		if (function_exists('mysqli_real_escape_string') && is_object($this->conn_id))
 		{
 			$str = mysqli_real_escape_string($this->conn_id, $str);
 		}
@@ -328,7 +305,7 @@
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = str_replace(array('%', '_'), array('\\%', '\\_'), $str);
+			return str_replace(array('%', '_'), array('\\%', '\\_'), $str);
 		}
 
 		return $str;
@@ -339,10 +316,9 @@
 	/**
 	 * Affected Rows
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function affected_rows()
+	public function affected_rows()
 	{
 		return @mysqli_affected_rows($this->conn_id);
 	}
@@ -352,10 +328,9 @@
 	/**
 	 * Insert ID
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function insert_id()
+	public function insert_id()
 	{
 		return @mysqli_insert_id($this->conn_id);
 	}
@@ -368,27 +343,25 @@
 	 * Generates a platform-specific query string that counts all records in
 	 * the specified database
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function count_all($table = '')
+	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));
-
+		$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();
+		$query = $query->row();
 		$this->_reset_select();
-		return (int) $row->numrows;
+		return (int) $query->numrows;
 	}
 
 	// --------------------------------------------------------------------
@@ -399,16 +372,16 @@
 	 * Generates a platform-specific query string so that the table names can be fetched
 	 *
 	 * @access	private
-	 * @param	boolean
+	 * @param	bool
 	 * @return	string
 	 */
-	function _list_tables($prefix_limit = FALSE)
+	protected function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = "SHOW TABLES FROM ".$this->_escape_char.$this->database.$this->_escape_char;
+		$sql = 'SHOW TABLES FROM '.$this->_escape_char.$this->database.$this->_escape_char;
 
-		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;
@@ -421,55 +394,61 @@
 	 *
 	 * Generates a platform-specific query string so that the column names can be fetched
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _list_columns($table = '')
+	protected function _list_columns($table = '')
 	{
-		return "SHOW COLUMNS FROM ".$this->_protect_identifiers($table, TRUE, NULL, FALSE);
+		return 'SHOW COLUMNS FROM '.$this->_protect_identifiers($table, TRUE, NULL, FALSE);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Field data query
+	 * Returns an object with field data
 	 *
-	 * Generates a platform-specific query so that the column data can be retrieved
-	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	object
 	 */
-	function _field_data($table)
+	public function field_data($table = '')
 	{
-		return "DESCRIBE ".$table;
+		if ($table == '')
+		{
+			return ($this->db_debug) ? $this->display_error('db_field_param_missing') : FALSE;
+		}
+
+		$query = $this->query('DESCRIBE '.$this->_protect_identifiers($table, TRUE, NULL, FALSE));
+		$query = $query->result_object();
+
+		$retval = array();
+		for ($i = 0, $c = count($query); $i < $c; $i++)
+		{
+			preg_match('/([a-z]+)(\(\d+\))?/', $query[$i]->Type, $matches);
+
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $query[$i]->Field;
+			$retval[$i]->type		= empty($matches[1]) ? NULL : $matches[1];
+			$retval[$i]->default		= $query[$i]->Default;
+			$retval[$i]->max_length		= empty($matches[2]) ? NULL : preg_replace('/[^\d]/', '', $matches[2]);
+			$retval[$i]->primary_key	= (int) ($query[$i]->Key === 'PRI');
+		}
+
+		return $retval;
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		return mysqli_error($this->conn_id);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		return mysqli_errno($this->conn_id);
+		return array('code' => mysqli_errno($this->conn_id), 'message' => mysqli_error($this->conn_id));
 	}
 
 	// --------------------------------------------------------------------
@@ -479,11 +458,10 @@
 	 *
 	 * This function escapes column and table names
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	function _escape_identifiers($item)
+	public function _escape_identifiers($item)
 	{
 		if ($this->_escape_char == '')
 		{
@@ -494,24 +472,20 @@
 		{
 			if (strpos($item, '.'.$id) !== FALSE)
 			{
-				$str = $this->_escape_char. str_replace('.', $this->_escape_char.'.', $item);
+				$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, $str);
+				return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item);
 			}
 		}
 
 		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;
+			$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, $str);
+		return preg_replace('/['.$this->_escape_char.']+/', $this->_escape_char, $this->_escape_char.$item.$this->_escape_char);
 	}
 
 	// --------------------------------------------------------------------
@@ -522,11 +496,10 @@
 	 * This function implicitly groups FROM tables so there is no confusion
 	 * about operator precedence in harmony with SQL standards
 	 *
-	 * @access	public
-	 * @param	type
-	 * @return	type
+	 * @param	string
+	 * @return	string
 	 */
-	function _from_tables($tables)
+	protected function _from_tables($tables)
 	{
 		if ( ! is_array($tables))
 		{
@@ -543,15 +516,14 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert($table, $keys, $values)
+	protected function _insert($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -561,15 +533,14 @@
 	 *
 	 * Generates a platform-specific insert string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _insert_batch($table, $keys, $values)
+	protected function _insert_batch($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
+		return 'INSERT INTO '.$table.' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
 	}
 
 	// --------------------------------------------------------------------
@@ -580,17 +551,16 @@
 	 *
 	 * Generates a platform-specific replace string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the insert keys
 	 * @param	array	the insert values
 	 * @return	string
 	 */
-	function _replace($table, $keys, $values)
+	protected function _replace($table, $keys, $values)
 	{
-		return "REPLACE INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return 'REPLACE INTO '.$table.' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -598,7 +568,6 @@
 	 *
 	 * Generates a platform-specific update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
@@ -606,24 +575,17 @@
 	 * @param	array	the limit clause
 	 * @return	string
 	 */
-	function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
+	protected function _update($table, $values, $where, $orderby = array(), $limit = FALSE)
 	{
 		foreach ($values as $key => $val)
 		{
-			$valstr[] = $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 'UPDATE '.$table.' SET '.implode(', ', $valstr)
+			.(($where != '' && count($where) > 0) ? ' WHERE '.implode(' ', $where) : '')
+			.(count($orderby) > 0 ? ' ORDER BY '.implode(', ', $orderby) : '')
+			.( ! $limit ? '' : ' LIMIT '.$limit);
 	}
 
 	// --------------------------------------------------------------------
@@ -633,17 +595,14 @@
 	 *
 	 * Generates a platform-specific batch update string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the update data
 	 * @param	array	the where clause
 	 * @return	string
 	 */
-	function _update_batch($table, $values, $index, $where = NULL)
+	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];
@@ -657,25 +616,19 @@
 			}
 		}
 
-		$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)."\n"
+				.'ELSE '.$k.' END, ';
 		}
 
-		$sql .= substr($cases, 0, -2);
+		$where = ($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '';
 
-		$sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
-
-		return $sql;
+		return 'UPDATE '.$table.' SET '.substr($cases, 0, -2)
+			.' WHERE '.(($where != '' && count($where) > 0) ? implode(' ', $where).' AND ' : '')
+			.$index.' IN('.implode(',', $ids).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -687,13 +640,12 @@
 	 * If the database does not support the truncate() command
 	 * This function maps to "DELETE FROM table"
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @return	string
 	 */
-	function _truncate($table)
+	protected function _truncate($table)
 	{
-		return "TRUNCATE ".$table;
+		return 'TRUNCATE '.$table;
 	}
 
 	// --------------------------------------------------------------------
@@ -703,31 +655,26 @@
 	 *
 	 * Generates a platform-specific delete string from the supplied data
 	 *
-	 * @access	public
 	 * @param	string	the table name
 	 * @param	array	the where clause
 	 * @param	string	the limit clause
 	 * @return	string
 	 */
-	function _delete($table, $where = array(), $like = array(), $limit = FALSE)
+	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);
+			$conditions = "\nWHERE ".implode("\n", $this->ar_where);
 
 			if (count($where) > 0 && count($like) > 0)
 			{
-				$conditions .= " AND ";
+				$conditions .= ' AND ';
 			}
 			$conditions .= implode("\n", $like);
 		}
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
-
-		return "DELETE FROM ".$table.$conditions.$limit;
+		return 'DELETE FROM '.$table.$conditions.( ! $limit ? '' : ' LIMIT '.$limit);
 	}
 
 	// --------------------------------------------------------------------
@@ -737,22 +684,15 @@
 	 *
 	 * Generates a platform-specific LIMIT clause
 	 *
-	 * @access	public
 	 * @param	string	the sql query string
-	 * @param	integer	the number of rows to limit the query to
-	 * @param	integer	the offset value
+	 * @param	int	the number of rows to limit the query to
+	 * @param	int	the offset value
 	 * @return	string
 	 */
-	function _limit($sql, $limit, $offset)
+	protected function _limit($sql, $limit, $offset)
 	{
-		$sql .= "LIMIT ".$limit;
-
-		if ($offset > 0)
-		{
-			$sql .= " OFFSET ".$offset;
-		}
-
-		return $sql;
+		return $sql.' LIMIT '.$limit
+			.($offset > 0 ? ' OFFSET '.$offset : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -760,18 +700,15 @@
 	/**
 	 * Close DB Connection
 	 *
-	 * @access	public
-	 * @param	resource
+	 * @param	object
 	 * @return	void
 	 */
-	function _close($conn_id)
+	protected function _close($conn_id)
 	{
 		@mysqli_close($conn_id);
 	}
 
-
 }
 
-
 /* End of file mysqli_driver.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mysqli/mysqli_driver.php */
diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php
index cdd5399..7de0361 100644
--- a/system/database/drivers/mysqli/mysqli_forge.php
+++ b/system/database/drivers/mysqli/mysqli_forge.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MySQLi Forge Class
  *
@@ -39,13 +37,12 @@
 	/**
 	 * Create database
 	 *
-	 * @access	private
 	 * @param	string	the database name
-	 * @return	bool
+	 * @return	string
 	 */
-	function _create_database($name)
+	public function _create_database($name)
 	{
-		return "CREATE DATABASE ".$name;
+		return 'CREATE DATABASE '.$name;
 	}
 
 	// --------------------------------------------------------------------
@@ -53,13 +50,12 @@
 	/**
 	 * Drop database
 	 *
-	 * @access	private
 	 * @param	string	the database name
-	 * @return	bool
+	 * @return	string
 	 */
-	function _drop_database($name)
+	public function _drop_database($name)
 	{
-		return "DROP DATABASE ".$name;
+		return 'DROP DATABASE '.$name;
 	}
 
 	// --------------------------------------------------------------------
@@ -67,68 +63,35 @@
 	/**
 	 * Process Fields
 	 *
-	 * @access	private
 	 * @param	mixed	the fields
 	 * @return	string
 	 */
-	function _process_fields($fields)
+	public function _process_fields($fields)
 	{
 		$current_field_count = 0;
 		$sql = '';
 
-		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);
-
-				if (array_key_exists('NAME', $attributes))
-				{
-					$sql .= ' '.$this->db->_protect_identifiers($attributes['NAME']).' ';
-				}
-
-				if (array_key_exists('TYPE', $attributes))
-				{
-					$sql .=  ' '.$attributes['TYPE'];
-				}
-
-				if (array_key_exists('CONSTRAINT', $attributes))
-				{
-					$sql .= '('.$attributes['CONSTRAINT'].')';
-				}
-
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
-				{
-					$sql .= ' UNSIGNED';
-				}
-
-				if (array_key_exists('DEFAULT', $attributes))
-				{
-					$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 .= ' AUTO_INCREMENT';
-				}
+				$sql .= "\n\t".$this->db->protect_identifiers($field)
+					.( ! empty($attributes['NAME']) ? ' '.$this->db->protect_identifiers($attributes['NAME']).' ' : '')
+					.( ! empty($attributes['TYPE']) ? ' '.$attributes['TYPE'] : '')
+					.( ! empty($attributes['CONSTRAINT']) ? '('.$attributes['CONSTRAINT'].')' : '')
+					.(( ! 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' : '');
 			}
 
 			// don't add a comma on the end of the last field
@@ -146,15 +109,14 @@
 	/**
 	 * Create Table
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @param	mixed	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	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -163,15 +125,12 @@
 			$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 (count($primary_keys) > 0)
 		{
-			$key_name = $this->db->_protect_identifiers(implode('_', $primary_keys));
-			$primary_keys = $this->db->_protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY ".$key_name." (" . implode(', ', $primary_keys) . ")";
+			$key_name = $this->db->protect_identifiers(implode('_', $primary_keys));
+			$sql .= ",\n\tPRIMARY KEY ".$key_name.' ('.implode(', ', $this->db->protect_identifiers($primary_keys)).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
@@ -180,22 +139,20 @@
 			{
 				if (is_array($key))
 				{
-					$key_name = $this->db->_protect_identifiers(implode('_', $key));
-					$key = $this->db->_protect_identifiers($key);
+					$key_name = $this->db->protect_identifiers(implode('_', $key));
+					$key = $this->db->protect_identifiers($key);
 				}
 				else
 				{
-					$key_name = $this->db->_protect_identifiers($key);
+					$key_name = $this->db->protect_identifiers($key);
 					$key = array($key_name);
 				}
 
-				$sql .= ",\n\tKEY {$key_name} (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tKEY ".$key_name.' ('.implode(', ', $key).')';
 			}
 		}
 
-		$sql .= "\n) DEFAULT CHARACTER SET {$this->db->char_set} COLLATE {$this->db->dbcollat};";
-
-		return $sql;
+		return $sql."\n) DEFAULT CHARACTER SET ".$this->db->char_set.' COLLATE '.$this->db->dbcollat.';';
 	}
 
 	// --------------------------------------------------------------------
@@ -203,12 +160,11 @@
 	/**
 	 * Drop Table
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _drop_table($table)
+	public function _drop_table($table)
 	{
-		return "DROP TABLE IF EXISTS ".$this->db->_escape_identifiers($table);
+		return 'DROP TABLE IF EXISTS '.$this->db->_escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -219,31 +175,24 @@
 	 * Generates a platform-specific query so that a table can be altered
 	 * Called by add_column(), drop_column(), and column_alter(),
 	 *
-	 * @access	private
 	 * @param	string	the ALTER type (ADD, DROP, CHANGE)
 	 * @param	string	the column name
 	 * @param	array	fields
 	 * @param	string	the field after which we should add the new field
-	 * @return	object
+	 * @return	string
 	 */
-	function _alter_table($alter_type, $table, $fields, $after_field = '')
+	public function _alter_table($alter_type, $table, $fields, $after_field = '')
 	{
-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";
+		$sql = 'ALTER TABLE '.$this->db->_protect_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->protect_identifiers($fields);
 		}
 
-		$sql .= $this->_process_fields($fields);
-
-		if ($after_field != '')
-		{
-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
-		}
-
-		return $sql;
+		return $sql.$this->_process_fields($fields)
+			.($after_field != '' ? ' AFTER '.$this->db->protect_identifiers($after_field) : '');
 	}
 
 	// --------------------------------------------------------------------
@@ -253,18 +202,16 @@
 	 *
 	 * Generates a platform-specific query so that a table can be renamed
 	 *
-	 * @access	private
 	 * @param	string	the old table name
 	 * @param	string	the new table name
 	 * @return	string
 	 */
-	function _rename_table($table_name, $new_table_name)
+	public function _rename_table($table_name, $new_table_name)
 	{
-		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
-		return $sql;
+		return 'ALTER TABLE '.$this->db->protect_identifiers($table_name).' RENAME TO '.$this->db->protect_identifiers($new_table_name);
 	}
 
 }
 
 /* End of file mysqli_forge.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_forge.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mysqli/mysqli_forge.php */
diff --git a/system/database/drivers/mysqli/mysqli_result.php b/system/database/drivers/mysqli/mysqli_result.php
index 163788b..8b909cc 100644
--- a/system/database/drivers/mysqli/mysqli_result.php
+++ b/system/database/drivers/mysqli/mysqli_result.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MySQLi Result Class
  *
@@ -41,10 +39,9 @@
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
 		return @mysqli_num_rows($this->result_id);
 	}
@@ -54,10 +51,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return @mysqli_num_fields($this->result_id);
 	}
@@ -69,10 +65,9 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		$field_names = array();
 		while ($field = mysqli_fetch_field($this->result_id))
@@ -90,40 +85,33 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
-		while ($field = mysqli_fetch_object($this->result_id))
+		$field_data = mysqli_fetch_fields($this->result_id);
+		for ($i = 0, $c = count($field_data); $i < $c; $i++)
 		{
-			preg_match('/([a-zA-Z]+)(\(\d+\))?/', $field->Type, $matches);
-
-			$type = (array_key_exists(1, $matches)) ? $matches[1] : NULL;
-			$length = (array_key_exists(2, $matches)) ? preg_replace('/[^\d]/', '', $matches[2]) : NULL;
-
-			$F				= new stdClass();
-			$F->name		= $field->Field;
-			$F->type		= $type;
-			$F->default		= $field->Default;
-			$F->max_length	= $length;
-			$F->primary_key = ( $field->Key == 'PRI' ? 1 : 0 );
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= $field_data[$i]->name;
+			$retval[$i]->type		= $field_data[$i]->type;
+			$retval[$i]->max_length		= $field_data[$i]->max_length;
+			$retval[$i]->primary_key	= (int) ($field_data[$i]->flags & 2);
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
 	 * Free the result
 	 *
-	 * @return	null
+	 * @return	void
 	 */
-	function free_result()
+	public function free_result()
 	{
 		if (is_object($this->result_id))
 		{
@@ -141,10 +129,9 @@
 	 * this internally before fetching results to make sure the
 	 * result set starts at zero
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _data_seek($n = 0)
+	protected function _data_seek($n = 0)
 	{
 		return mysqli_data_seek($this->result_id, $n);
 	}
@@ -156,10 +143,9 @@
 	 *
 	 * Returns the result set as an array
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _fetch_assoc()
+	protected function _fetch_assoc()
 	{
 		return mysqli_fetch_assoc($this->result_id);
 	}
@@ -171,16 +157,14 @@
 	 *
 	 * Returns the result set as an object
 	 *
-	 * @access	private
 	 * @return	object
 	 */
-	function _fetch_object()
+	protected function _fetch_object()
 	{
 		return mysqli_fetch_object($this->result_id);
 	}
 
 }
 
-
 /* End of file mysqli_result.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_result.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mysqli/mysqli_result.php */
diff --git a/system/database/drivers/mysqli/mysqli_utility.php b/system/database/drivers/mysqli/mysqli_utility.php
index ef7c89f..3fdc5c7 100644
--- a/system/database/drivers/mysqli/mysqli_utility.php
+++ b/system/database/drivers/mysqli/mysqli_utility.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * MySQLi Utility Class
  *
@@ -39,12 +37,11 @@
 	/**
 	 * List databases
 	 *
-	 * @access	private
-	 * @return	bool
+	 * @return	string
 	 */
-	function _list_databases()
+	public function _list_databases()
 	{
-		return "SHOW DATABASES";
+		return 'SHOW DATABASES';
 	}
 
 	// --------------------------------------------------------------------
@@ -54,13 +51,12 @@
 	 *
 	 * Generates a platform-specific query so that a table can be optimized
 	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _optimize_table($table)
+	public function _optimize_table($table)
 	{
-		return "OPTIMIZE TABLE ".$this->db->_escape_identifiers($table);
+		return 'OPTIMIZE TABLE '.$this->db->_escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -70,13 +66,12 @@
 	 *
 	 * Generates a platform-specific query so that a table can be repaired
 	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _repair_table($table)
+	public function _repair_table($table)
 	{
-		return "REPAIR TABLE ".$this->db->_escape_identifiers($table);
+		return 'REPAIR TABLE '.$this->db->_escape_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -84,11 +79,10 @@
 	/**
 	 * MySQLi Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	public function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
@@ -96,4 +90,4 @@
 }
 
 /* End of file mysqli_utility.php */
-/* Location: ./system/database/drivers/mysqli/mysqli_utility.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mysqli/mysqli_utility.php */
diff --git a/system/database/drivers/oci8/oci8_driver.php b/system/database/drivers/oci8/oci8_driver.php
index 9c38dcb..35cafff 100644
--- a/system/database/drivers/oci8/oci8_driver.php
+++ b/system/database/drivers/oci8/oci8_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -139,30 +139,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Set client character set
+	 * Database version number
 	 *
-	 * @access	public
-	 * @param	string
-	 * @param	string
-	 * @return	resource
+	 * @return	string
 	 */
-	public function db_set_charset($charset, $collation)
+	public function version()
 	{
-		// this is done upon connect
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Version number query string
-	 *
-	 * @access  protected
-	 * @return  string
-	 */
-	protected function _version()
-	{
-		return oci_server_version($this->conn_id);
+		return isset($this->data_cache['version'])
+			? $this->data_cache['version']
+			: $this->data_cache['version'] = oci_server_version($this->conn_id);
 	}
 
 	// --------------------------------------------------------------------
@@ -398,10 +383,9 @@
 	/**
 	 * Escape String
 	 *
-	 * @access  public
-	 * @param   string
+	 * @param	string
 	 * @param	bool	whether or not the string will be used in a LIKE condition
-	 * @return  string
+	 * @return	string
 	 */
 	public function escape_str($str, $like = FALSE)
 	{
@@ -415,15 +399,14 @@
 			return $str;
 		}
 
-		$str = remove_invisible_characters($str);
-		$str = str_replace("'", "''", $str);
+		$str = str_replace("'", "''", remove_invisible_characters($str));
 
 		// escape LIKE condition wildcards
 		if ($like === TRUE)
 		{
-			$str = 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_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;
@@ -545,31 +528,32 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access  protected
-	 * @return  string
-	 */
-	protected function _error_message()
-	{
-		// If the error was during connection, no conn_id should be passed
-		$error = is_resource($this->conn_id) ? oci_error($this->conn_id) : oci_error();
-		return $error['message'];
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access  protected
-	 * @return  integer
+	 * @return	array
 	 */
-	protected function _error_number()
+	public function error()
 	{
-		// Same as _error_message()
-		$error = is_resource($this->conn_id) ? oci_error($this->conn_id) : oci_error();
-		return $error['code'];
+		/* oci_error() returns an array that already contains the
+		 * 'code' and 'message' keys, so we can just return it.
+		 */
+		if (is_resource($this->curs_id))
+		{
+			return oci_error($this->curs_id);
+		}
+		elseif (is_resource($this->stmt_id))
+		{
+			return oci_error($this->stmt_id);
+		}
+		elseif (is_resource($this->conn_id))
+		{
+			return oci_error($this->conn_id);
+		}
+
+		return oci_error();
 	}
 
 	// --------------------------------------------------------------------
diff --git a/system/database/drivers/oci8/oci8_forge.php b/system/database/drivers/oci8/oci8_forge.php
index bafab3d..0aa1199 100644
--- a/system/database/drivers/oci8/oci8_forge.php
+++ b/system/database/drivers/oci8/oci8_forge.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -67,15 +67,14 @@
 	/**
 	 * Create Table
 	 *
-	 * @access	private
 	 * @param	string	the table name
 	 * @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	bool
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	public function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
 	{
 		$sql = 'CREATE TABLE ';
 
@@ -84,54 +83,27 @@
 			$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 .=  ' '.$attributes['TYPE'];
-
-				if (array_key_exists('CONSTRAINT', $attributes))
-				{
-					$sql .= '('.$attributes['CONSTRAINT'].')';
-				}
-
-				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
-				{
-					$sql .= ' UNSIGNED';
-				}
-
-				if (array_key_exists('DEFAULT', $attributes))
-				{
-					$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 .= ' AUTO_INCREMENT';
-				}
+				$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'] : '');
 			}
 
 			// don't add a comma on the end of the last field
@@ -143,8 +115,8 @@
 
 		if (count($primary_keys) > 0)
 		{
-			$primary_keys = $this->db->_protect_identifiers($primary_keys);
-			$sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")";
+			$primary_keys = $this->db->protect_identifiers($primary_keys);
+			$sql .= ",\n\tCONSTRAINT ".$table.' PRIMARY KEY ('.implode(', ', $primary_keys).')';
 		}
 
 		if (is_array($keys) && count($keys) > 0)
@@ -153,20 +125,18 @@
 			{
 				if (is_array($key))
 				{
-					$key = $this->db->_protect_identifiers($key);
+					$key = $this->db->protect_identifiers($key);
 				}
 				else
 				{
-					$key = array($this->db->_protect_identifiers($key));
+					$key = array($this->db->protect_identifiers($key));
 				}
 
-				$sql .= ",\n\tUNIQUE COLUMNS (" . implode(', ', $key) . ")";
+				$sql .= ",\n\tUNIQUE COLUMNS (".implode(', ', $key).")";
 			}
 		}
 
-		$sql .= "\n)";
-
-		return $sql;
+		return $sql."\n)";
 	}
 
 	// --------------------------------------------------------------------
@@ -257,4 +227,4 @@
 }
 
 /* End of file oci8_forge.php */
-/* Location: ./system/database/drivers/oci8/oci8_forge.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/oci8/oci8_forge.php */
diff --git a/system/database/drivers/oci8/oci8_result.php b/system/database/drivers/oci8/oci8_result.php
index f325592..0f69fa9 100644
--- a/system/database/drivers/oci8/oci8_result.php
+++ b/system/database/drivers/oci8/oci8_result.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/oci8/oci8_utility.php b/system/database/drivers/oci8/oci8_utility.php
index 28c374d..d60f98b 100644
--- a/system/database/drivers/oci8/oci8_utility.php
+++ b/system/database/drivers/oci8/oci8_utility.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/odbc/odbc_driver.php b/system/database/drivers/odbc/odbc_driver.php
index 0e9d46d..779b0c6 100644
--- a/system/database/drivers/odbc/odbc_driver.php
+++ b/system/database/drivers/odbc/odbc_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -124,35 +124,6 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Set client character set
-	 *
-	 * @access	public
-	 * @param	string
-	 * @param	string
-	 * @return	resource
-	 */
-	function db_set_charset($charset, $collation)
-	{
-		// @todo - add support if needed
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Version number query string
-	 *
-	 * @access	public
-	 * @return	string
-	 */
-	function _version()
-	{
-		return "SELECT version() AS ver";
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
 	 * Execute the query
 	 *
 	 * @access	private called by the base class
@@ -414,27 +385,16 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		return odbc_errormsg($this->conn_id);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		return odbc_error($this->conn_id);
+		return array('code' => odbc_error($this->conn_id), 'message' => odbc_errormsg($this->conn_id));
 	}
 
 	// --------------------------------------------------------------------
@@ -646,4 +606,4 @@
 
 
 /* End of file odbc_driver.php */
-/* Location: ./system/database/drivers/odbc/odbc_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/odbc/odbc_driver.php */
diff --git a/system/database/drivers/odbc/odbc_forge.php b/system/database/drivers/odbc/odbc_forge.php
index e326a28..e0ec687 100644
--- a/system/database/drivers/odbc/odbc_forge.php
+++ b/system/database/drivers/odbc/odbc_forge.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/odbc/odbc_result.php b/system/database/drivers/odbc/odbc_result.php
index b23a821..572e110 100644
--- a/system/database/drivers/odbc/odbc_result.php
+++ b/system/database/drivers/odbc/odbc_result.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -38,15 +38,27 @@
  */
 class CI_DB_odbc_result extends CI_DB_result {
 
+	public $num_rows;
+
 	/**
 	 * Number of rows in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_rows()
+	public function num_rows()
 	{
-		return @odbc_num_rows($this->result_id);
+		if (is_int($this->num_rows))
+		{
+			return $this->num_rows;
+		}
+
+		// Work-around for ODBC subdrivers that don't support num_rows()
+		if (($this->num_rows = @odbc_num_rows($this->result_id)) === -1)
+		{
+			$this->num_rows = count($this->result_array());
+		}
+
+		return $this->num_rows;
 	}
 
 	// --------------------------------------------------------------------
@@ -54,10 +66,9 @@
 	/**
 	 * Number of fields in the result set
 	 *
-	 * @access	public
-	 * @return	integer
+	 * @return	int
 	 */
-	function num_fields()
+	public function num_fields()
 	{
 		return @odbc_num_fields($this->result_id);
 	}
@@ -69,15 +80,19 @@
 	 *
 	 * Generates an array of column names
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function list_fields()
+	public function list_fields()
 	{
 		$field_names = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		$num_fields = $this->num_fields();
+
+		if ($num_fields > 0)
 		{
-			$field_names[]	= odbc_field_name($this->result_id, $i);
+			for ($i = 1; $i <= $num_fields; $i++)
+			{
+				$field_names[] = odbc_field_name($this->result_id, $i);
+			}
 		}
 
 		return $field_names;
@@ -90,22 +105,19 @@
 	 *
 	 * Generates an array of objects containing field meta-data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function field_data()
+	public function field_data()
 	{
 		$retval = array();
-		for ($i = 0; $i < $this->num_fields(); $i++)
+		for ($i = 0, $odbc_index = 1, $c = $this->num_fields(); $i < $c; $i++, $odbc_index++)
 		{
-			$F				= new stdClass();
-			$F->name		= odbc_field_name($this->result_id, $i);
-			$F->type		= odbc_field_type($this->result_id, $i);
-			$F->max_length	= odbc_field_len($this->result_id, $i);
-			$F->primary_key = 0;
-			$F->default		= '';
-
-			$retval[] = $F;
+			$retval[$i]			= new stdClass();
+			$retval[$i]->name		= odbc_field_name($this->result_id, $odbc_index);
+			$retval[$i]->type		= odbc_field_type($this->result_id, $odbc_index);
+			$retval[$i]->max_length		= odbc_field_len($this->result_id, $odbc_index);
+			$retval[$i]->primary_key	= 0;
+			$retval[$i]->default		= '';
 		}
 
 		return $retval;
@@ -237,4 +249,4 @@
 
 
 /* End of file odbc_result.php */
-/* Location: ./system/database/drivers/odbc/odbc_result.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/odbc/odbc_result.php */
diff --git a/system/database/drivers/odbc/odbc_utility.php b/system/database/drivers/odbc/odbc_utility.php
index 94666ac..bae3fe8 100644
--- a/system/database/drivers/odbc/odbc_utility.php
+++ b/system/database/drivers/odbc/odbc_utility.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/pdo/pdo_driver.php b/system/database/drivers/pdo/pdo_driver.php
index 457cf71..8fdfd58 100644
--- a/system/database/drivers/pdo/pdo_driver.php
+++ b/system/database/drivers/pdo/pdo_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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.1.0
@@ -46,9 +46,10 @@
 
 	// the character used to excape - not necessary for PDO
 	var $_escape_char = '';
+
+	// clause and character used for LIKE escape sequences
 	var $_like_escape_str;
 	var $_like_escape_chr;
-	
 
 	/**
 	 * The syntax to count rows is slightly different across different
@@ -57,29 +58,36 @@
 	 */
 	var $_count_string = "SELECT COUNT(*) AS ";
 	var $_random_keyword;
-	
+
+	// need to track the pdo DSN, driver and options
+	var $dsn;
+	var $pdodriver;
 	var $options = array();
 
 	function __construct($params)
 	{
 		parent::__construct($params);
-		
+
+		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.
+			$this->pdodriver = end($match);
+		}
+		else
+		{
+			// Try to build a complete DSN string from params
+			$this->_connect_string($params);
+		}
+
 		// clause and character used for LIKE escape sequences
-		if (strpos($this->hostname, 'mysql') !== FALSE)
+		// this one depends on the driver being used
+		if ($this->pdodriver == 'mysql')
 		{
 			$this->_like_escape_str = '';
 			$this->_like_escape_chr = '';
-			
-			//Prior to this version, the charset can't be set in the dsn
-			if(is_php('5.3.6'))
-			{
-				$this->hostname .= ";charset={$this->char_set}";
-			}
-			
-			//Set the charset with the connection options
-			$this->options['PDO::MYSQL_ATTR_INIT_COMMAND'] = "SET NAMES {$this->char_set}";
 		}
-		else if (strpos($this->hostname, 'odbc') !== FALSE)
+		elseif ($this->pdodriver == 'odbc')
 		{
 			$this->_like_escape_str = " {escape '%s'} ";
 			$this->_like_escape_chr = '!';
@@ -90,17 +98,97 @@
 			$this->_like_escape_chr = '!';
 		}
 		
-		if (strpos($this->hostname, 'sqlite') === FALSE)
-		{
-			$this->hostname .= ";dbname=".$this->database;
-		}
-		
-		$this->trans_enabled = FALSE;
-
+		$this->trans_enabled   = FALSE;
 		$this->_random_keyword = ' RND('.time().')'; // database specific random keyword
 	}
 
 	/**
+	 * Connection String
+	 *
+	 * @access	private
+	 * @param	array
+	 * @return	void
+	 */
+	function _connect_string($params)
+	{
+		if (strpos($this->hostname, ':'))
+		{
+			// hostname generally would have this prototype
+			// $db['hostname'] = 'pdodriver:host(/Server(/DSN))=hostname(/DSN);';
+			// We need to get the prefix (pdodriver used by PDO).
+			$dsnarray = explode(':', $this->hostname);
+			$this->pdodriver = $dsnarray[0];
+
+			// End dsn with a semicolon for extra backward compability
+			// if database property was not empty.
+			if ( ! empty($this->database))
+			{
+				$this->dsn .= rtrim($this->hostname, ';').';';
+			}
+		}
+		else
+		{
+			// Invalid DSN, display an error
+			if ( ! array_key_exists('pdodriver', $params))
+			{
+				show_error('Invalid DB Connection String for PDO');
+			}
+
+			// Assuming that the following DSN string format is used:
+			// $dsn = 'pdo://username:password@hostname:port/database?pdodriver=pgsql';
+			$this->dsn = $this->pdodriver.':';
+
+			// Add hostname to the DSN for databases that need it
+			if ( ! empty($this->hostname) 
+				&& strpos($this->hostname, ':') === FALSE
+				&& in_array($this->pdodriver, array('informix', 'mysql', 'pgsql', 'sybase', 'mssql', 'dblib', 'cubrid')))
+			{
+			    $this->dsn .= 'host='.$this->hostname.';';
+			}
+
+			// Add a port to the DSN for databases that can use it
+			if ( ! empty($this->port) && in_array($this->pdodriver, array('informix', 'mysql', 'pgsql', 'ibm', 'cubrid')))
+			{
+			    $this->dsn .= 'port='.$this->port.';';
+			}
+		}
+
+		// Add the database name to the DSN, if needed
+	    if (stripos($this->dsn, 'dbname') === FALSE 
+	       && in_array($this->pdodriver, array('4D', 'pgsql', 'mysql', 'firebird', 'sybase', 'mssql', 'dblib', 'cubrid')))
+	    {
+	        $this->dsn .= 'dbname='.$this->database.';';
+	    }
+	    elseif (stripos($this->dsn, 'database') === FALSE && in_array($this->pdodriver, array('ibm', 'sqlsrv')))
+	    {
+	    	if (stripos($this->dsn, 'dsn') === FALSE)
+	    	{
+		        $this->dsn .= 'database='.$this->database.';';
+	    	}
+	    }
+	    elseif ($this->pdodriver === 'sqlite' && $this->dsn === 'sqlite:')
+	    {
+	        if ($this->database !== ':memory')
+	        {
+	            if ( ! file_exists($this->database))
+	            {
+	                show_error('Invalid DB Connection string for PDO SQLite');
+	            }
+
+	            $this->dsn .= (strpos($this->database, DIRECTORY_SEPARATOR) !== 0) ? DIRECTORY_SEPARATOR : '';
+	        }
+
+	        $this->dsn .= $this->database;
+	    }
+
+	    // Add charset to the DSN, if needed
+	    if ( ! empty($this->char_set) && in_array($this->pdodriver, array('4D', 'mysql', 'sybase', 'mssql', 'dblib', 'oci')))
+	    {
+	        $this->dsn .= 'charset='.$this->char_set.';';
+	    }
+	}
+
+	/**
 	 * Non-persistent database connection
 	 *
 	 * @access	private called by the base class
@@ -108,9 +196,9 @@
 	 */
 	function db_connect()
 	{
-		$this->options['PDO::ATTR_ERRMODE'] = PDO::ERRMODE_SILENT;
-		
-		return new PDO($this->hostname, $this->username, $this->password, $this->options);
+		$this->options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_SILENT;
+
+		return $this->pdo_connect();
 	}
 
 	// --------------------------------------------------------------------
@@ -123,10 +211,44 @@
 	 */
 	function db_pconnect()
 	{
-		$this->options['PDO::ATTR_ERRMODE'] = PDO::ERRMODE_SILENT;
-		$this->options['PDO::ATTR_PERSISTENT'] = TRUE;
+		$this->options[PDO::ATTR_ERRMODE]    = PDO::ERRMODE_SILENT;
+		$this->options[PDO::ATTR_PERSISTENT] = TRUE;
 	
-		return new PDO($this->hostname, $this->username, $this->password, $this->options);
+		return $this->pdo_connect();
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * PDO connection
+	 *
+	 * @access	private called by the PDO driver class
+	 * @return	resource
+	 */
+	function pdo_connect()
+	{
+		// Refer : http://php.net/manual/en/ref.pdo-mysql.connection.php
+		if ($this->pdodriver == 'mysql' && is_php('5.3.6'))
+		{
+			$this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES $this->char_set COLLATE '$this->dbcollat'";
+		}
+
+		// Connecting...
+		try 
+		{
+			$db = new PDO($this->dsn, $this->username, $this->password, $this->options);
+		} 
+		catch (PDOException $e) 
+		{
+			if ($this->db_debug && empty($this->failover))
+			{
+				$this->display_error($e->getMessage(), '', TRUE);
+			}
+
+			return FALSE;
+		}
+
+		return $db;
 	}
 
 	// --------------------------------------------------------------------
@@ -146,6 +268,7 @@
 		{
 			return $this->db->display_error('db_unsuported_feature');
 		}
+
 		return FALSE;
 	}
 
@@ -166,30 +289,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Set client character set
+	 * Database version number
 	 *
-	 * @access	public
-	 * @param	string
-	 * @param	string
-	 * @return	resource
-	 */
-	function db_set_charset($charset, $collation)
-	{
-		// @todo - add support if needed
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Version number query string
-	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function _version()
+	public function version()
 	{
-		return $this->conn_id->getAttribute(PDO::ATTR_CLIENT_VERSION);
+		return isset($this->data_cache['version'])
+			? $this->data_cache['version']
+			: $this->data_cache['version'] = $this->conn_id->getAttribute(PDO::ATTR_SERVER_VERSION);
 	}
 
 	// --------------------------------------------------------------------
@@ -204,6 +312,7 @@
 	function _execute($sql)
 	{
 		$sql = $this->_prep_query($sql);
+
 		$result_id = $this->conn_id->query($sql);
 		
 		if (is_object($result_id))
@@ -231,6 +340,17 @@
 	 */
 	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;
 	}
 
@@ -285,6 +405,7 @@
 		}
 
 		$ret = $this->conn->commit();
+		
 		return $ret;
 	}
 
@@ -310,6 +431,7 @@
 		}
 
 		$ret = $this->conn_id->rollBack();
+
 		return $ret;
 	}
 
@@ -348,7 +470,9 @@
 		if ($like === TRUE)
 		{
 			$str = str_replace(	array('%', '_', $this->_like_escape_chr),
-								array($this->_like_escape_chr.'%', $this->_like_escape_chr.'_', $this->_like_escape_chr.$this->_like_escape_chr),
+								array($this->_like_escape_chr.'%', 
+								      $this->_like_escape_chr.'_', 
+								      $this->_like_escape_chr.$this->_like_escape_chr),
 								$str);
 		}
 
@@ -372,31 +496,19 @@
 
 	/**
 	 * Insert ID
-	 * 
-	 * @access	public
-	 * @return	integer
+	 *
+	 * @return	int
 	 */
-	function insert_id($name=NULL)
+	public function insert_id($name = NULL)
 	{
-		//Convenience method for postgres insertid
-		if (strpos($this->hostname, 'pgsql') !== FALSE)
+		if ($this->pdodriver === 'pgsql' && $name === NULL && $this->version() >= '8.1')
 		{
-			$v = $this->_version();
-
-			$table	= func_num_args() > 0 ? func_get_arg(0) : NULL;
-
-			if ($table == NULL && $v >= '8.1')
-			{
-				$sql='SELECT LASTVAL() as ins_id';
-			}
-			$query = $this->query($sql);
-			$row = $query->row();
-			return $row->ins_id;
+			$query = $this->query('SELECT LASTVAL() AS ins_id');
+			$query = $query->row();
+			return $query->ins_id;
 		}
-		else
-		{
-			return $this->conn_id->lastInsertId($name);
-		}
+
+		return $this->conn_id->lastInsertId($name);
 	}
 
 	// --------------------------------------------------------------------
@@ -418,7 +530,9 @@
 			return 0;
 		}
 
-		$query = $this->query($this->_count_string . $this->_protect_identifiers('numrows') . " FROM " . $this->_protect_identifiers($table, TRUE, NULL, FALSE));
+		$sql   = $this->_count_string.$this->_protect_identifiers('numrows').' FROM ';
+		$sql  .= $this->_protect_identifiers($table, TRUE, NULL, FALSE);
+		$query = $this->query($sql);
 
 		if ($query->num_rows() == 0)
 		{
@@ -427,6 +541,7 @@
 
 		$row = $query->row();
 		$this->_reset_select();
+
 		return (int) $row->numrows;
 	}
 
@@ -443,12 +558,19 @@
 	 */
 	function _list_tables($prefix_limit = FALSE)
 	{
-		$sql = "SHOW TABLES FROM `".$this->database."`";
+		if ($this->pdodriver == 'pgsql')
+		{
+			// Analog function to show all tables in postgre
+			$sql = "SELECT * FROM information_schema.tables WHERE table_schema = 'public'";
+		}
+		else
+		{
+			$sql = "SHOW TABLES FROM `".$this->database."`";
+		}
 
 		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
+			return FALSE; 
 		}
 
 		return $sql;
@@ -467,7 +589,7 @@
 	 */
 	function _list_columns($table = '')
 	{
-		return "SHOW COLUMNS FROM ".$table;
+		return 'SHOW COLUMNS FROM '.$this->_from_tables($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -483,34 +605,36 @@
 	 */
 	function _field_data($table)
 	{
-		return "SELECT TOP 1 FROM ".$table;
+		return 'SELECT TOP 1 FROM '.$this->_from_tables($table);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		$error_array = $this->conn_id->errorInfo();
-		return $error_array[2];
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		return $this->conn_id->errorCode();
+		$error = array('code' => '00000', 'message' => '');
+		$pdo_error = $this->conn_id->errorInfo();
+
+		if (empty($pdo_error[0]))
+		{
+			return $error;
+		}
+
+		$error['code'] = isset($pdo_error[1]) ? $pdo_error[0].'/'.$pdo_error[1] : $pdo_error[0];
+		if (isset($pdo_error[2]))
+		{
+			 $error['message'] = $pdo_error[2];
+		}
+
+		return $error;
 	}
 
 	// --------------------------------------------------------------------
@@ -544,8 +668,8 @@
 
 		if (strpos($item, '.') !== FALSE)
 		{
-			$str = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item).$this->_escape_char;
-			
+			$str  = $this->_escape_char.str_replace('.', $this->_escape_char.'.'.$this->_escape_char, $item);
+			$str .= $this->_escape_char;
 		}
 		else
 		{
@@ -575,7 +699,7 @@
 			$tables = array($tables);
 		}
 
-		return (count($tables) == 1) ? $tables[0] : '('.implode(', ', $tables).')';
+		return (count($tables) == 1) ? '`'.$tables[0].'`' : '('.implode(', ', $tables).')';
 	}
 
 	// --------------------------------------------------------------------
@@ -593,7 +717,7 @@
 	 */
 	function _insert($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")";
+		return 'INSERT INTO '.$this->_from_tables($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')';
 	}
 	
 	// --------------------------------------------------------------------
@@ -611,7 +735,7 @@
 	 */
 	function _insert_batch($table, $keys, $values)
 	{
-		return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values);
+		return 'INSERT INTO '.$this->_from_tables($table).' ('.implode(', ', $keys).') VALUES '.implode(', ', $values);
 	}
 
 	// --------------------------------------------------------------------
@@ -636,14 +760,11 @@
 			$valstr[] = $key." = ".$val;
 		}
 
-		$limit = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		$limit   = ( ! $limit) ? '' : ' LIMIT '.$limit;
+		$orderby = (count($orderby) >= 1) ? ' ORDER BY '.implode(', ', $orderby) : '';
 
-		$orderby = (count($orderby) >= 1)?' ORDER BY '.implode(", ", $orderby):'';
-
-		$sql = "UPDATE ".$table." SET ".implode(', ', $valstr);
-
-		$sql .= ($where != '' AND count($where) >=1) ? " WHERE ".implode(" ", $where) : '';
-
+		$sql  = 'UPDATE '.$this->_from_tables($table).' SET '.implode(', ', $valstr);
+		$sql .= ($where != '' && count($where) >= 1) ? ' WHERE '.implode(' ', $where) : '';
 		$sql .= $orderby.$limit;
 
 		return $sql;
@@ -664,8 +785,8 @@
 	 */
 	function _update_batch($table, $values, $index, $where = NULL)
 	{
-		$ids = array();
-		$where = ($where != '' AND count($where) >=1) ? implode(" ", $where).' AND ' : '';
+		$ids   = array();
+		$where = ($where != '' && count($where) >=1) ? implode(" ", $where).' AND ' : '';
 
 		foreach ($values as $key => $val)
 		{
@@ -680,12 +801,13 @@
 			}
 		}
 
-		$sql = "UPDATE ".$table." SET ";
+		$sql   = 'UPDATE '.$this->_from_tables($table).' SET ';
 		$cases = '';
 
 		foreach ($final as $k => $v)
 		{
 			$cases .= $k.' = CASE '."\n";
+
 			foreach ($v as $row)
 			{
 				$cases .= $row."\n";
@@ -695,7 +817,6 @@
 		}
 
 		$sql .= substr($cases, 0, -2);
-
 		$sql .= ' WHERE '.$where.$index.' IN ('.implode(',', $ids).')';
 
 		return $sql;
@@ -739,19 +860,20 @@
 
 		if (count($where) > 0 OR count($like) > 0)
 		{
-			$conditions = "\nWHERE ";
+			$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 '.$this->_from_tables($table).$conditions.$limit;
 	}
 
 	// --------------------------------------------------------------------
@@ -769,27 +891,16 @@
 	 */
 	function _limit($sql, $limit, $offset)
 	{
-		if (strpos($this->hostname, 'cubrid') !== FALSE || strpos($this->hostname, 'sqlite') !== FALSE)
+		if ($this->pdodriver == 'cubrid' OR $this->pdodriver == 'sqlite')
 		{
-			if ($offset == 0)
-			{
-				$offset = '';
-			}
-			else
-			{
-				$offset .= ", ";
-			}
+			$offset = ($offset == 0) ? '' : $offset.', ';
 
-			return $sql."LIMIT ".$offset.$limit;
+			return $sql.'LIMIT '.$offset.$limit;
 		}
 		else
 		{
-			$sql .= "LIMIT ".$limit;
-
-			if ($offset > 0)
-			{
-				$sql .= " OFFSET ".$offset;
-			}
+			$sql .= 'LIMIT '.$limit;
+			$sql .= ($offset > 0) ? ' OFFSET '.$offset : '';
 			
 			return $sql;
 		}
@@ -809,10 +920,7 @@
 		$this->conn_id = null;
 	}
 
-
 }
 
-
-
 /* End of file pdo_driver.php */
-/* Location: ./system/database/drivers/pdo/pdo_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/pdo/pdo_driver.php */
diff --git a/system/database/drivers/pdo/pdo_forge.php b/system/database/drivers/pdo/pdo_forge.php
index bf30665..478b2db 100644
--- a/system/database/drivers/pdo/pdo_forge.php
+++ b/system/database/drivers/pdo/pdo_forge.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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.1.0
@@ -96,7 +96,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)
@@ -111,6 +111,7 @@
 			else
 			{
 				$attributes = array_change_key_case($attributes, CASE_UPPER);
+				$numeric    = array('SERIAL', 'INTEGER');
 
 				$sql .= "\n\t".$this->db->_protect_identifiers($field);
 
@@ -118,7 +119,11 @@
 
 				if (array_key_exists('CONSTRAINT', $attributes))
 				{
-					$sql .= '('.$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)))
+					{
+						$sql .= '('.$attributes['CONSTRAINT'].')';
+					}
 				}
 
 				if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE)
@@ -219,7 +224,7 @@
 	 */
 	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->_protect_identifiers($table)."` $alter_type ".$this->db->_protect_identifiers($column_name);
 
 		// DROP has everything it needs now.
 		if ($alter_type == 'DROP')
@@ -271,7 +276,6 @@
 		return $sql;
 	}
 
-
 }
 
 /* End of file pdo_forge.php */
diff --git a/system/database/drivers/pdo/pdo_result.php b/system/database/drivers/pdo/pdo_result.php
index 559c2ed..c333abc 100644
--- a/system/database/drivers/pdo/pdo_result.php
+++ b/system/database/drivers/pdo/pdo_result.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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.1.0
@@ -39,6 +39,16 @@
 class CI_DB_pdo_result extends CI_DB_result {
 
 	/**
+	 * @var bool  Hold the flag whether a result handler already fetched before
+	 */
+	protected $is_fetched = FALSE;
+
+	/**
+	 * @var mixed Hold the fetched assoc array of a result handler
+	 */
+	protected $result_assoc;
+
+	/**
 	 * Number of rows in the result set
 	 *
 	 * @access	public
@@ -46,7 +56,59 @@
 	 */
 	function num_rows()
 	{
-		return $this->result_id->rowCount();
+		if (empty($this->result_id) OR ! is_object($this->result_id))
+		{
+			// invalid result handler
+			return 0;
+		}
+		elseif (($num_rows = $this->result_id->rowCount()) && $num_rows > 0)
+		{
+			// If rowCount return something, we're done.
+			return $num_rows;
+		}
+
+		// Fetch the result, instead perform another extra query
+		return ($this->is_fetched && is_array($this->result_assoc)) ? count($this->result_assoc) : count($this->result_assoc());
+	}
+
+	/**
+	 * Fetch the result handler
+	 *
+	 * @access	public
+	 * @return	mixed
+	 */
+	function result_assoc()
+	{
+		// If the result already fetched before, use that one
+		if (count($this->result_array) > 0 OR $this->is_fetched)
+		{
+			return $this->result_array();
+		}
+
+		// Define the output
+		$output = array('assoc', 'object');
+
+		// Fetch the result
+		foreach ($output as $type)
+		{
+			// 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;
+			}
+		}
+
+		// Save this as buffer and marked the fetch flag
+		$this->result_array = $this->result_assoc;
+		$this->is_fetched = TRUE;
+
+		return $this->result_assoc;
 	}
 
 	// --------------------------------------------------------------------
@@ -78,6 +140,7 @@
 		{
 			return $this->db->display_error('db_unsuported_feature');
 		}
+		
 		return FALSE;
 	}
 
@@ -110,6 +173,7 @@
 			{
 				return $this->db->display_error('db_unsuported_feature');
 			}
+
 			return FALSE;
 		}
 	}
@@ -178,6 +242,5 @@
 
 }
 
-
 /* End of file pdo_result.php */
 /* Location: ./system/database/drivers/pdo/pdo_result.php */
\ No newline at end of file
diff --git a/system/database/drivers/pdo/pdo_utility.php b/system/database/drivers/pdo/pdo_utility.php
index 90b46af..971ec88 100644
--- a/system/database/drivers/pdo/pdo_utility.php
+++ b/system/database/drivers/pdo/pdo_utility.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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.1.0
diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php
index 50f096b..df0f50d 100644
--- a/system/database/drivers/postgre/postgre_driver.php
+++ b/system/database/drivers/postgre/postgre_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -149,28 +149,41 @@
 	/**
 	 * Set client character set
 	 *
-	 * @access	public
-	 * @param	string
-	 * @param	string
-	 * @return	resource
+	 * @param       string
+	 * @return      bool
 	 */
-	function db_set_charset($charset, $collation)
+	protected function _db_set_charset($charset)
 	{
-		// @todo - add support if needed
-		return TRUE;
+		return (pg_set_client_encoding($this->conn_id, $charset) === 0);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Version number query string
+	 * Database version number
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function _version()
+	public function version()
 	{
-		return "SELECT version() AS ver";
+		if (isset($this->data_cache['version']))
+		{
+			return $this->data_cache['version'];
+		}
+
+		if (($pg_version = pg_version($this->conn_id)) === FALSE)
+		{
+			return FALSE;
+		}
+
+		/* If PHP was compiled with PostgreSQL lib versions earlier
+		 * than 7.4, pg_version() won't return the server version
+		 * and so we'll have to fall back to running a query in
+		 * order to get it.
+		 */
+		return isset($pg_version['server'])
+			? $this->data_cache['version'] = $pg_version['server']
+			: parent::version();
 	}
 
 	// --------------------------------------------------------------------
@@ -209,18 +222,12 @@
 	/**
 	 * Begin Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_begin($test_mode = FALSE)
+	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;
 		}
@@ -228,9 +235,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);
 
-		return @pg_exec($this->conn_id, "begin");
+		return @pg_query($this->conn_id, 'BEGIN');
 	}
 
 	// --------------------------------------------------------------------
@@ -238,23 +245,17 @@
 	/**
 	 * Commit Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_commit()
+	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;
 		}
 
-		return @pg_exec($this->conn_id, "commit");
+		return @pg_query($this->conn_id, 'COMMIT');
 	}
 
 	// --------------------------------------------------------------------
@@ -262,23 +263,17 @@
 	/**
 	 * Rollback Transaction
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function trans_rollback()
+	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;
 		}
 
-		return @pg_exec($this->conn_id, "rollback");
+		return @pg_query($this->conn_id, 'ROLLBACK');
 	}
 
 	// --------------------------------------------------------------------
@@ -339,8 +334,7 @@
 	 */
 	function insert_id()
 	{
-		$v = $this->_version();
-		$v = $v['server'];
+		$v = $this->version();
 
 		$table	= func_num_args() > 0 ? func_get_arg(0) : NULL;
 		$column	= func_num_args() > 1 ? func_get_arg(1) : NULL;
@@ -459,27 +453,16 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		return pg_last_error($this->conn_id);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		return '';
+		return array('code' => '', 'message' => pg_last_error($this->conn_id));
 	}
 
 	// --------------------------------------------------------------------
@@ -712,4 +695,4 @@
 
 
 /* End of file postgre_driver.php */
-/* Location: ./system/database/drivers/postgre/postgre_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/postgre/postgre_driver.php */
diff --git a/system/database/drivers/postgre/postgre_forge.php b/system/database/drivers/postgre/postgre_forge.php
index f86ba2d..756fd34 100644
--- a/system/database/drivers/postgre/postgre_forge.php
+++ b/system/database/drivers/postgre/postgre_forge.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -63,32 +63,16 @@
 	}
 
 	// --------------------------------------------------------------------
-
+	
 	/**
-	 * Create Table
+	 * Process Fields
 	 *
-	 * @access	private
-	 * @param	string	the table name
-	 * @param	array	the fields
-	 * @param	mixed	primary key(s)
-	 * @param	mixed	key(s)
-	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
-	 * @return	bool
+	 * @param	mixed	the fields
+	 * @return	string
 	 */
-	function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists)
+	function _process_fields($fields, $primary_keys=array())
 	{
-		$sql = 'CREATE TABLE ';
-
-		if ($if_not_exists === TRUE)
-		{
-			// PostgreSQL doesn't support IF NOT EXISTS syntax so we check if table exists manually
-			if ($this->db->table_exists($table))
-			{
-				return TRUE;
-			}
-		}
-
-		$sql .= $this->db->_escape_identifiers($table)." (";
+		$sql = '';
 		$current_field_count = 0;
 
 		foreach ($fields as $field=>$attributes)
@@ -184,6 +168,38 @@
 				$sql .= ',';
 			}
 		}
+		
+		return $sql;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
+	 * Create Table
+	 *
+	 * @access	private
+	 * @param	string	the table name
+	 * @param	array	the fields
+	 * @param	mixed	primary key(s)
+	 * @param	mixed	key(s)
+	 * @param	boolean	should 'IF NOT EXISTS' be added to the SQL
+	 * @return	bool
+	 */
+	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 ($this->db->table_exists($table))
+			{
+				return TRUE;
+			}
+		}
+
+		$sql .= $this->db->_escape_identifiers($table)." (";
+		$sql .= $this->_process_fields($fields, $primary_keys);
 
 		if (count($primary_keys) > 0)
 		{
@@ -249,40 +265,25 @@
 	 * @param	string	the field after which we should add the new field
 	 * @return	object
 	 */
-	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);
+ 	function _alter_table($alter_type, $table, $fields, $after_field = '')
+ 	{
+ 		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ";
 
-		// DROP has everything it needs now.
-		if ($alter_type == 'DROP')
-		{
-			return $sql;
-		}
+ 		// DROP has everything it needs now.
+ 		if ($alter_type == 'DROP')
+ 		{
+ 			return $sql.$this->db->_protect_identifiers($fields);
+ 		}
 
-		$sql .= " $column_definition";
+ 		$sql .= $this->_process_fields($fields);
 
-		if ($default_value != '')
-		{
-			$sql .= " DEFAULT \"$default_value\"";
-		}
+ 		if ($after_field != '')
+ 		{
+ 			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
+ 		}
 
-		if ($null === NULL)
-		{
-			$sql .= ' NULL';
-		}
-		else
-		{
-			$sql .= ' NOT NULL';
-		}
-
-		if ($after_field != '')
-		{
-			$sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field);
-		}
-
-		return $sql;
-
-	}
+ 		return $sql;
+ 	}
 
 	// --------------------------------------------------------------------
 
@@ -301,8 +302,6 @@
 		$sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name);
 		return $sql;
 	}
-
-
 }
 
 /* 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 808e8bf..9161bf9 100644
--- a/system/database/drivers/postgre/postgre_result.php
+++ b/system/database/drivers/postgre/postgre_result.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/postgre/postgre_utility.php b/system/database/drivers/postgre/postgre_utility.php
index f81f857..c426b36 100644
--- a/system/database/drivers/postgre/postgre_utility.php
+++ b/system/database/drivers/postgre/postgre_utility.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Postgre Utility Class
  *
@@ -39,12 +37,11 @@
 	/**
 	 * List databases
 	 *
-	 * @access	private
-	 * @return	bool
+	 * @return	string
 	 */
-	function _list_databases()
+	public function _list_databases()
 	{
-		return "SELECT datname FROM pg_database";
+		return 'SELECT datname FROM pg_database';
 	}
 
 	// --------------------------------------------------------------------
@@ -52,15 +49,12 @@
 	/**
 	 * Optimize table query
 	 *
-	 * Is table optimization supported in Postgre?
-	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	string
 	 */
-	function _optimize_table($table)
+	public function _optimize_table($table)
 	{
-		return FALSE;
+		return 'REINDEX TABLE '.$this->db->protect_identifiers($table);
 	}
 
 	// --------------------------------------------------------------------
@@ -68,13 +62,10 @@
 	/**
 	 * Repair table query
 	 *
-	 * Are table repairs supported in Postgre?
-	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	bool
 	 */
-	function _repair_table($table)
+	public function _repair_table($table)
 	{
 		return FALSE;
 	}
@@ -84,7 +75,6 @@
 	/**
 	 * Postgre Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
@@ -95,6 +85,5 @@
 	}
 }
 
-
 /* End of file postgre_utility.php */
-/* Location: ./system/database/drivers/postgre/postgre_utility.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/postgre/postgre_utility.php */
diff --git a/system/database/drivers/sqlite/sqlite_driver.php b/system/database/drivers/sqlite/sqlite_driver.php
index a6257cb..3eaec94 100644
--- a/system/database/drivers/sqlite/sqlite_driver.php
+++ b/system/database/drivers/sqlite/sqlite_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -141,30 +141,15 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * Set client character set
+	 * Database version number
 	 *
-	 * @access	public
-	 * @param	string
-	 * @param	string
-	 * @return	resource
-	 */
-	function db_set_charset($charset, $collation)
-	{
-		// @todo - add support if needed
-		return TRUE;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Version number query string
-	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function _version()
+	public function version()
 	{
-		return sqlite_libversion();
+		return isset($this->data_cache['version'])
+			? $this->data_cache['version']
+			: $this->data_cache['version'] = sqlite_libversion();
 	}
 
 	// --------------------------------------------------------------------
@@ -428,27 +413,18 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		return sqlite_error_string(sqlite_last_error($this->conn_id));
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		return sqlite_last_error($this->conn_id);
+		$error = array('code' => sqlite_last_error($this->conn_id));
+		$error['message'] = sqlite_error_string($error['code']);
+		return $error;
 	}
 
 	// --------------------------------------------------------------------
@@ -667,4 +643,4 @@
 
 
 /* End of file sqlite_driver.php */
-/* Location: ./system/database/drivers/sqlite/sqlite_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/sqlite/sqlite_driver.php */
diff --git a/system/database/drivers/sqlite/sqlite_forge.php b/system/database/drivers/sqlite/sqlite_forge.php
index 96a5e0e..fd0f3eb 100644
--- a/system/database/drivers/sqlite/sqlite_forge.php
+++ b/system/database/drivers/sqlite/sqlite_forge.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -89,7 +89,7 @@
 		$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)
+		if ($if_not_exists === TRUE && version_compare($this->db->version(), '3.3.0', '>=') === TRUE)
 		{
 			$sql .= 'IF NOT EXISTS ';
 		}
@@ -274,4 +274,4 @@
 }
 
 /* End of file sqlite_forge.php */
-/* Location: ./system/database/drivers/sqlite/sqlite_forge.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/sqlite/sqlite_forge.php */
diff --git a/system/database/drivers/sqlite/sqlite_result.php b/system/database/drivers/sqlite/sqlite_result.php
index 2bbd1db..74c0dc5 100644
--- a/system/database/drivers/sqlite/sqlite_result.php
+++ b/system/database/drivers/sqlite/sqlite_result.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/sqlite/sqlite_utility.php b/system/database/drivers/sqlite/sqlite_utility.php
index c9914f2..8fefcd9 100644
--- a/system/database/drivers/sqlite/sqlite_utility.php
+++ b/system/database/drivers/sqlite/sqlite_utility.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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 Utility Class
  *
@@ -40,20 +38,15 @@
 	 * 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
+	 * 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
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	function _list_databases()
+	public function _list_databases()
 	{
-		if ($this->db_debug)
-		{
-			return $this->db->display_error('db_unsuported_feature');
-		}
-		return array();
+		return ($this->db_debug) ? $this->db->display_error('db_unsuported_feature') : FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -61,14 +54,12 @@
 	/**
 	 * Optimize table query
 	 *
-	 * Is optimization even supported in SQLite?
-	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	bool
 	 */
-	function _optimize_table($table)
+	public function _optimize_table($table)
 	{
+		// Not supported
 		return FALSE;
 	}
 
@@ -77,14 +68,12 @@
 	/**
 	 * Repair table query
 	 *
-	 * Are table repairs even supported in SQLite?
-	 *
-	 * @access	private
 	 * @param	string	the table name
-	 * @return	object
+	 * @return	bool
 	 */
-	function _repair_table($table)
+	public function _repair_table($table)
 	{
+		// Not supported
 		return FALSE;
 	}
 
@@ -93,16 +82,16 @@
 	/**
 	 * SQLite Export
 	 *
-	 * @access	private
 	 * @param	array	Preferences
 	 * @return	mixed
 	 */
-	function _backup($params = array())
+	public function _backup($params = array())
 	{
 		// Currently unsupported
 		return $this->db->display_error('db_unsuported_feature');
 	}
+
 }
 
 /* End of file sqlite_utility.php */
-/* Location: ./system/database/drivers/sqlite/sqlite_utility.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/sqlite/sqlite_utility.php */
diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php
index 340cd3a..5c90cb4 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_driver.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -122,28 +122,23 @@
 	/**
 	 * Select the database
 	 *
-	 * @access	private called by the base class
-	 * @return	resource
+	 * @param	string	database name
+	 * @return	bool
 	 */
-	function db_select()
+	public function db_select($database = '')
 	{
-		return $this->_execute('USE ' . $this->database);
-	}
+		if ($database === '')
+		{
+			$database = $this->database;
+		}
 
-	// --------------------------------------------------------------------
+		if ($this->_execute('USE '.$database))
+		{
+			$this->database = $database;
+			return TRUE;
+		}
 
-	/**
-	 * Set client character set
-	 *
-	 * @access	public
-	 * @param	string
-	 * @param	string
-	 * @return	resource
-	 */
-	function db_set_charset($charset, $collation)
-	{
-		// @todo - add support if needed
-		return TRUE;
+		return FALSE;
 	}
 
 	// --------------------------------------------------------------------
@@ -322,15 +317,23 @@
 	// --------------------------------------------------------------------
 
 	/**
-	* Version number query string
-	*
-	* @access public
-	* @return string
-	*/
-	function _version()
+	 * Database version number
+	 *
+	 * @return	string
+	 */
+	public function version()
 	{
-		$info = sqlsrv_server_info($this->conn_id);
-		return sprintf("select '%s' as ver", $info['SQLServerVersion']);
+		if (isset($this->data_cache['version']))
+		{
+			return $this->data_cache['version'];
+		}
+
+		if (($info = sqlsrv_server_info($this->conn_id)) === FALSE)
+		{
+			return FALSE;
+		}
+
+		return $this->data_cache['version'] = $info['SQLServerVersion'];
 	}
 
 	// --------------------------------------------------------------------
@@ -411,29 +414,39 @@
 	// --------------------------------------------------------------------
 
 	/**
-	 * The error message string
+	 * Error
 	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _error_message()
-	{
-		$error = array_shift(sqlsrv_errors());
-		return !empty($error['message']) ? $error['message'] : null;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * The error message number
+	 * Returns an array containing code and message of the last
+	 * database error that has occured.
 	 *
-	 * @access	private
-	 * @return	integer
+	 * @return	array
 	 */
-	function _error_number()
+	public function error()
 	{
-		$error = array_shift(sqlsrv_errors());
-		return isset($error['SQLSTATE']) ? $error['SQLSTATE'] : null;
+		$error = array('code' => '00000', 'message' => '');
+		$sqlsrv_errors = sqlsrv_errors(SQLSRV_ERR_ERRORS);
+
+		if ( ! is_array($sqlsrv_errors))
+		{
+			return $error;
+		}
+
+		$sqlsrv_error = array_shift($sqlsrv_errors);
+		if (isset($sqlsrv_error['SQLSTATE']))
+		{
+			$error['code'] = isset($sqlsrv_error['code']) ? $sqlsrv_error['SQLSTATE'].'/'.$sqlsrv_error['code'] : $sqlsrv_error['SQLSTATE'];
+		}
+		elseif (isset($sqlsrv_error['code']))
+		{
+			$error['code'] = $sqlsrv_error['code'];
+		}
+
+		if (isset($sqlsrv_error['message']))
+		{
+			$error['message'] = $sqlsrv_error['message'];
+		}
+
+		return $error;
 	}
 
 	// --------------------------------------------------------------------
@@ -608,4 +621,4 @@
 
 
 /* End of file mssql_driver.php */
-/* Location: ./system/database/drivers/mssql/mssql_driver.php */
\ No newline at end of file
+/* Location: ./system/database/drivers/mssql/mssql_driver.php */
diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php
index 4fa0596..2a77669 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_forge.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php
index 38aaec7..1ee19c2 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_result.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_result.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php
index f58b5bd..e96df96 100644
--- a/system/database/drivers/sqlsrv/sqlsrv_utility.php
+++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php
index 6b8695c..c46c4d1 100644
--- a/system/helpers/array_helper.php
+++ b/system/helpers/array_helper.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/helpers/captcha_helper.php b/system/helpers/captcha_helper.php
index 0fed819..668b034 100644
--- a/system/helpers/captcha_helper.php
+++ b/system/helpers/captcha_helper.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
index a4c1e49..7b439c4 100644
--- a/system/helpers/cookie_helper.php
+++ b/system/helpers/cookie_helper.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
index b0d79be..d061b4b 100644
--- a/system/helpers/date_helper.php
+++ b/system/helpers/date_helper.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
index cb37446..be65b38 100644
--- a/system/helpers/directory_helper.php
+++ b/system/helpers/directory_helper.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php
index 5f5d1aa..a8c59c2 100644
--- a/system/helpers/download_helper.php
+++ b/system/helpers/download_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Download Helpers
  *
@@ -47,73 +45,72 @@
  * @access	public
  * @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'))
 {
-	function force_download($filename = '', $data = '')
+	function force_download($filename = '', $data = '', $set_mime = FALSE)
 	{
 		if ($filename == '' OR $data == '')
 		{
 			return FALSE;
 		}
 
-		// Try to determine if the filename includes a file extension.
-		// We need it in order to set the MIME type
-		if (FALSE === strpos($filename, '.'))
-		{
-			return FALSE;
-		}
+		// Set the default MIME type to send
+		$mime = 'application/octet-stream';
 
-		// Grab the file extension
-		$x = explode('.', $filename);
-		$extension = end($x);
+		if ($set_mime === TRUE)
+		{
+			/* If we're going to detect the MIME type,
+			 * we'll need a file extension.
+			 */
+			if (FALSE === strpos($filename, '.'))
+			{
+				return FALSE;
+			}
 
-		// Load the mime types
-		if (defined('ENVIRONMENT') AND 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');
-		}
+			$extension = explode('.', $filename);
+			$extension = end($extension);
 
-		// Set a default mime if we can't find it
-		if ( ! isset($mimes[$extension]))
-		{
-			$mime = 'application/octet-stream';
-		}
-		else
-		{
-			$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
+			// 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');
+			}
+
+			// Only change the default MIME if we can find one
+			if (isset($mimes[$extension]))
+			{
+				$mime = is_array($mimes[$extension]) ? $mimes[$extension][0] : $mimes[$extension];
+			}
 		}
 
 		// Generate the server headers
-		if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
+		header('Content-Type: "'.$mime.'"');
+		header('Content-Disposition: attachment; filename="'.$filename.'"');
+		header('Expires: 0');
+		header('Content-Transfer-Encoding: binary');
+		header('Content-Length: '.strlen($data));
+
+		// Internet Explorer-specific headers
+		if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE)
 		{
-			header('Content-Type: "'.$mime.'"');
-			header('Content-Disposition: attachment; filename="'.$filename.'"');
-			header('Expires: 0');
 			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
-			header("Content-Transfer-Encoding: binary");
 			header('Pragma: public');
-			header("Content-Length: ".strlen($data));
 		}
 		else
 		{
-			header('Content-Type: "'.$mime.'"');
-			header('Content-Disposition: attachment; filename="'.$filename.'"');
-			header("Content-Transfer-Encoding: binary");
-			header('Expires: 0');
 			header('Pragma: no-cache');
-			header("Content-Length: ".strlen($data));
 		}
 
 		exit($data);
 	}
 }
 
-
 /* End of file download_helper.php */
-/* Location: ./system/helpers/download_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/download_helper.php */
diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php
index 22099e5..f184031 100644
--- a/system/helpers/email_helper.php
+++ b/system/helpers/email_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -49,7 +49,7 @@
 {
 	function valid_email($address)
 	{
-		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;
+		return (bool) preg_match('/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix', $address);
 	}
 }
 
@@ -69,6 +69,5 @@
 	}
 }
 
-
 /* End of file email_helper.php */
-/* Location: ./system/helpers/email_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/email_helper.php */
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
index 5b50853..2d4b10e 100644
--- a/system/helpers/file_helper.php
+++ b/system/helpers/file_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -142,15 +142,11 @@
 
 		while (FALSE !== ($filename = @readdir($current_dir)))
 		{
-			if ($filename != "." and $filename != "..")
+			if ($filename !== '.' and $filename !== '..')
 			{
-				if (is_dir($path.DIRECTORY_SEPARATOR.$filename))
+				if (is_dir($path.DIRECTORY_SEPARATOR.$filename) && $filename[0] !== '.')
 				{
-					// Ignore empty folders
-					if (substr($filename, 0, 1) != '.')
-					{
-						delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1);
-					}
+					delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1);
 				}
 				else
 				{
@@ -200,21 +196,21 @@
 
 			while (FALSE !== ($file = readdir($fp)))
 			{
-				if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)
+				if (@is_dir($source_dir.$file) && $file[0] !== '.')
 				{
 					get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
 				}
-				elseif (strncmp($file, '.', 1) !== 0)
+				elseif ($file[0] !== '.')
 				{
 					$_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;
 				}
 			}
+			closedir($fp);
+
 			return $_filedata;
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return FALSE;
 	}
 }
 
@@ -253,23 +249,22 @@
 			// foreach (scandir($source_dir, 1) as $file) // In addition to being PHP5+, scandir() is simply not as fast
 			while (FALSE !== ($file = readdir($fp)))
 			{
-				if (@is_dir($source_dir.$file) AND strncmp($file, '.', 1) !== 0 AND $top_level_only === FALSE)
+				if (@is_dir($source_dir.$file) && $file[0] !== '.' && $top_level_only === FALSE)
 				{
 					get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $top_level_only, TRUE);
 				}
-				elseif (strncmp($file, '.', 1) !== 0)
+				elseif ($file[0] !== '.')
 				{
 					$_filedata[$file] = get_file_info($source_dir.$file);
 					$_filedata[$file]['relative_path'] = $relative_path;
 				}
 			}
+			closedir($fp);
 
 			return $_filedata;
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return FALSE;
 	}
 }
 
@@ -364,7 +359,7 @@
 
 		if ( ! is_array($mimes))
 		{
-			if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
+			if (defined('ENVIRONMENT') && is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
 			{
 				include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
 			}
@@ -391,10 +386,8 @@
 				return $mimes[$extension];
 			}
 		}
-		else
-		{
-			return FALSE;
-		}
+
+		return FALSE;
 	}
 }
 
@@ -414,31 +407,31 @@
 {
 	function symbolic_permissions($perms)
 	{
-		if (($perms & 0xC000) == 0xC000)
+		if (($perms & 0xC000) === 0xC000)
 		{
 			$symbolic = 's'; // Socket
 		}
-		elseif (($perms & 0xA000) == 0xA000)
+		elseif (($perms & 0xA000) === 0xA000)
 		{
 			$symbolic = 'l'; // Symbolic Link
 		}
-		elseif (($perms & 0x8000) == 0x8000)
+		elseif (($perms & 0x8000) === 0x8000)
 		{
 			$symbolic = '-'; // Regular
 		}
-		elseif (($perms & 0x6000) == 0x6000)
+		elseif (($perms & 0x6000) === 0x6000)
 		{
 			$symbolic = 'b'; // Block special
 		}
-		elseif (($perms & 0x4000) == 0x4000)
+		elseif (($perms & 0x4000) === 0x4000)
 		{
 			$symbolic = 'd'; // Directory
 		}
-		elseif (($perms & 0x2000) == 0x2000)
+		elseif (($perms & 0x2000) === 0x2000)
 		{
 			$symbolic = 'c'; // Character special
 		}
-		elseif (($perms & 0x1000) == 0x1000)
+		elseif (($perms & 0x1000) === 0x1000)
 		{
 			$symbolic = 'p'; // FIFO pipe
 		}
@@ -448,19 +441,19 @@
 		}
 
 		// Owner
-		$symbolic .= (($perms & 0x0100) ? 'r' : '-');
-		$symbolic .= (($perms & 0x0080) ? 'w' : '-');
-		$symbolic .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));
+		$symbolic .= (($perms & 0x0100) ? 'r' : '-')
+			. (($perms & 0x0080) ? 'w' : '-')
+			. (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));
 
 		// Group
-		$symbolic .= (($perms & 0x0020) ? 'r' : '-');
-		$symbolic .= (($perms & 0x0010) ? 'w' : '-');
-		$symbolic .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));
+		$symbolic .= (($perms & 0x0020) ? 'r' : '-')
+			. (($perms & 0x0010) ? 'w' : '-')
+			. (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));
 
 		// World
-		$symbolic .= (($perms & 0x0004) ? 'r' : '-');
-		$symbolic .= (($perms & 0x0002) ? 'w' : '-');
-		$symbolic .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));
+		$symbolic .= (($perms & 0x0004) ? 'r' : '-')
+			. (($perms & 0x0002) ? 'w' : '-')
+			. (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));
 
 		return $symbolic;
 	}
@@ -486,6 +479,5 @@
 	}
 }
 
-
 /* End of file file_helper.php */
-/* Location: ./system/helpers/file_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/file_helper.php */
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
index 347e8be..6efef23 100644
--- a/system/helpers/form_helper.php
+++ b/system/helpers/form_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,11 +18,10 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
 // ------------------------------------------------------------------------
@@ -70,14 +69,10 @@
 		// If no action is provided then set to the current url
 		$action OR $action = $CI->config->site_url($CI->uri->uri_string());
 
-		$form = '<form action="'.$action.'"';
-
-		$form .= _attributes_to_string($attributes, TRUE);
-
-		$form .= '>';
+		$form = '<form action="'.$action.'"'._attributes_to_string($attributes, TRUE).">\n";
 
 		// Add CSRF field if enabled, but leave it out for GET requests and requests to external websites	
-		if ($CI->config->item('csrf_protection') === TRUE AND ! (strpos($action, $CI->config->site_url()) === FALSE OR strpos($form, 'method="get"')))	
+		if ($CI->config->item('csrf_protection') === TRUE AND ! (strpos($action, $CI->config->base_url()) === FALSE OR strpos($form, 'method="get"')))	
 		{
 			$hidden[$CI->security->get_csrf_token_name()] = $CI->security->get_csrf_hash();
 		}
@@ -156,7 +151,7 @@
 
 		if ( ! is_array($value))
 		{
-			$form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value, $name).'" />'."\n";
+			$form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value, $name)."\" />\n";
 		}
 		else
 		{
@@ -188,7 +183,7 @@
 	{
 		$defaults = array('type' => 'text', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
 
-		return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
 
@@ -274,7 +269,7 @@
 		}
 
 		$name = (is_array($data)) ? $data['name'] : $data;
-		return "<textarea "._parse_form_attributes($data, $defaults).$extra.">".form_prep($val, $name)."</textarea>";
+		return '<textarea '._parse_form_attributes($data, $defaults).$extra.'>'.form_prep($val, $name)."</textarea>\n";
 	}
 }
 
@@ -325,13 +320,9 @@
 		}
 
 		// If no selected state was submitted we will attempt to set it automatically
-		if (count($selected) === 0)
+		if (count($selected) === 0 && isset($_POST[$name]))
 		{
-			// If the form name appears in the $_POST array we have a winner!
-			if (isset($_POST[$name]))
-			{
-				$selected = array($_POST[$name]);
-			}
+			$selected = array($_POST[$name]);
 		}
 
 		if ($extra != '') $extra = ' '.$extra;
@@ -346,12 +337,11 @@
 
 			if (is_array($val) && ! empty($val))
 			{
-				$form .= '<optgroup label="'.$key.'">'."\n";
+				$form .= '<optgroup label="'.$key."\">\n";
 
 				foreach ($val as $optgroup_key => $optgroup_val)
 				{
 					$sel = (in_array($optgroup_key, $selected)) ? ' selected="selected"' : '';
-
 					$form .= '<option value="'.$optgroup_key.'"'.$sel.'>'.(string) $optgroup_val."</option>\n";
 				}
 
@@ -359,13 +349,11 @@
 			}
 			else
 			{
-				$sel = (in_array($key, $selected)) ? ' selected="selected"' : '';
-
-				$form .= '<option value="'.$key.'"'.$sel.'>'.(string) $val."</option>\n";
+				$form .= '<option value="'.$key.'"'.(in_array($key, $selected) ? ' selected="selected"' : '').'>'.(string) $val."</option>\n";
 			}
 		}
 
-		$form .= '</select>';
+		$form .= "</select>\n";
 
 		return $form;
 	}
@@ -412,7 +400,7 @@
 			unset($defaults['checked']);
 		}
 
-		return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
 
@@ -458,8 +446,7 @@
 	function form_submit($data = '', $value = '', $extra = '')
 	{
 		$defaults = array('type' => 'submit', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
-
-		return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
 
@@ -479,8 +466,7 @@
 	function form_reset($data = '', $value = '', $extra = '')
 	{
 		$defaults = array('type' => 'reset', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
-
-		return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+		return '<input '._parse_form_attributes($data, $defaults).$extra." />\n";
 	}
 }
 
@@ -500,14 +486,13 @@
 	function form_button($data = '', $content = '', $extra = '')
 	{
 		$defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'type' => 'button');
-
 		if ( is_array($data) AND isset($data['content']))
 		{
 			$content = $data['content'];
 			unset($data['content']); // content is not an attribute
 		}
 
-		return "<button "._parse_form_attributes($data, $defaults).$extra.">".$content."</button>";
+		return '<button '._parse_form_attributes($data, $defaults).$extra.'>'.$content."</button>\n";
 	}
 }
 
@@ -542,9 +527,7 @@
 			}
 		}
 
-		$label .= ">$label_text</label>";
-
-		return $label;
+		return $label .= ">$label_text</label>";
 	}
 }
 
@@ -564,12 +547,7 @@
 {
 	function form_fieldset($legend_text = '', $attributes = array())
 	{
-		$fieldset = "<fieldset";
-
-		$fieldset .= _attributes_to_string($attributes, FALSE);
-
-		$fieldset .= ">\n";
-
+		$fieldset = '<fieldset'._attributes_to_string($attributes, FALSE).">\n";
 		if ($legend_text != '')
 		{
 			$fieldset .= "<legend>$legend_text</legend>\n";
@@ -654,15 +632,13 @@
 		{
 			return $str;
 		}
-		
-		$str = html_escape($str);
 
 		if ($field_name != '')
 		{
 			$prepped_fields[$field_name] = $field_name;
 		}
 
-		return $str;
+		return html_escape($str);
 	}
 }
 
@@ -992,7 +968,7 @@
 				$attributes .= ' accept-charset="'.strtolower(config_item('charset')).'"';
 			}
 
-		return ' '.$attributes;
+			return ' '.$attributes;
 		}
 
 		if (is_object($attributes) AND count($attributes) > 0)
@@ -1043,21 +1019,20 @@
 
 		// We set this as a variable since we're returning by reference.
 		$return = FALSE;
-		
+
 		if (FALSE !== ($object = $CI->load->is_loaded('form_validation')))
 		{
 			if ( ! isset($CI->$object) OR ! is_object($CI->$object))
 			{
 				return $return;
 			}
-			
+
 			return $CI->$object;
 		}
-		
+
 		return $return;
 	}
 }
 
-
 /* End of file form_helper.php */
 /* Location: ./system/helpers/form_helper.php */
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
index b6bb402..72970d9 100644
--- a/system/helpers/html_helper.php
+++ b/system/helpers/html_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -54,8 +54,7 @@
 {
 	function heading($data = '', $h = '1', $attributes = '')
 	{
-		$attributes = ($attributes != '') ? ' '.$attributes : $attributes;
-		return "<h".$h.$attributes.">".$data."</h".$h.">";
+		return '<h'.$h.($attributes != '' ? ' ' : '').$attributes.'>'.$data.'</h'.$h.'>';
 	}
 }
 
@@ -124,7 +123,7 @@
 		}
 
 		// Set the indentation based on the depth
-		$out = str_repeat(" ", $depth);
+		$out = str_repeat(' ', $depth);
 
 		// Were any attributes submitted?  If so generate a string
 		if (is_array($attributes))
@@ -142,7 +141,7 @@
 		}
 
 		// Write the opening list tag
-		$out .= "<".$type.$attributes.">\n";
+		$out .= '<'.$type.$attributes.">\n";
 
 		// Cycle through the list elements.  If an array is
 		// encountered we will recursively call _list()
@@ -152,8 +151,7 @@
 		{
 			$_last_list_item = $key;
 
-			$out .= str_repeat(" ", $depth + 2);
-			$out .= "<li>";
+			$out .= str_repeat(' ', $depth + 2).'<li>';
 
 			if ( ! is_array($val))
 			{
@@ -161,21 +159,14 @@
 			}
 			else
 			{
-				$out .= $_last_list_item."\n";
-				$out .= _list($type, $val, '', $depth + 4);
-				$out .= str_repeat(" ", $depth + 2);
+				$out .= $_last_list_item."\n"._list($type, $val, '', $depth + 4).str_repeat(' ', $depth + 2);
 			}
 
 			$out .= "</li>\n";
 		}
 
-		// Set the indentation for the closing tag
-		$out .= str_repeat(" ", $depth);
-
-		// Write the closing list tag
-		$out .= "</".$type.">\n";
-
-		return $out;
+		// Set the indentation for the closing tag and apply it
+		return $out.str_repeat(' ', $depth).'</'.$type.">\n";
 	}
 }
 
@@ -192,7 +183,7 @@
 {
 	function br($num = 1)
 	{
-		return str_repeat("<br />", $num);
+		return str_repeat('<br />', $num);
 	}
 }
 
@@ -224,10 +215,9 @@
 
 		$img = '<img';
 
-		foreach ($src as $k=>$v)
+		foreach ($src as $k => $v)
 		{
-
-			if ($k == 'src' AND strpos($v, '://') === FALSE)
+			if ($k === 'src' AND strpos($v, '://') === FALSE)
 			{
 				$CI =& get_instance();
 
@@ -246,9 +236,7 @@
 			}
 		}
 
-		$img .= '/>';
-
-		return $img;
+		return $img.'/>';
 	}
 }
 
@@ -290,14 +278,7 @@
 			}
 		}
 
-		if (isset($_doctypes[$type]))
-		{
-			return $_doctypes[$type];
-		}
-		else
-		{
-			return FALSE;
-		}
+		return (isset($_doctypes[$type])) ? $_doctypes[$type] : FALSE;
 	}
 }
 
@@ -322,14 +303,13 @@
 	function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE)
 	{
 		$CI =& get_instance();
-
 		$link = '<link ';
 
 		if (is_array($href))
 		{
-			foreach ($href as $k=>$v)
+			foreach ($href as $k => $v)
 			{
-				if ($k == 'href' AND strpos($v, '://') === FALSE)
+				if ($k === 'href' AND strpos($v, '://') === FALSE)
 				{
 					if ($index_page === TRUE)
 					{
@@ -346,11 +326,11 @@
 				}
 			}
 
-			$link .= "/>";
+			$link .= '/>';
 		}
 		else
 		{
-			if ( strpos($href, '://') !== FALSE)
+			if (strpos($href, '://') !== FALSE)
 			{
 				$link .= 'href="'.$href.'" ';
 			}
@@ -365,21 +345,20 @@
 
 			$link .= 'rel="'.$rel.'" type="'.$type.'" ';
 
-			if ($media	!= '')
+			if ($media != '')
 			{
 				$link .= 'media="'.$media.'" ';
 			}
 
-			if ($title	!= '')
+			if ($title != '')
 			{
 				$link .= 'title="'.$title.'" ';
 			}
 
 			$link .= '/>';
 		}
-		$link .= "\n";
 
-		return $link;
+		return $link."\n";
 	}
 }
 
@@ -439,10 +418,9 @@
 {
 	function nbs($num = 1)
 	{
-		return str_repeat("&nbsp;", $num);
+		return str_repeat('&nbsp;', $num);
 	}
 }
 
-
 /* End of file html_helper.php */
-/* Location: ./system/helpers/html_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/html_helper.php */
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
index 7c50821..02c425b 100644
--- a/system/helpers/inflector_helper.php
+++ b/system/helpers/inflector_helper.php
@@ -1,4 +1,4 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -34,7 +34,7 @@
  * @subpackage	Helpers
  * @category	Helpers
  * @author		EllisLab Dev Team
- * @link		http://codeigniter.com/user_guide/helpers/directory_helper.html
+ * @link		http://codeigniter.com/user_guide/helpers/inflector_helper.html
  */
 
 
@@ -45,7 +45,6 @@
  *
  * Takes a plural word and makes it singular
  *
- * @access	public
  * @param	string
  * @return	str
  */
@@ -55,34 +54,39 @@
 	{
 		$result = strval($str);
 
+		if ( ! is_countable($result))
+		{
+			return $result;
+		}
+		
 		$singular_rules = array(
-			'/(matr)ices$/'			=> '\1ix',
-			'/(vert|ind)ices$/'		=> '\1ex',
-			'/^(ox)en/'				=> '\1',
-			'/(alias)es$/'			=> '\1',
-			'/([octop|vir])i$/'		=> '\1us',
-			'/(cris|ax|test)es$/'	=> '\1is',
-			'/(shoe)s$/'			=> '\1',
-			'/(o)es$/'				=> '\1',
-			'/(bus|campus)es$/'		=> '\1',
-			'/([m|l])ice$/'			=> '\1ouse',
-			'/(x|ch|ss|sh)es$/'		=> '\1',
-			'/(m)ovies$/'			=> '\1\2ovie',
-			'/(s)eries$/'			=> '\1\2eries',
-			'/([^aeiouy]|qu)ies$/'	=> '\1y',
-			'/([lr])ves$/'			=> '\1f',
-			'/(tive)s$/'			=> '\1',
-			'/(hive)s$/'			=> '\1',
-			'/([^f])ves$/'			=> '\1fe',
-			'/(^analy)ses$/'		=> '\1sis',
+			'/(matr)ices$/'         => '\1ix',
+			'/(vert|ind)ices$/'     => '\1ex',
+			'/^(ox)en/'             => '\1',
+			'/(alias)es$/'          => '\1',
+			'/([octop|vir])i$/'     => '\1us',
+			'/(cris|ax|test)es$/'   => '\1is',
+			'/(shoe)s$/'            => '\1',
+			'/(o)es$/'              => '\1',
+			'/(bus|campus)es$/'     => '\1',
+			'/([m|l])ice$/'         => '\1ouse',
+			'/(x|ch|ss|sh)es$/'     => '\1',
+			'/(m)ovies$/'           => '\1\2ovie',
+			'/(s)eries$/'           => '\1\2eries',
+			'/([^aeiouy]|qu)ies$/'  => '\1y',
+			'/([lr])ves$/'          => '\1f',
+			'/(tive)s$/'            => '\1',
+			'/(hive)s$/'            => '\1',
+			'/([^f])ves$/'          => '\1fe',
+			'/(^analy)ses$/'        => '\1sis',
 			'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/' => '\1\2sis',
-			'/([ti])a$/'			=> '\1um',
-			'/(p)eople$/'			=> '\1\2erson',
-			'/(m)en$/'				=> '\1an',
-			'/(s)tatuses$/'			=> '\1\2tatus',
-			'/(c)hildren$/'			=> '\1\2hild',
-			'/(n)ews$/'				=> '\1\2ews',
-			'/([^u])s$/'			=> '\1',
+			'/([ti])a$/'            => '\1um',
+			'/(p)eople$/'           => '\1\2erson',
+			'/(m)en$/'              => '\1an',
+			'/(s)tatuses$/'         => '\1\2tatus',
+			'/(c)hildren$/'         => '\1\2hild',
+			'/(n)ews$/'             => '\1\2ews',
+			'/([^us])s$/'           => '\1',
 		);
 
 		foreach ($singular_rules as $rule => $replacement)
@@ -105,7 +109,6 @@
  *
  * Takes a singular word and makes it plural
  *
- * @access	public
  * @param	string
  * @param	bool
  * @return	str
@@ -113,31 +116,36 @@
 if ( ! function_exists('plural'))
 {
 	function plural($str, $force = FALSE)
-	{
+	{	
 		$result = strval($str);
 
-		$plural_rules = array(
-			'/^(ox)$/'					=> '\1\2en',	 // ox
-			'/([m|l])ouse$/'			=> '\1ice',	  // mouse, louse
-			'/(matr|vert|ind)ix|ex$/'	=> '\1ices',	 // matrix, vertex, index
-			'/(x|ch|ss|sh)$/'			=> '\1es',	   // search, switch, fix, box, process, address
-			'/([^aeiouy]|qu)y$/'		=> '\1ies',	  // query, ability, agency
-			'/(hive)$/'					=> '\1s',		// archive, hive
-			'/(?:([^f])fe|([lr])f)$/'	=> '\1\2ves',	// half, safe, wife
-			'/sis$/'					=> 'ses',		// basis, diagnosis
-			'/([ti])um$/'				=> '\1a',		// datum, medium
-			'/(p)erson$/'				=> '\1eople',	// person, salesperson
-			'/(m)an$/'					=> '\1en',	   // man, woman, spokesman
-			'/(c)hild$/'				=> '\1hildren',  // child
-			'/(buffal|tomat)o$/'		=> '\1\2oes',	// buffalo, tomato
-			'/(bu|campu)s$/'			=> '\1\2ses',	// bus, campus
-			'/(alias|status|virus)/'	=> '\1es',	   // alias
-			'/(octop)us$/'				=> '\1i',		// octopus
-			'/(ax|cris|test)is$/'		=> '\1es',	   // axis, crisis
-			'/s$/'						=> 's',		  // no change (compatibility)
-			'/$/'						=> 's',
-		);
+		if ( ! is_countable($result))
+		{
+			return $result;
+		}
 
+		$plural_rules = array(
+			'/^(ox)$/'                 => '\1\2en',     // ox
+			'/([m|l])ouse$/'           => '\1ice',      // mouse, louse
+			'/(matr|vert|ind)ix|ex$/'  => '\1ices',     // matrix, vertex, index
+			'/(x|ch|ss|sh)$/'          => '\1es',       // search, switch, fix, box, process, address
+			'/([^aeiouy]|qu)y$/'       => '\1ies',      // query, ability, agency
+			'/(hive)$/'                => '\1s',        // archive, hive
+			'/(?:([^f])fe|([lr])f)$/'  => '\1\2ves',    // half, safe, wife
+			'/sis$/'                   => 'ses',        // basis, diagnosis
+			'/([ti])um$/'              => '\1a',        // datum, medium
+			'/(p)erson$/'              => '\1eople',    // person, salesperson
+			'/(m)an$/'                 => '\1en',       // man, woman, spokesman
+			'/(c)hild$/'               => '\1hildren',  // child
+			'/(buffal|tomat)o$/'       => '\1\2oes',    // buffalo, tomato
+			'/(bu|campu)s$/'           => '\1\2ses',    // bus, campus
+			'/(alias|status|virus)$/'  => '\1es',       // alias
+			'/(octop)us$/'             => '\1i',        // octopus
+			'/(ax|cris|test)is$/'      => '\1es',       // axis, crisis
+			'/s$/'                     => 's',          // no change (compatibility)
+			'/$/'                      => 's',
+		);
+		
 		foreach ($plural_rules as $rule => $replacement)
 		{
 			if (preg_match($rule, $result))
@@ -158,7 +166,6 @@
  *
  * Takes multiple words separated by spaces or underscores and camelizes them
  *
- * @access	public
  * @param	string
  * @return	str
  */
@@ -166,9 +173,7 @@
 {
 	function camelize($str)
 	{
-		$str = 'x'.strtolower(trim($str));
-		$str = ucwords(preg_replace('/[\s_]+/', ' ', $str));
-		return substr(str_replace(' ', '', $str), 1);
+		return substr(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $str))), 1);
 	}
 }
 
@@ -179,7 +184,6 @@
  *
  * Takes multiple words separated by spaces and underscores them
  *
- * @access	public
  * @param	string
  * @return	str
  */
@@ -198,7 +202,6 @@
  *
  * Takes multiple words separated by the separator and changes them to spaces
  *
- * @access	public
  * @param	string $str
  * @param 	string $separator
  * @return	str
@@ -211,5 +214,22 @@
 	}
 }
 
+/**
+ * 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'))
+{
+	function is_countable($word)
+	{
+		return ! (in_array(strtolower(strval($word)), array(
+			'equipment', 'information', 'rice', 'money',
+			'species', 'series', 'fish', 'meta'
+		)));
+	}
+}
+
 /* End of file inflector_helper.php */
 /* Location: ./system/helpers/inflector_helper.php */
\ No newline at end of file
diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php
index b5217c9..a83580a 100644
--- a/system/helpers/language_helper.php
+++ b/system/helpers/language_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -65,6 +65,5 @@
 	}
 }
 
-// ------------------------------------------------------------------------
 /* End of file language_helper.php */
-/* Location: ./system/helpers/language_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/language_helper.php */
diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php
index 71cdabb..331b468 100644
--- a/system/helpers/number_helper.php
+++ b/system/helpers/number_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -83,6 +83,5 @@
 	}
 }
 
-
 /* End of file number_helper.php */
-/* Location: ./system/helpers/number_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/number_helper.php */
diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php
index bca9dcb..cd87a73 100644
--- a/system/helpers/path_helper.php
+++ b/system/helpers/path_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -60,25 +60,21 @@
 		// Resolve the path
 		if (function_exists('realpath') AND @realpath($path) !== FALSE)
 		{
-			$path = realpath($path).'/';
+			$path = realpath($path);
 		}
 
 		// Add a trailing slash
-		$path = preg_replace("#([^/])/*$#", "\\1/", $path);
+		$path = rtrim($path, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
 
 		// Make sure the path exists
-		if ($check_existance == TRUE)
+		if ($check_existance == TRUE && ! is_dir($path))
 		{
-			if ( ! is_dir($path))
-			{
-				show_error('Not a valid path: '.$path);
-			}
+			show_error('Not a valid path: '.$path);
 		}
 
 		return $path;
 	}
 }
 
-
 /* End of file path_helper.php */
-/* Location: ./system/helpers/path_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/path_helper.php */
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
index ad4e29a..99fda56 100644
--- a/system/helpers/security_helper.php
+++ b/system/helpers/security_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -87,14 +87,7 @@
 {
 	function do_hash($str, $type = 'sha1')
 	{
-		if ($type == 'sha1')
-		{
-			return sha1($str);
-		}
-		else
-		{
-			return md5($str);
-		}
+		return ($type === 'sha1') ? sha1($str) : md5($str);
 	}
 }
 
@@ -111,10 +104,7 @@
 {
 	function strip_image_tags($str)
 	{
-		$str = preg_replace("#<img\s+.*?src\s*=\s*[\"'](.+?)[\"'].*?\>#", "\\1", $str);
-		$str = preg_replace("#<img\s+.*?src\s*=\s*(.+?).*?\>#", "\\1", $str);
-
-		return $str;
+		return preg_replace(array("#<img\s+.*?src\s*=\s*[\"'](.+?)[\"'].*?\>#", "#<img\s+.*?src\s*=\s*(.+?).*?\>#"), "\\1", $str);
 	}
 }
 
@@ -135,6 +125,5 @@
 	}
 }
 
-
 /* End of file security_helper.php */
-/* Location: ./system/helpers/security_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/security_helper.php */
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
index 38e2965..700f448 100644
--- a/system/helpers/smiley_helper.php
+++ b/system/helpers/smiley_helper.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
index 6691681..04d51c2 100644
--- a/system/helpers/string_helper.php
+++ b/system/helpers/string_helper.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
index 38b46e2..6e9ea57 100644
--- a/system/helpers/text_helper.php
+++ b/system/helpers/text_helper.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -300,9 +300,9 @@
 
 		// 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'), $str);
+					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
@@ -311,25 +311,15 @@
 		// All the magic happens here, baby!
 		$str = highlight_string($str, TRUE);
 
-		// Prior to PHP 5, the highligh function used icky <font> tags
-		// so we'll replace them with <span> tags.
-
-		if (abs(PHP_VERSION) < 5)
-		{
-			$str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);
-			$str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
-		}
-
 		// 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);
 
 		// Replace our markers back to PHP tags.
-		$str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
-							array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;'), $str);
-
-		return $str;
+		return str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
+					array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;'),
+					$str);
 	}
 }
 
@@ -544,4 +534,4 @@
 }
 
 /* End of file text_helper.php */
-/* Location: ./system/helpers/text_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/text_helper.php */
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
index b1cedcd..c49348e 100644
--- a/system/helpers/typography_helper.php
+++ b/system/helpers/typography_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -88,7 +88,7 @@
  *
  * @access	public
  * @param	string
- * @param   string
+ * @param	string
  * @return	string
  */
 if ( ! function_exists('entity_decode'))
@@ -101,4 +101,4 @@
 }
 
 /* End of file typography_helper.php */
-/* Location: ./system/helpers/typography_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/typography_helper.php */
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
old mode 100755
new mode 100644
index 5d9afe4..3f0fef5
--- a/system/helpers/url_helper.php
+++ b/system/helpers/url_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -62,7 +62,7 @@
 
 /**
  * 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.
@@ -198,7 +198,6 @@
 	function anchor_popup($uri = '', $title = '', $attributes = FALSE)
 	{
 		$title = (string) $title;
-
 		$site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;
 
 		if ($title == '')
@@ -248,14 +247,12 @@
 	{
 		$title = (string) $title;
 
-		if ($title == "")
+		if ($title == '')
 		{
 			$title = $email;
 		}
 
-		$attributes = _parse_attributes($attributes);
-
-		return '<a href="mailto:'.$email.'"'.$attributes.'>'.$title.'</a>';
+		return '<a href="mailto:'.$email.'"'._parse_attributes($attributes).'>'.$title.'</a>';
 	}
 }
 
@@ -278,19 +275,16 @@
 	{
 		$title = (string) $title;
 
-		if ($title == "")
+		if ($title == '')
 		{
 			$title = $email;
 		}
 
-		for ($i = 0; $i < 16; $i++)
-		{
-			$x[] = substr('<a href="mailto:', $i, 1);
-		}
+		$x = str_split('<a href="mailto:', 1);
 
-		for ($i = 0; $i < strlen($email); $i++)
+		for ($i = 0, $l = strlen($email); $i < $l; $i++)
 		{
-			$x[] = "|".ord(substr($email, $i, 1));
+			$x[] = '|'.ord($email[$i]);
 		}
 
 		$x[] = '"';
@@ -302,18 +296,18 @@
 				foreach ($attributes as $key => $val)
 				{
 					$x[] =  ' '.$key.'="';
-					for ($i = 0; $i < strlen($val); $i++)
+					for ($i = 0, $l = strlen($val); $i < $l; $i++)
 					{
-						$x[] = "|".ord(substr($val, $i, 1));
+						$x[] = '|'.ord($val[$i]);
 					}
 					$x[] = '"';
 				}
 			}
 			else
 			{
-				for ($i = 0; $i < strlen($attributes); $i++)
+				for ($i = 0, $l = strlen($attributes); $i < $l; $i++)
 				{
-					$x[] = substr($attributes, $i, 1);
+					$x[] = $attributes[$i];
 				}
 			}
 		}
@@ -321,26 +315,28 @@
 		$x[] = '>';
 
 		$temp = array();
-		for ($i = 0; $i < strlen($title); $i++)
+		for ($i = 0, $l = strlen($title); $i < $l; $i++)
 		{
 			$ordinal = ord($title[$i]);
 
 			if ($ordinal < 128)
 			{
-				$x[] = "|".$ordinal;
+				$x[] = '|'.$ordinal;
 			}
 			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);
-					$x[] = "|".$number;
+					$number = ($count === 3)
+							? (($temp[0] % 16) * 4096) + (($temp[1] % 64) * 64) + ($temp[2] % 64)
+							: (($temp[0] % 32) * 64) + ($temp[1] % 64);
+					$x[] = '|'.$number;
 					$count = 1;
 					$temp = array();
 				}
@@ -356,8 +352,7 @@
 	//<![CDATA[
 	var l=new Array();
 	<?php
-	$i = 0;
-	foreach ($x as $val){ ?>l[<?php echo $i++; ?>]='<?php echo $val; ?>';<?php } ?>
+	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))+";");
@@ -391,49 +386,46 @@
 {
 	function auto_link($str, $type = 'both', $popup = FALSE)
 	{
-		if ($type != 'email')
+		if ($type !== 'email' && preg_match_all('#(^|\s|\(|\b)((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i', $str, $matches))
 		{
-			if (preg_match_all("#(^|\s|\(|\b)((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches))
-			{
-				$pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
+			$pop = ($popup) ? ' target="_blank" ' : '';
 
-				for ($i = 0; $i < count($matches['0']); $i++)
+			for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
+			{
+				if (preg_match('|\.$|', $matches[6][$i]))
+				{
+					$period = '.';
+					$matches[6][$i] = substr($matches[6][$i], 0, -1);
+				}
+				else
 				{
 					$period = '';
-					if (preg_match("|\.$|", $matches['6'][$i]))
-					{
-						$period = '.';
-						$matches['6'][$i] = substr($matches['6'][$i], 0, -1);
-					}
-
-					$str = str_replace($matches['0'][$i],
-										$matches['1'][$i].'<a href="http'.
-										$matches['4'][$i].'://'.
-										$matches['5'][$i].
-										$matches['6'][$i].'"'.$pop.'>http'.
-										$matches['4'][$i].'://'.
-										$matches['5'][$i].
-										$matches['6'][$i].'</a>'.
-										$period, $str);
 				}
+
+				$str = str_replace($matches[0][$i],
+							$matches[1][$i].'<a href="http'.$matches[4][$i].'://'
+								.$matches[5][$i].$matches[6][$i].'"'.$pop.'>http'
+								.$matches[4][$i].'://'.$matches[5][$i]
+								.$matches[6][$i].'</a>'.$period,
+							$str);
 			}
 		}
 
-		if ($type != 'url')
+		if ($type !== 'url' && preg_match_all('/([a-zA-Z0-9_\.\-\+]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i', $str, $matches))
 		{
-			if (preg_match_all("/([a-zA-Z0-9_\.\-\+]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches))
+			for ($i = 0, $c = count($matches); $i < $c; $i++)
 			{
-				for ($i = 0; $i < count($matches['0']); $i++)
+				if (preg_match('|\.$|', $matches[3][$i]))
+				{
+					$period = '.';
+					$matches[3][$i] = substr($matches[3][$i], 0, -1);
+				}
+				else
 				{
 					$period = '';
-					if (preg_match("|\.$|", $matches['3'][$i]))
-					{
-						$period = '.';
-						$matches['3'][$i] = substr($matches['3'][$i], 0, -1);
-					}
-
-					$str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str);
 				}
+
+				$str = str_replace($matches[0][$i], safe_mailto($matches[1][$i].'@'.$matches[2][$i].'.'.$matches[3][$i]).$period, $str);
 			}
 		}
 
@@ -456,7 +448,7 @@
 {
 	function prep_url($str = '')
 	{
-		if ($str == 'http://' OR $str == '')
+		if ($str === 'http://' OR $str == '')
 		{
 			return '';
 		}
@@ -465,7 +457,7 @@
 
 		if ( ! $url OR ! isset($url['scheme']))
 		{
-			$str = 'http://'.$str;
+			return 'http://'.$str;
 		}
 
 		return $str;
@@ -478,45 +470,40 @@
  * Create URL Title
  *
  * Takes a "title" string as input and creates a
- * human-friendly URL string with either a dash
- * or an underscore as the word separator.
+ * human-friendly URL string with a "separator" string 
+ * as the word separator.
  *
  * @access	public
  * @param	string	the string
- * @param	string	the separator: dash, or underscore
+ * @param	string	the separator
  * @return	string
  */
 if ( ! function_exists('url_title'))
 {
-	function url_title($str, $separator = 'dash', $lowercase = FALSE)
+	function url_title($str, $separator = '-', $lowercase = FALSE)
 	{
-		if ($separator == 'dash')
+		if ($separator === 'dash')
 		{
-			$search		= '_';
-			$replace	= '-';
+		    $separator = '-';
 		}
-		else
+		else if ($separator == 'underscore')
 		{
-			$search		= '-';
-			$replace	= '_';
+		    $separator = '_';
 		}
+		
+		$q_separator = preg_quote($separator);
 
 		$trans = array(
-						'&\#\d+?;'				=> '',
-						'&\S+?;'				=> '',
-						'\s+'					=> $replace,
-						'[^a-z0-9\-\._]'		=> '',
-						$replace.'+'			=> $replace,
-						$replace.'$'			=> $replace,
-						'^'.$replace			=> $replace,
-						'\.+$'					=> ''
-					);
+			'&.+?;'                 => '',
+			'[^a-z0-9 _-]'          => '',
+			'\s+'                   => $separator,
+			'('.$q_separator.')+'   => $separator
+		);
 
 		$str = strip_tags($str);
-
 		foreach ($trans as $key => $val)
 		{
-			$str = preg_replace("#".$key."#i", $val, $str);
+			$str = preg_replace('#'.$key.'#i', $val, $str);
 		}
 
 		if ($lowercase === TRUE)
@@ -524,7 +511,7 @@
 			$str = strtolower($str);
 		}
 
-		return trim(trim(stripslashes($str)), $replace);
+		return trim(trim($str, $separator));
 	}
 }
 
@@ -552,16 +539,18 @@
 		}
 
 		// IIS environment likely? Use 'refresh' for better compatibility
-		if (DIRECTORY_SEPARATOR != '/' && $method == 'auto')
+		if (DIRECTORY_SEPARATOR !== '/' && $method === 'auto')
 		{
 			$method = 'refresh';
 		}
 
 		switch($method)
 		{
-			case 'refresh'	: header("Refresh:0;url=".$uri);
+			case 'refresh':
+				header('Refresh:0;url='.$uri);
 				break;
-			default			: header("Location: ".$uri, TRUE, $http_response_code);
+			default:
+				header('Location: '.$uri, TRUE, $http_response_code);
 				break;
 		}
 		exit;
@@ -604,13 +593,12 @@
 
 		if ($javascript == TRUE AND $att != '')
 		{
-			$att = substr($att, 0, -1);
+			return substr($att, 0, -1);
 		}
 
 		return $att;
 	}
 }
 
-
 /* End of file url_helper.php */
-/* Location: ./system/helpers/url_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/url_helper.php */
diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php
index 0cf8f13..5242193 100644
--- a/system/helpers/xml_helper.php
+++ b/system/helpers/xml_helper.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -56,28 +56,26 @@
 		// 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);
+			$str = preg_replace('/&(\w+);/', "$temp\\1;", $str);
 		}
 
-		$str = str_replace(array("&","<",">","\"", "'", "-"),
-							array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;", "&#45;"),
-							$str);
+		$str = str_replace(array('&', '<', '>', '"', "'", '-'),
+					array('&amp;', '&lt;', '&gt;', '&quot;', '&apos;', '&#45;'),
+					$str);
 
 		// Decode the temp markers back to entities
-		$str = preg_replace("/$temp(\d+);/","&#\\1;",$str);
+		$str = preg_replace('/$temp(\d+);/', '&#\\1;', $str);
 
-		if ($protect_all === TRUE)
+		if ($protect_all == TRUE)
 		{
-			$str = preg_replace("/$temp(\w+);/","&\\1;", $str);
+			return preg_replace("/$temp(\w+);/", '&\\1;', $str);
 		}
 
 		return $str;
 	}
 }
 
-// ------------------------------------------------------------------------
-
 /* End of file xml_helper.php */
-/* Location: ./system/helpers/xml_helper.php */
\ No newline at end of file
+/* Location: ./system/helpers/xml_helper.php */
diff --git a/system/language/english/calendar_lang.php b/system/language/english/calendar_lang.php
index 313eee1..bf61db0 100644
--- a/system/language/english/calendar_lang.php
+++ b/system/language/english/calendar_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/date_lang.php b/system/language/english/date_lang.php
index 515feec..cd6cf39 100644
--- a/system/language/english/date_lang.php
+++ b/system/language/english/date_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -41,7 +41,7 @@
 $lang['date_seconds'] = "Seconds";
 
 $lang['UM12']	= '(UTC -12:00) Baker/Howland Island';
-$lang['UM11']	= '(UTC -11:00) Samoa Time Zone, Niue';
+$lang['UM11']	= '(UTC -11:00) Niue';
 $lang['UM10']	= '(UTC -10:00) Hawaii-Aleutian Standard Time, Cook Islands, Tahiti';
 $lang['UM95']	= '(UTC -9:30) Marquesas Islands';
 $lang['UM9']	= '(UTC -9:00) Alaska Standard Time, Gambier Islands';
@@ -58,9 +58,9 @@
 $lang['UTC']	= '(UTC) Greenwich Mean Time, Western European Time';
 $lang['UP1']	= '(UTC +1:00) Central European Time, West Africa Time';
 $lang['UP2']	= '(UTC +2:00) Central Africa Time, Eastern European Time, Kaliningrad Time';
-$lang['UP3']	= '(UTC +3:00) Moscow Time, East Africa Time';
+$lang['UP3']	= '(UTC +3:00) East Africa Time, Arabia Standard Time';
 $lang['UP35']	= '(UTC +3:30) Iran Standard Time';
-$lang['UP4']	= '(UTC +4:00) Azerbaijan Standard Time, Samara Time';
+$lang['UP4']	= '(UTC +4:00) Moscow Time, Azerbaijan Standard Time';
 $lang['UP45']	= '(UTC +4:30) Afghanistan';
 $lang['UP5']	= '(UTC +5:00) Pakistan Standard Time, Yekaterinburg Time';
 $lang['UP55']	= '(UTC +5:30) Indian Standard Time, Sri Lanka Time';
@@ -78,7 +78,7 @@
 $lang['UP115']	= '(UTC +11:30) Norfolk Island';
 $lang['UP12']	= '(UTC +12:00) Fiji, Gilbert Islands, Kamchatka Time, New Zealand Standard Time';
 $lang['UP1275']	= '(UTC +12:45) Chatham Islands Standard Time';
-$lang['UP13']	= '(UTC +13:00) Phoenix Islands Time, Tonga';
+$lang['UP13']	= '(UTC +13:00) Samoa Time Zone, Phoenix Islands Time, Tonga';
 $lang['UP14']	= '(UTC +14:00) Line Islands';
 
 
diff --git a/system/language/english/db_lang.php b/system/language/english/db_lang.php
index f42e469..2a91597 100644
--- a/system/language/english/db_lang.php
+++ b/system/language/english/db_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/email_lang.php b/system/language/english/email_lang.php
index f2dba27..e0ef427 100644
--- a/system/language/english/email_lang.php
+++ b/system/language/english/email_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/form_validation_lang.php b/system/language/english/form_validation_lang.php
index 1960dfe..6afa37a 100644
--- a/system/language/english/form_validation_lang.php
+++ b/system/language/english/form_validation_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/ftp_lang.php b/system/language/english/ftp_lang.php
index e934a19..18ca927 100644
--- a/system/language/english/ftp_lang.php
+++ b/system/language/english/ftp_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/imglib_lang.php b/system/language/english/imglib_lang.php
index b431d39..fbb92ab 100644
--- a/system/language/english/imglib_lang.php
+++ b/system/language/english/imglib_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/migration_lang.php b/system/language/english/migration_lang.php
index d87ac8d..9765562 100644
--- a/system/language/english/migration_lang.php
+++ b/system/language/english/migration_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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 3.0
diff --git a/system/language/english/number_lang.php b/system/language/english/number_lang.php
index a4e6c89..5dfd882 100644
--- a/system/language/english/number_lang.php
+++ b/system/language/english/number_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php
index 790abfa..1d10efa 100644
--- a/system/language/english/profiler_lang.php
+++ b/system/language/english/profiler_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/unit_test_lang.php b/system/language/english/unit_test_lang.php
index 185d83d..ed98439 100644
--- a/system/language/english/unit_test_lang.php
+++ b/system/language/english/unit_test_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/language/english/upload_lang.php b/system/language/english/upload_lang.php
index 2821055..a9a2fe7 100644
--- a/system/language/english/upload_lang.php
+++ b/system/language/english/upload_lang.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php
index c296fa7..2e78a66 100644
--- a/system/libraries/Cache/Cache.php
+++ b/system/libraries/Cache/Cache.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,26 +18,26 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2006 - 2011 EllisLab, Inc.
+ * @copyright	Copyright (c) 2006 - 2012 EllisLab, Inc.
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 2.0
- * @filesource	
+ * @filesource
  */
 
 // ------------------------------------------------------------------------
 
 /**
- * CodeIgniter Caching Class 
+ * CodeIgniter Caching Class
  *
  * @package		CodeIgniter
  * @subpackage	Libraries
  * @category	Core
  * @author		EllisLab Dev Team
- * @link		
+ * @link
  */
 class CI_Cache extends CI_Driver_Library {
-	
+
 	protected $valid_drivers 	= array(
 		'cache_apc', 'cache_file', 'cache_memcached', 'cache_dummy'
 	);
@@ -45,7 +45,7 @@
 	protected $_cache_path		= NULL;		// Path of cache files (if file-based cache)
 	protected $_adapter			= 'dummy';
 	protected $_backup_driver;
-	
+
 	// ------------------------------------------------------------------------
 
 	/**
@@ -64,16 +64,16 @@
 	// ------------------------------------------------------------------------
 
 	/**
-	 * Get 
+	 * Get
 	 *
-	 * Look for a value in the cache.  If it exists, return the data 
+	 * Look for a value in the cache.  If it exists, return the data
 	 * if not, return FALSE
 	 *
-	 * @param 	string	
+	 * @param 	string
 	 * @return 	mixed		value that is stored/FALSE on failure
 	 */
 	public function get($id)
-	{	
+	{
 		return $this->{$this->_adapter}->get($id);
 	}
 
@@ -124,7 +124,7 @@
 	 * Cache Info
 	 *
 	 * @param 	string		user/filehits
-	 * @return 	mixed		array on success, false on failure	
+	 * @return 	mixed		array on success, false on failure
 	 */
 	public function cache_info($type = 'user')
 	{
@@ -132,7 +132,7 @@
 	}
 
 	// ------------------------------------------------------------------------
-	
+
 	/**
 	 * Get Cache Metadata
 	 *
@@ -143,7 +143,7 @@
 	{
 		return $this->{$this->_adapter}->get_metadata($id);
 	}
-	
+
 	// ------------------------------------------------------------------------
 
 	/**
@@ -151,7 +151,7 @@
 	 *
 	 * Initialize class properties based on the configuration array.
 	 *
-	 * @param	array 	
+	 * @param	array
 	 * @return 	void
 	 */
 	private function _initialize($config)
@@ -219,10 +219,10 @@
 
 		return $obj;
 	}
-	
+
 	// ------------------------------------------------------------------------
 }
 // End Class
 
 /* End of file Cache.php */
-/* Location: ./system/libraries/Cache/Cache.php */
\ No newline at end of file
+/* Location: ./system/libraries/Cache/Cache.php */
diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php
index f15cf85..a3dd469 100644
--- a/system/libraries/Cache/drivers/Cache_apc.php
+++ b/system/libraries/Cache/drivers/Cache_apc.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,34 +18,34 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2006 - 2011 EllisLab, Inc.
+ * @copyright	Copyright (c) 2006 - 2012 EllisLab, Inc.
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 2.0
- * @filesource	
+ * @filesource
  */
 
 // ------------------------------------------------------------------------
 
 /**
- * CodeIgniter APC Caching Class 
+ * CodeIgniter APC Caching Class
  *
  * @package		CodeIgniter
  * @subpackage	Libraries
  * @category	Core
  * @author		EllisLab Dev Team
- * @link		
+ * @link
  */
 
 class CI_Cache_apc extends CI_Driver {
 
 	/**
-	 * Get 
+	 * Get
 	 *
-	 * Look for a value in the cache.  If it exists, return the data 
+	 * Look for a value in the cache.  If it exists, return the data
 	 * if not, return FALSE
 	 *
-	 * @param 	string	
+	 * @param 	string
 	 * @return 	mixed		value that is stored/FALSE on failure
 	 */
 	public function get($id)
@@ -55,8 +55,8 @@
 		return (is_array($data)) ? $data[0] : FALSE;
 	}
 
-	// ------------------------------------------------------------------------	
-	
+	// ------------------------------------------------------------------------
+
 	/**
 	 * Cache Save
 	 *
@@ -68,9 +68,10 @@
 	 */
 	public function save($id, $data, $ttl = 60)
 	{
+		$ttl = (int) $ttl;
 		return apc_store($id, array($data, time(), $ttl), $ttl);
 	}
-	
+
 	// ------------------------------------------------------------------------
 
 	/**
@@ -102,7 +103,7 @@
 	 * Cache Info
 	 *
 	 * @param 	string		user/filehits
-	 * @return 	mixed		array on success, false on failure	
+	 * @return 	mixed		array on success, false on failure
 	 */
 	 public function cache_info($type = NULL)
 	 {
@@ -149,13 +150,13 @@
 			log_message('error', 'The APC PHP extension must be loaded to use APC Cache.');
 			return FALSE;
 		}
-		
+
 		return TRUE;
 	}
 
 	// ------------------------------------------------------------------------
 
-	
+
 }
 // End Class
 
diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php
index 965bb2b..fcd55da 100644
--- a/system/libraries/Cache/drivers/Cache_dummy.php
+++ b/system/libraries/Cache/drivers/Cache_dummy.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2006 - 2011 EllisLab, Inc.
+ * @copyright	Copyright (c) 2006 - 2012 EllisLab, Inc.
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 2.0
@@ -138,4 +138,4 @@
 // End Class
 
 /* End of file Cache_dummy.php */
-/* Location: ./system/libraries/Cache/drivers/Cache_dummy.php */
\ No newline at end of file
+/* Location: ./system/libraries/Cache/drivers/Cache_dummy.php */
diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php
index be392d3..a960730 100644
--- a/system/libraries/Cache/drivers/Cache_file.php
+++ b/system/libraries/Cache/drivers/Cache_file.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,23 +18,23 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2006 - 2011 EllisLab, Inc.
+ * @copyright	Copyright (c) 2006 - 2012 EllisLab, Inc.
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 2.0
- * @filesource	
+ * @filesource
  */
 
 // ------------------------------------------------------------------------
 
 /**
- * CodeIgniter Memcached Caching Class 
+ * CodeIgniter Memcached Caching Class
  *
  * @package		CodeIgniter
  * @subpackage	Libraries
  * @category	Core
  * @author		EllisLab Dev Team
- * @link		
+ * @link
  */
 
 class CI_Cache_file extends CI_Driver {
@@ -48,9 +48,7 @@
 	{
 		$CI =& get_instance();
 		$CI->load->helper('file');
-		
 		$path = $CI->config->item('cache_path');
-	
 		$this->_cache_path = ($path == '') ? APPPATH.'cache/' : $path;
 	}
 
@@ -68,16 +66,15 @@
 		{
 			return FALSE;
 		}
-		
-		$data = read_file($this->_cache_path.$id);
-		$data = unserialize($data);
-		
+
+		$data = unserialize(read_file($this->_cache_path.$id));
+
 		if (time() >  $data['time'] + $data['ttl'])
 		{
 			unlink($this->_cache_path.$id);
 			return FALSE;
 		}
-		
+
 		return $data['data'];
 	}
 
@@ -88,22 +85,22 @@
 	 *
 	 * @param 	string		unique key
 	 * @param 	mixed		data to store
-	 * @param 	int			length of time (in seconds) the cache is valid 
+	 * @param 	int			length of time (in seconds) the cache is valid
 	 *						- Default is 60 seconds
 	 * @return 	boolean		true on success/false on failure
 	 */
 	public function save($id, $data, $ttl = 60)
-	{		
+	{
 		$contents = array(
 				'time'		=> time(),
-				'ttl'		=> $ttl,			
+				'ttl'		=> $ttl,
 				'data'		=> $data
 			);
-		
+
 		if (write_file($this->_cache_path.$id, serialize($contents)))
 		{
-			@chmod($this->_cache_path.$id, 0777);
-			return TRUE;			
+			@chmod($this->_cache_path.$id, 0660);
+			return TRUE;
 		}
 
 		return FALSE;
@@ -119,14 +116,7 @@
 	 */
 	public function delete($id)
 	{
-		if (file_exists($this->_cache_path.$id))
-		{
-			return unlink($this->_cache_path.$id);
-		}
-		else
-		{
-			return FALSE;
-		}
+		return (file_exists($this->_cache_path.$id)) ? unlink($this->_cache_path.$id) : FALSE;
 	}
 
 	// ------------------------------------------------------------------------
@@ -135,7 +125,7 @@
 	 * Clean the Cache
 	 *
 	 * @return 	boolean		false on failure/true on success
-	 */	
+	 */
 	public function clean()
 	{
 		return delete_files($this->_cache_path);
@@ -170,10 +160,9 @@
 		{
 			return FALSE;
 		}
-		
-		$data = read_file($this->_cache_path.$id);		
-		$data = unserialize($data);
-		
+
+		$data = unserialize(read_file($this->_cache_path.$id));
+
 		if (is_array($data))
 		{
 			$mtime = filemtime($this->_cache_path.$id);
@@ -188,7 +177,7 @@
 				'mtime'	 => $mtime
 			);
 		}
-		
+
 		return FALSE;
 	}
 
@@ -198,7 +187,7 @@
 	 * Is supported
 	 *
 	 * In the file driver, check to see that the cache directory is indeed writable
-	 * 
+	 *
 	 * @return boolean
 	 */
 	public function is_supported()
diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php
index 78cab25..ffe6f2f 100644
--- a/system/libraries/Cache/drivers/Cache_memcached.php
+++ b/system/libraries/Cache/drivers/Cache_memcached.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2006 - 2011 EllisLab, Inc.
+ * @copyright	Copyright (c) 2006 - 2012 EllisLab, Inc.
  * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
  * @link		http://codeigniter.com
  * @since		Version 2.0
@@ -84,7 +84,7 @@
 		{
 			return $this->_memcached->set($id, array($data, time(), $ttl), 0, $ttl);
 		}
-		
+
 		return FALSE;
 	}
 
@@ -256,4 +256,4 @@
 // End Class
 
 /* End of file Cache_memcached.php */
-/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
\ No newline at end of file
+/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php
index 605765b..a05a7ba 100644
--- a/system/libraries/Calendar.php
+++ b/system/libraries/Calendar.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php
index 01a0cb8..10b5362 100644
--- a/system/libraries/Cart.php
+++ b/system/libraries/Cart.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2006 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2006 - 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
@@ -329,13 +329,6 @@
 			return FALSE;
 		}
 
-		// Is the new quantity different than what is already saved in the cart?
-		// If it's the same there's nothing to do
-		if ($this->_cart_contents[$items['rowid']]['qty'] == $items['qty'])
-		{
-			return FALSE;
-		}
-
 		// Is the quantity zero?  If so we will remove the item from the cart.
 		// If the quantity is greater than zero we are updating
 		if ($items['qty'] == 0)
diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php
index 183a959..4e89443 100644
--- a/system/libraries/Driver.php
+++ b/system/libraries/Driver.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2006 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2006 - 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
@@ -76,7 +76,7 @@
 						if (file_exists($filepath))
 						{
 							include_once $filepath;
-							break;
+							break 2;
 						}
 					}
 				}
diff --git a/system/libraries/Email.php b/system/libraries/Email.php
index 1066535..8d839d0 100644
--- a/system/libraries/Email.php
+++ b/system/libraries/Email.php
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Email Class
  *
@@ -40,55 +38,55 @@
  */
 class CI_Email {
 
-	public $useragent		= "CodeIgniter";
-	public $mailpath		= "/usr/sbin/sendmail";	// Sendmail path
-	public $protocol		= "mail";	// mail/sendmail/smtp
-	public $smtp_host		= "";		// SMTP Server.  Example: mail.earthlink.net
-	public $smtp_user		= "";		// SMTP Username
-	public $smtp_pass		= "";		// SMTP Password
-	public $smtp_port		= "25";		// SMTP Port
-	public $smtp_timeout	= 5;		// SMTP Timeout in seconds
-	public $smtp_crypto	= "";		// SMTP Encryption. Can be null, tls or ssl.
-	public $wordwrap		= TRUE;		// TRUE/FALSE  Turns word-wrap on/off
-	public $wrapchars		= "76";		// Number of characters to wrap at.
-	public $mailtype		= "text";	// text/html  Defines email formatting
-	public $charset		= "utf-8";	// Default char set: iso-8859-1 or us-ascii
-	public $multipart		= "mixed";	// "mixed" (in the body) or "related" (separate)
-	public $alt_message	= '';		// Alternative message for HTML emails
-	public $validate		= FALSE;	// TRUE/FALSE.  Enables email validation
-	public $priority		= "3";		// Default priority (1 - 5)
-	public $newline		= "\n";		// Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)
-	public $crlf			= "\n";		// The RFC 2045 compliant CRLF for quoted-printable is "\r\n".  Apparently some servers,
+	public $useragent	= 'CodeIgniter';
+	public $mailpath	= '/usr/sbin/sendmail';	// Sendmail path
+	public $protocol	= 'mail';		// mail/sendmail/smtp
+	public $smtp_host	= '';			// SMTP Server. Example: mail.earthlink.net
+	public $smtp_user	= '';			// SMTP Username
+	public $smtp_pass	= '';			// SMTP Password
+	public $smtp_port	= 25;			// SMTP Port
+	public $smtp_timeout	= 5;			// SMTP Timeout in seconds
+	public $smtp_crypto	= '';			// SMTP Encryption. Can be null, tls or ssl.
+	public $wordwrap	= TRUE;			// TRUE/FALSE  Turns word-wrap on/off
+	public $wrapchars	= 76;			// Number of characters to wrap at.
+	public $mailtype	= 'text';		// text/html  Defines email formatting
+	public $charset		= 'utf-8';		// Default char set: iso-8859-1 or us-ascii
+	public $multipart	= 'mixed';		// "mixed" (in the body) or "related" (separate)
+	public $alt_message	= '';			// Alternative message for HTML emails
+	public $validate	= FALSE;		// TRUE/FALSE.  Enables email validation
+	public $priority	= 3;			// Default priority (1 - 5)
+	public $newline		= "\n";			// Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)
+	public $crlf		= "\n";			// The RFC 2045 compliant CRLF for quoted-printable is "\r\n".  Apparently some servers,
 									// even on the receiving end think they need to muck with CRLFs, so using "\n", while
 									// distasteful, is the only thing that seems to work for all environments.
 	public $send_multipart	= TRUE;		// TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override.  Set to FALSE for Yahoo.
-	public $bcc_batch_mode	= FALSE;	// TRUE/FALSE  Turns on/off Bcc batch feature
+	public $bcc_batch_mode	= FALSE;	// TRUE/FALSE - Turns on/off Bcc batch feature
 	public $bcc_batch_size	= 200;		// If bcc_batch_mode = TRUE, sets max number of Bccs in each batch
-	private $_safe_mode		= FALSE;
-	private $_subject		= "";
-	private $_body			= "";
-	private $_finalbody		= "";
-	private $_alt_boundary	= "";
-	private $_atc_boundary	= "";
-	private $_header_str	= "";
-	private $_smtp_connect	= "";
-	private $_encoding		= "8bit";
-	private $_IP			= FALSE;
-	private $_smtp_auth		= FALSE;
-	private $_replyto_flag	= FALSE;
-	private $_debug_msg		= array();
-	private $_recipients	= array();
-	private $_cc_array		= array();
-	private $_bcc_array		= array();
-	private $_headers		= array();
-	private $_attach_name	= array();
-	private $_attach_type	= array();
-	private $_attach_disp	= array();
-	private $_protocols		= array('mail', 'sendmail', 'smtp');
-	private $_base_charsets	= array('us-ascii', 'iso-2022-');	// 7-bit charsets (excluding language suffix)
-	private $_bit_depths	= array('7bit', '8bit');
-	private $_priorities	= array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
 
+	protected $_safe_mode		= FALSE;
+	protected $_subject		= '';
+	protected $_body		= '';
+	protected $_finalbody		= '';
+	protected $_alt_boundary	= '';
+	protected $_atc_boundary	= '';
+	protected $_header_str		= '';
+	protected $_smtp_connect	= '';
+	protected $_encoding		= '8bit';
+	protected $_IP			= FALSE;
+	protected $_smtp_auth		= FALSE;
+	protected $_replyto_flag	= FALSE;
+	protected $_debug_msg		= array();
+	protected $_recipients		= array();
+	protected $_cc_array		= array();
+	protected $_bcc_array		= array();
+	protected $_headers		= array();
+	protected $_attach_name		= array();
+	protected $_attach_type		= array();
+	protected $_attach_disp		= array();
+	protected $_protocols		= array('mail', 'sendmail', 'smtp');
+	protected $_base_charsets	= array('us-ascii', 'iso-2022-');	// 7-bit charsets (excluding language suffix)
+	protected $_bit_depths		= array('7bit', '8bit');
+	protected $_priorities		= array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
 
 	/**
 	 * Constructor - Sets Email Preferences
@@ -103,11 +101,11 @@
 		}
 		else
 		{
-			$this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
-			$this->_safe_mode = (bool) @ini_get("safe_mode");
+			$this->_smtp_auth = ! ($this->smtp_user == '' && $this->smtp_pass == '');
+			$this->_safe_mode = (bool) @ini_get('safe_mode');
 		}
 
-		log_message('debug', "Email Class Initialized");
+		log_message('debug', 'Email Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -115,7 +113,6 @@
 	/**
 	 * Initialize preferences
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	void
 	 */
@@ -139,8 +136,8 @@
 		}
 		$this->clear();
 
-		$this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE;
-		$this->_safe_mode = (bool) @ini_get("safe_mode");
+		$this->_smtp_auth = ! ($this->smtp_user == '' && $this->smtp_pass == '');
+		$this->_safe_mode = (bool) @ini_get('safe_mode');
 
 		return $this;
 	}
@@ -150,17 +147,16 @@
 	/**
 	 * Initialize the Email Data
 	 *
-	 * @access	public
 	 * @param	bool
-	 * @return	void
+	 * @return	object
 	 */
 	public function clear($clear_attachments = FALSE)
 	{
-		$this->_subject		= "";
-		$this->_body		= "";
-		$this->_finalbody	= "";
-		$this->_header_str	= "";
-		$this->_replyto_flag = FALSE;
+		$this->_subject		= '';
+		$this->_body		= '';
+		$this->_finalbody	= '';
+		$this->_header_str	= '';
+		$this->_replyto_flag	= FALSE;
 		$this->_recipients	= array();
 		$this->_cc_array	= array();
 		$this->_bcc_array	= array();
@@ -185,14 +181,13 @@
 	/**
 	 * Set FROM
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function from($from, $name = '')
 	{
-		if (preg_match( '/\<(.*)\>/', $from, $match))
+		if (preg_match('/\<(.*)\>/', $from, $match))
 		{
 			$from = $match[1];
 		}
@@ -228,14 +223,13 @@
 	/**
 	 * Set Reply-to
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function reply_to($replyto, $name = '')
 	{
-		if (preg_match( '/\<(.*)\>/', $replyto, $match))
+		if (preg_match('/\<(.*)\>/', $replyto, $match))
 		{
 			$replyto = $match[1];
 		}
@@ -266,9 +260,8 @@
 	/**
 	 * Set Recipients
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function to($to)
 	{
@@ -282,17 +275,17 @@
 
 		if ($this->_get_protocol() !== 'mail')
 		{
-			$this->_set_header('To', implode(", ", $to));
+			$this->_set_header('To', implode(', ', $to));
 		}
 
 		switch ($this->_get_protocol())
 		{
-			case 'smtp'		:
+			case 'smtp':
 				$this->_recipients = $to;
 			break;
-			case 'sendmail'	:
-			case 'mail'		:
-				$this->_recipients = implode(", ", $to);
+			case 'sendmail':
+			case 'mail':
+				$this->_recipients = implode(', ', $to);
 			break;
 		}
 
@@ -304,9 +297,8 @@
 	/**
 	 * Set CC
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function cc($cc)
 	{
@@ -318,7 +310,7 @@
 			$this->validate_email($cc);
 		}
 
-		$this->_set_header('Cc', implode(", ", $cc));
+		$this->_set_header('Cc', implode(', ', $cc));
 
 		if ($this->_get_protocol() === 'smtp')
 		{
@@ -333,10 +325,9 @@
 	/**
 	 * Set BCC
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function bcc($bcc, $limit = '')
 	{
@@ -360,7 +351,7 @@
 		}
 		else
 		{
-			$this->_set_header('Bcc', implode(", ", $bcc));
+			$this->_set_header('Bcc', implode(', ', $bcc));
 		}
 
 		return $this;
@@ -371,9 +362,8 @@
 	/**
 	 * Set Email Subject
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function subject($subject)
 	{
@@ -387,13 +377,12 @@
 	/**
 	 * Set Body
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function message($body)
 	{
-		$this->_body = rtrim(str_replace("\r", "", $body));
+		$this->_body = rtrim(str_replace("\r", '', $body));
 
 		/* strip slashes only if magic quotes is ON
 		   if we do it with magic quotes OFF, it strips real, user-inputted chars.
@@ -414,9 +403,8 @@
 	/**
 	 * Assign file attachments
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function attach($filename, $disposition = '', $newname = NULL)
 	{
@@ -431,7 +419,6 @@
 	/**
 	 * Add a Header Item
 	 *
-	 * @access	protected
 	 * @param	string
 	 * @param	string
 	 * @return	void
@@ -446,7 +433,6 @@
 	/**
 	 * Convert a String to an Array
 	 *
-	 * @access	protected
 	 * @param	string
 	 * @return	array
 	 */
@@ -460,8 +446,7 @@
 			}
 			else
 			{
-				$email = trim($email);
-				settype($email, "array");
+				$email = (array) trim($email);
 			}
 		}
 		return $email;
@@ -472,9 +457,8 @@
 	/**
 	 * Set Multipart Value
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_alt_message($str = '')
 	{
@@ -487,9 +471,8 @@
 	/**
 	 * Set Mailtype
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_mailtype($type = 'text')
 	{
@@ -502,9 +485,8 @@
 	/**
 	 * Set Wordwrap
 	 *
-	 * @access	public
 	 * @param	bool
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_wordwrap($wordwrap = TRUE)
 	{
@@ -517,13 +499,12 @@
 	/**
 	 * Set Protocol
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_protocol($protocol = 'mail')
 	{
-		$this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol);
+		$this->protocol = in_array($protocol, $this->_protocols, TRUE) ? strtolower($protocol) : 'mail';
 		return $this;
 	}
 
@@ -532,19 +513,12 @@
 	/**
 	 * Set Priority
 	 *
-	 * @access	public
-	 * @param	integer
-	 * @return	void
+	 * @param	int
+	 * @return	object
 	 */
 	public function set_priority($n = 3)
 	{
-		if ( ! is_numeric($n) OR $n < 1 OR $n > 5)
-		{
-			$this->priority = 3;
-			return;
-		}
-
-		$this->priority = (int) $n;
+		$this->priority = preg_match('/^[1-5]$/', $n) ? (int) $n : 3;
 		return $this;
 	}
 
@@ -553,9 +527,8 @@
 	/**
 	 * Set Newline Character
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_newline($newline = "\n")
 	{
@@ -568,13 +541,12 @@
 	/**
 	 * Set CRLF
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
 	public function set_crlf($crlf = "\n")
 	{
-		$this->crlf = ($crlf !== "\n" AND $crlf !== "\r\n" AND $crlf !== "\r") ? "\n" : $crlf;
+		$this->crlf = ($crlf !== "\n" && $crlf !== "\r\n" && $crlf !== "\r") ? "\n" : $crlf;
 		return $this;
 	}
 
@@ -583,13 +555,12 @@
 	/**
 	 * Set Message Boundary
 	 *
-	 * @access	protected
 	 * @return	void
 	 */
 	protected function _set_boundaries()
 	{
-		$this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative
-		$this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary
+		$this->_alt_boundary = 'B_ALT_'.uniqid(''); // multipart/alternative
+		$this->_atc_boundary = 'B_ATC_'.uniqid(''); // attachment boundary
 	}
 
 	// --------------------------------------------------------------------
@@ -597,14 +568,12 @@
 	/**
 	 * Get the Message ID
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _get_message_id()
 	{
 		$from = str_replace(array('>', '<'), '', $this->_headers['Return-Path']);
-
-		return  "<".uniqid('').strstr($from, '@').">";
+		return  '<'.uniqid('').strstr($from, '@').'>';
 	}
 
 	// --------------------------------------------------------------------
@@ -612,14 +581,13 @@
 	/**
 	 * Get Mail Protocol
 	 *
-	 * @access	protected
 	 * @param	bool
-	 * @return	string
+	 * @return	mixed
 	 */
 	protected function _get_protocol($return = TRUE)
 	{
 		$this->protocol = strtolower($this->protocol);
-		$this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol;
+		in_array($this->protocol, $this->_protocols, TRUE) OR $this->protocol = 'mail';
 
 		if ($return == TRUE)
 		{
@@ -632,13 +600,12 @@
 	/**
 	 * Get Mail Encoding
 	 *
-	 * @access	protected
 	 * @param	bool
 	 * @return	string
 	 */
 	protected function _get_encoding($return = TRUE)
 	{
-		$this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding;
+		in_array($this->_encoding, $this->_bit_depths) OR $this->_encoding = '8bit';
 
 		foreach ($this->_base_charsets as $charset)
 		{
@@ -659,7 +626,6 @@
 	/**
 	 * Get content type (text/html/attachment)
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _get_content_type()
@@ -687,17 +653,16 @@
 	/**
 	 * Set RFC 822 Date
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _set_date()
 	{
-		$timezone = date("Z");
+		$timezone = date('Z');
 		$operator = (strncmp($timezone, '-', 1) === 0) ? '-' : '+';
 		$timezone = abs($timezone);
 		$timezone = floor($timezone/3600) * 100 + ($timezone % 3600) / 60;
 
-		return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);
+		return sprintf('%s %s%04d', date('D, j M Y H:i:s'), $operator, $timezone);
 	}
 
 	// --------------------------------------------------------------------
@@ -705,12 +670,11 @@
 	/**
 	 * Mime message
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _get_mime_message()
 	{
-		return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";
+		return 'This is a multi-part message in MIME format.'.$this->newline.'Your email application may not support this format.';
 	}
 
 	// --------------------------------------------------------------------
@@ -718,7 +682,6 @@
 	/**
 	 * Validate Email Address
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -747,13 +710,12 @@
 	/**
 	 * Email Validation
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function valid_email($address)
 	{
-		return (bool) preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address);
+		return (bool) preg_match('/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix', $address);
 	}
 
 	// --------------------------------------------------------------------
@@ -761,7 +723,6 @@
 	/**
 	 * Clean Extended Email Address: Joe Smith <joe@smith.com>
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -776,7 +737,7 @@
 
 		foreach ($email as $addy)
 		{
-			$clean_email[] = (preg_match( '/\<(.*)\>/', $addy, $match)) ? $match[1] : $addy;
+			$clean_email[] = preg_match('/\<(.*)\>/', $addy, $match) ? $match[1] : $addy;
 		}
 
 		return $clean_email;
@@ -792,12 +753,11 @@
 	 * If the user hasn't specified his own alternative message
 	 * it creates one by stripping the HTML
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _get_alt_message()
 	{
-		if ($this->alt_message != "")
+		if ($this->alt_message != '')
 		{
 			return $this->word_wrap($this->alt_message, '76');
 		}
@@ -818,9 +778,8 @@
 	/**
 	 * Word Wrap
 	 *
-	 * @access	public
 	 * @param	string
-	 * @param	integer
+	 * @param	int
 	 * @return	string
 	 */
 	public function word_wrap($str, $charlim = '')
@@ -911,8 +870,6 @@
 	/**
 	 * Build final headers
 	 *
-	 * @access	protected
-	 * @param	string
 	 * @return	string
 	 */
 	protected function _build_headers()
@@ -929,7 +886,6 @@
 	/**
 	 * Write Headers as a string
 	 *
-	 * @access	protected
 	 * @return	void
 	 */
 	protected function _write_headers()
@@ -964,12 +920,11 @@
 	/**
 	 * Build Final Body and attachments
 	 *
-	 * @access	protected
 	 * @return	void
 	 */
 	protected function _build_message()
 	{
-		if ($this->wordwrap === TRUE AND $this->mailtype !== 'html')
+		if ($this->wordwrap === TRUE && $this->mailtype !== 'html')
 		{
 			$this->_body = $this->word_wrap($this->_body);
 		}
@@ -1131,9 +1086,8 @@
 	 * Prepares string for Quoted-Printable Content-Transfer-Encoding
 	 * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt
 	 *
-	 * @access	protected
 	 * @param	string
-	 * @param	integer
+	 * @param	int
 	 * @return	string
 	 */
 	protected function _prep_quoted_printable($str, $charlim = '')
@@ -1203,9 +1157,7 @@
 		}
 
 		// get rid of extra CRLF tacked onto the end
-		$output = substr($output, 0, strlen($this->crlf) * -1);
-
-		return $output;
+		return substr($output, 0, strlen($this->crlf) * -1);
 	}
 
 	// --------------------------------------------------------------------
@@ -1216,10 +1168,9 @@
 	 * Performs "Q Encoding" on a string for use in email headers.  It's related
 	 * but not identical to quoted-printable, so it has its own method
 	 *
-	 * @access	public
-	 * @param	str
-	 * @param	bool	// set to TRUE for processing From: headers
-	 * @return	str
+	 * @param	string
+	 * @param	bool	set to TRUE for processing From: headers
+	 * @return	string
 	 */
 	protected function _prep_q_encoding($str, $from = FALSE)
 	{
@@ -1275,9 +1226,7 @@
 
 		// wrap each line with the shebang, charset, and transfer encoding
 		// the preceding space on successive lines is required for header "folding"
-		$str = trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $str));
-
-		return $str;
+		return trim(preg_replace('/^(.*)$/m', ' =?'.$this->charset.'?Q?$1?=', $str));
 	}
 
 	// --------------------------------------------------------------------
@@ -1285,7 +1234,6 @@
 	/**
 	 * Send Email
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function send()
@@ -1295,9 +1243,9 @@
 			$this->reply_to($this->_headers['From']);
 		}
 
-		if (( ! isset($this->_recipients) AND ! isset($this->_headers['To']))  AND
-			( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND
-			( ! isset($this->_headers['Cc'])))
+		if ( ! isset($this->_recipients) && ! isset($this->_headers['To'])
+			&& ! isset($this->_bcc_array) && ! isset($this->_headers['Bcc'])
+			&& ! isset($this->_headers['Cc']))
 		{
 			$this->_set_error_message('lang:email_no_recipients');
 			return FALSE;
@@ -1305,44 +1253,40 @@
 
 		$this->_build_headers();
 
-		if ($this->bcc_batch_mode AND count($this->_bcc_array) > $this->bcc_batch_size)
+		if ($this->bcc_batch_mode && count($this->_bcc_array) > $this->bcc_batch_size)
 		{
 			return $this->batch_bcc_send();
 		}
 
 		$this->_build_message();
-
 		return $this->_spool_email();
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Batch Bcc Send.  Sends groups of BCCs in batches
+	 * Batch Bcc Send. Sends groups of BCCs in batches
 	 *
-	 * @access	public
-	 * @return	bool
+	 * @return	void
 	 */
 	public function batch_bcc_send()
 	{
-		$float = $this->bcc_batch_size -1;
-
-		$set = "";
-
+		$float = $this->bcc_batch_size - 1;
+		$set = '';
 		$chunk = array();
 
 		for ($i = 0, $c = count($this->_bcc_array); $i < $c; $i++)
 		{
 			if (isset($this->_bcc_array[$i]))
 			{
-				$set .= ", ".$this->_bcc_array[$i];
+				$set .= ', '.$this->_bcc_array[$i];
 			}
 
 			if ($i == $float)
 			{
 				$chunk[] = substr($set, 1);
 				$float += $this->bcc_batch_size;
-				$set = "";
+				$set = '';
 			}
 
 			if ($i === $c-1)
@@ -1359,7 +1303,7 @@
 
 			if ($this->protocol !== 'smtp')
 			{
-				$this->_set_header('Bcc', implode(", ", $bcc));
+				$this->_set_header('Bcc', implode(', ', $bcc));
 			}
 			else
 			{
@@ -1376,7 +1320,6 @@
 	/**
 	 * Unwrap special elements
 	 *
-	 * @access	protected
 	 * @return	void
 	 */
 	protected function _unwrap_specials()
@@ -1389,7 +1332,6 @@
 	/**
 	 * Strip line-breaks via callback
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _remove_nl_callback($matches)
@@ -1407,7 +1349,6 @@
 	/**
 	 * Spool mail to the mail server
 	 *
-	 * @access	protected
 	 * @return	bool
 	 */
 	protected function _spool_email()
@@ -1418,6 +1359,7 @@
 		if ( ! $this->$method())
 		{
 			$this->_set_error_message('lang:email_send_failure_' . ($this->_get_protocol() === 'mail' ? 'phpmail' : $this->_get_protocol()));
+			return FALSE;
 		}
 
 		$this->_set_error_message('lang:email_sent', $this->_get_protocol());
@@ -1429,7 +1371,6 @@
 	/**
 	 * Send using mail()
 	 *
-	 * @access	protected
 	 * @return	bool
 	 */
 	protected function _send_with_mail()
@@ -1451,7 +1392,6 @@
 	/**
 	 * Send using Sendmail
 	 *
-	 * @access	protected
 	 * @return	bool
 	 */
 	protected function _send_with_sendmail()
@@ -1484,7 +1424,6 @@
 	/**
 	 * Send using SMTP
 	 *
-	 * @access	protected
 	 * @return	bool
 	 */
 	protected function _send_with_smtp()
@@ -1495,8 +1434,10 @@
 			return FALSE;
 		}
 
-		$this->_smtp_connect();
-		$this->_smtp_authenticate();
+		if ( ! $this->_smtp_connect() OR ! $this->_smtp_authenticate())
+		{
+			return FALSE;
+		}
 
 		$this->_send_command('from', $this->clean_email($this->_headers['From']));
 
@@ -1553,7 +1494,6 @@
 	/**
 	 * SMTP Connect
 	 *
-	 * @access	protected
 	 * @param	string
 	 * @return	string
 	 */
@@ -1597,7 +1537,6 @@
 	/**
 	 * Send SMTP command
 	 *
-	 * @access	protected
 	 * @param	string
 	 * @param	string
 	 * @return	string
@@ -1670,7 +1609,6 @@
 	/**
 	 *  SMTP Authenticate
 	 *
-	 * @access	protected
 	 * @return	bool
 	 */
 	protected function _smtp_authenticate()
@@ -1680,7 +1618,7 @@
 			return TRUE;
 		}
 
-		if ($this->smtp_user == ""  AND  $this->smtp_pass == "")
+		if ($this->smtp_user == '' && $this->smtp_pass == '')
 		{
 			$this->_set_error_message('lang:email_no_smtp_unpw');
 			return FALSE;
@@ -1724,7 +1662,6 @@
 	/**
 	 * Send SMTP data
 	 *
-	 * @access	protected
 	 * @return	bool
 	 */
 	protected function _send_data($data)
@@ -1743,7 +1680,6 @@
 	/**
 	 * Get SMTP data
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _get_smtp_data()
@@ -1768,12 +1704,11 @@
 	/**
 	 * Get Hostname
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _get_hostname()
 	{
-		return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
+		return isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
 	}
 
 	// --------------------------------------------------------------------
@@ -1781,7 +1716,6 @@
 	/**
 	 * Get IP
 	 *
-	 * @access	protected
 	 * @return	string
 	 */
 	protected function _get_ip()
@@ -1791,13 +1725,13 @@
 			return $this->_IP;
 		}
 
-		$cip = (isset($_SERVER['HTTP_CLIENT_IP']) AND $_SERVER['HTTP_CLIENT_IP'] != "") ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
-		$rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE;
+		$cip = ( ! empty($_SERVER['HTTP_CLIENT_IP'])) ? $_SERVER['HTTP_CLIENT_IP'] : FALSE;
+		$rip = ( ! empty($_SERVER['REMOTE_ADDR'])) ? $_SERVER['REMOTE_ADDR'] : FALSE;
 		if ($cip) $this->_IP = $cip;
 		elseif ($rip) $this->_IP = $rip;
 		else
 		{
-			$fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE;
+			$fip = ( ! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE;
 			if ($fip)
 			{
 				$this->_IP = $fip;
@@ -1810,7 +1744,7 @@
 			$this->_IP = end($x);
 		}
 
-		if ( ! preg_match( "/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/", $this->_IP))
+		if ( ! preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/', $this->_IP))
 		{
 			$this->_IP = '0.0.0.0';
 		}
@@ -1823,7 +1757,6 @@
 	/**
 	 * Get Debug Message
 	 *
-	 * @access	public
 	 * @return	string
 	 */
 	public function print_debugger()
@@ -1838,8 +1771,7 @@
 			}
 		}
 
-		$msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
-		return $msg;
+		return $msg.'<pre>'.$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>';
 	}
 
 	// --------------------------------------------------------------------
@@ -1847,16 +1779,15 @@
 	/**
 	 * Set Message
 	 *
-	 * @access	protected
 	 * @param	string
-	 * @return	string
+	 * @return	void
 	 */
 	protected function _set_error_message($msg, $val = '')
 	{
 		$CI =& get_instance();
 		$CI->lang->load('email');
 
-		if (substr($msg, 0, 5) !== 'lang:' || FALSE === ($line = $CI->lang->line(substr($msg, 5))))
+		if (substr($msg, 0, 5) !== 'lang:' OR FALSE === ($line = $CI->lang->line(substr($msg, 5))))
 		{
 			$this->_debug_msg[] = str_replace('%s', $val, $msg)."<br />";
 		}
@@ -1871,13 +1802,13 @@
 	/**
 	 * Mime Types
 	 *
-	 * @access	protected
 	 * @param	string
 	 * @return	string
 	 */
-	protected function _mime_types($ext = "")
+	protected function _mime_types($ext = '')
 	{
-		$mimes = array(	'hqx'	=>	'application/mac-binhex40',
+		$mimes = array(
+						'hqx'	=>	'application/mac-binhex40',
 						'cpt'	=>	'application/mac-compactpro',
 						'doc'	=>	'application/msword',
 						'bin'	=>	'application/macbinary',
@@ -1966,11 +1897,10 @@
 						'eml'	=>	'message/rfc822'
 					);
 
-		return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];
+		return isset($mimes[strtolower($ext)]) ? $mimes[strtolower($ext)] : 'application/x-unknown-content-type';
 	}
 
 }
-// END CI_Email class
 
 /* End of file Email.php */
 /* Location: ./system/libraries/Email.php */
diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php
index c2cb808..0b06189 100644
--- a/system/libraries/Encrypt.php
+++ b/system/libraries/Encrypt.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * CodeIgniter Encryption Class
  *
@@ -40,24 +38,16 @@
  */
 class CI_Encrypt {
 
-	var $CI;
-	var $encryption_key	= '';
-	var $_hash_type	= 'sha1';
-	var $_mcrypt_exists = FALSE;
-	var $_mcrypt_cipher;
-	var $_mcrypt_mode;
+	public $encryption_key	= '';
+	protected $_hash_type	= 'sha1';
+	protected $_mcrypt_exists = FALSE;
+	protected $_mcrypt_cipher;
+	protected $_mcrypt_mode;
 
-	/**
-	 * Constructor
-	 *
-	 * Simply determines whether the mcrypt library exists.
-	 *
-	 */
 	public function __construct()
 	{
-		$this->CI =& get_instance();
 		$this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;
-		log_message('debug', "Encrypt Class Initialized");
+		log_message('debug', 'Encrypt Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -68,11 +58,10 @@
 	 * Returns it as MD5 in order to have an exact-length 128 bit key.
 	 * Mcrypt is sensitive to keys that are not the correct length
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function get_key($key = '')
+	public function get_key($key = '')
 	{
 		if ($key == '')
 		{
@@ -84,7 +73,7 @@
 			$CI =& get_instance();
 			$key = $CI->config->item('encryption_key');
 
-			if ($key == FALSE)
+			if ($key === FALSE)
 			{
 				show_error('In order to use the encryption class requires that you set an encryption key in your config file.');
 			}
@@ -98,13 +87,13 @@
 	/**
 	 * Set the encryption key
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	void
+	 * @return	object
 	 */
-	function set_key($key = '')
+	public function set_key($key = '')
 	{
 		$this->encryption_key = $key;
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -120,25 +109,14 @@
 	 * that is randomized with each call to this function,
 	 * even if the supplied message and key are the same.
 	 *
-	 * @access	public
 	 * @param	string	the string to encode
 	 * @param	string	the key
 	 * @return	string
 	 */
-	function encode($string, $key = '')
+	public function encode($string, $key = '')
 	{
-		$key = $this->get_key($key);
-
-		if ($this->_mcrypt_exists === TRUE)
-		{
-			$enc = $this->mcrypt_encode($string, $key);
-		}
-		else
-		{
-			$enc = $this->_xor_encode($string, $key);
-		}
-
-		return base64_encode($enc);
+		$method = ($this->_mcrypt_exists === TRUE) ? 'mcrypt_encode' : '_xor_encode';
+		return base64_encode($this->$method($string, $this->get_key($key)));
 	}
 
 	// --------------------------------------------------------------------
@@ -148,35 +126,19 @@
 	 *
 	 * Reverses the above process
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	function decode($string, $key = '')
+	public function decode($string, $key = '')
 	{
-		$key = $this->get_key($key);
-
 		if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
 		{
 			return FALSE;
 		}
 
-		$dec = base64_decode($string);
-
-		if ($this->_mcrypt_exists === TRUE)
-		{
-			if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)
-			{
-				return FALSE;
-			}
-		}
-		else
-		{
-			$dec = $this->_xor_decode($dec, $key);
-		}
-
-		return $dec;
+		$method = ($this->_mcrypt_exists === TRUE) ? 'mcrypt_decode' : '_xor_decode';
+		return $this->$method(base64_decode($string), $this->get_key($key));
 	}
 
 	// --------------------------------------------------------------------
@@ -191,19 +153,22 @@
 	 *
 	 * For more details, see http://codeigniter.com/user_guide/installation/upgrade_200.html#encryption
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	int		(mcrypt mode constant)
 	 * @param	string
 	 * @return	string
 	 */
-	function encode_from_legacy($string, $legacy_mode = MCRYPT_MODE_ECB, $key = '')
+	public function encode_from_legacy($string, $legacy_mode = MCRYPT_MODE_ECB, $key = '')
 	{
 		if ($this->_mcrypt_exists === FALSE)
 		{
 			log_message('error', 'Encoding from legacy is available only when Mcrypt is in use.');
 			return FALSE;
 		}
+		elseif (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
+		{
+			return FALSE;
+		}
 
 		// decode it first
 		// set mode temporarily to what it was when string was encoded with the legacy
@@ -212,14 +177,7 @@
 		$this->set_mode($legacy_mode);
 
 		$key = $this->get_key($key);
-
-		if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
-		{
-			return FALSE;
-		}
-
 		$dec = base64_decode($string);
-
 		if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)
 		{
 			return FALSE;
@@ -242,25 +200,25 @@
 	 * Takes a plain-text string and key as input and generates an
 	 * encoded bit-string using XOR
 	 *
-	 * @access	private
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	function _xor_encode($string, $key)
+	protected function _xor_encode($string, $key)
 	{
 		$rand = '';
-		while (strlen($rand) < 32)
+		do
 		{
 			$rand .= mt_rand(0, mt_getrandmax());
 		}
+		while (strlen($rand) < 32);
 
 		$rand = $this->hash($rand);
 
 		$enc = '';
-		for ($i = 0; $i < strlen($string); $i++)
+		for ($i = 0, $ls = strlen($string), $lr = strlen($rand); $i < $ls; $i++)
 		{
-			$enc .= substr($rand, ($i % strlen($rand)), 1).(substr($rand, ($i % strlen($rand)), 1) ^ substr($string, $i, 1));
+			$enc .= $rand[($i % $lr)].($rand[($i % $lr)] ^ $string[$i]);
 		}
 
 		return $this->_xor_merge($enc, $key);
@@ -274,19 +232,18 @@
 	 * Takes an encoded string and key as input and generates the
 	 * plain-text original message
 	 *
-	 * @access	private
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	function _xor_decode($string, $key)
+	protected function _xor_decode($string, $key)
 	{
 		$string = $this->_xor_merge($string, $key);
 
 		$dec = '';
-		for ($i = 0; $i < strlen($string); $i++)
+		for ($i = 0, $l = strlen($string); $i < $l; $i++)
 		{
-			$dec .= (substr($string, $i++, 1) ^ substr($string, $i, 1));
+			$dec .= ($string[$i++] ^ $string[$i]);
 		}
 
 		return $dec;
@@ -299,18 +256,17 @@
 	 *
 	 * Takes a string and key as input and computes the difference using XOR
 	 *
-	 * @access	private
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	function _xor_merge($string, $key)
+	protected function _xor_merge($string, $key)
 	{
 		$hash = $this->hash($key);
 		$str = '';
-		for ($i = 0; $i < strlen($string); $i++)
+		for ($i = 0, $ls = strlen($string), $lh = strlen($hash); $i < $ls; $i++)
 		{
-			$str .= substr($string, $i, 1) ^ substr($hash, ($i % strlen($hash)), 1);
+			$str .= $string[$i] ^ $hash[($i % $lh)];
 		}
 
 		return $str;
@@ -321,12 +277,11 @@
 	/**
 	 * Encrypt using Mcrypt
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	function mcrypt_encode($data, $key)
+	public function mcrypt_encode($data, $key)
 	{
 		$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
 		$init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);
@@ -338,12 +293,11 @@
 	/**
 	 * Decrypt using Mcrypt
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	function mcrypt_decode($data, $key)
+	public function mcrypt_decode($data, $key)
 	{
 		$data = $this->_remove_cipher_noise($data, $key);
 		$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());
@@ -365,27 +319,23 @@
 	 * against Man-in-the-middle attacks on CBC mode ciphers
 	 * http://www.ciphersbyritter.com/GLOSSARY.HTM#IV
 	 *
-	 * Function description
-	 *
-	 * @access	private
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
-	function _add_cipher_noise($data, $key)
+	protected function _add_cipher_noise($data, $key)
 	{
-		$keyhash = $this->hash($key);
-		$keylen = strlen($keyhash);
+		$key = $this->hash($key);
 		$str = '';
 
-		for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)
+		for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j)
 		{
-			if ($j >= $keylen)
+			if ($j >= $lk)
 			{
 				$j = 0;
 			}
 
-			$str .= chr((ord($data[$i]) + ord($keyhash[$j])) % 256);
+			$str .= chr((ord($data[$i]) + ord($key[$j])) % 256);
 		}
 
 		return $str;
@@ -399,28 +349,26 @@
 	 *
 	 * Function description
 	 *
-	 * @access	public
 	 * @param	type
 	 * @return	type
 	 */
-	function _remove_cipher_noise($data, $key)
+	protected function _remove_cipher_noise($data, $key)
 	{
-		$keyhash = $this->hash($key);
-		$keylen = strlen($keyhash);
+		$key = $this->hash($key);
 		$str = '';
 
-		for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)
+		for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j)
 		{
-			if ($j >= $keylen)
+			if ($j >= $lk)
 			{
 				$j = 0;
 			}
 
-			$temp = ord($data[$i]) - ord($keyhash[$j]);
+			$temp = ord($data[$i]) - ord($key[$j]);
 
 			if ($temp < 0)
 			{
-				$temp = $temp + 256;
+				$temp += 256;
 			}
 
 			$str .= chr($temp);
@@ -434,13 +382,13 @@
 	/**
 	 * Set the Mcrypt Cipher
 	 *
-	 * @access	public
 	 * @param	constant
 	 * @return	string
 	 */
-	function set_cipher($cipher)
+	public function set_cipher($cipher)
 	{
 		$this->_mcrypt_cipher = $cipher;
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -448,13 +396,13 @@
 	/**
 	 * Set the Mcrypt Mode
 	 *
-	 * @access	public
 	 * @param	constant
 	 * @return	string
 	 */
-	function set_mode($mode)
+	public function set_mode($mode)
 	{
 		$this->_mcrypt_mode = $mode;
+		return $this;
 	}
 
 	// --------------------------------------------------------------------
@@ -462,14 +410,13 @@
 	/**
 	 * Get Mcrypt cipher Value
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _get_cipher()
+	protected function _get_cipher()
 	{
 		if ($this->_mcrypt_cipher == '')
 		{
-			$this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;
+			return $this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;
 		}
 
 		return $this->_mcrypt_cipher;
@@ -480,14 +427,13 @@
 	/**
 	 * Get Mcrypt Mode Value
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _get_mode()
+	protected function _get_mode()
 	{
 		if ($this->_mcrypt_mode == '')
 		{
-			$this->_mcrypt_mode = MCRYPT_MODE_CBC;
+			return $this->_mcrypt_mode = MCRYPT_MODE_CBC;
 		}
 
 		return $this->_mcrypt_mode;
@@ -498,13 +444,12 @@
 	/**
 	 * Set the Hash type
 	 *
-	 * @access	public
 	 * @param	string
-	 * @return	string
+	 * @return	void
 	 */
-	function set_hash($type = 'sha1')
+	public function set_hash($type = 'sha1')
 	{
-		$this->_hash_type = ($type != 'sha1' AND $type != 'md5') ? 'sha1' : $type;
+		$this->_hash_type = ($type !== 'sha1' && $type !== 'md5') ? 'sha1' : $type;
 	}
 
 	// --------------------------------------------------------------------
@@ -512,48 +457,14 @@
 	/**
 	 * Hash encode a string
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function hash($str)
+	public function hash($str)
 	{
-		return ($this->_hash_type == 'sha1') ? $this->sha1($str) : md5($str);
+		return ($this->_hash_type === 'sha1') ? sha1($str) : md5($str);
 	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Generate an SHA1 Hash
-	 *
-	 * @access	public
-	 * @param	string
-	 * @return	string
-	 */
-	function sha1($str)
-	{
-		if ( ! function_exists('sha1'))
-		{
-			if ( ! function_exists('mhash'))
-			{
-				require_once(BASEPATH.'libraries/Sha1.php');
-				$SH = new CI_SHA;
-				return $SH->generate($str);
-			}
-			else
-			{
-				return bin2hex(mhash(MHASH_SHA1, $str));
-			}
-		}
-		else
-		{
-			return sha1($str);
-		}
-	}
-
 }
 
-// END CI_Encrypt class
-
 /* End of file Encrypt.php */
-/* Location: ./system/libraries/Encrypt.php */
\ No newline at end of file
+/* Location: ./system/libraries/Encrypt.php */
diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php
index 3f53232..b3efe82 100644
--- a/system/libraries/Form_validation.php
+++ b/system/libraries/Form_validation.php
@@ -1,4 +1,4 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -47,7 +47,8 @@
 	protected $_error_suffix		= '</p>';
 	protected $error_string			= '';
 	protected $_safe_form_data		= FALSE;
-
+	protected $validation_data		= array();
+	
 	/**
 	 * Constructor
 	 */
@@ -78,15 +79,15 @@
 	 * This function takes an array of field names and validation
 	 * rules as input, validates the info, and stores it
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @param	string
 	 * @return	void
 	 */
 	public function set_rules($field, $label = '', $rules = '')
 	{
-		// No reason to set rules if we have no POST data
-		if (count($_POST) == 0)
+		// No reason to set rules if we have no POST data 
+		// or a validation array has not been specified
+		if (count($_POST) === 0 && count($this->validation_data) === 0)
 		{
 			return $this;
 		}
@@ -113,7 +114,7 @@
 		}
 
 		// 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;
 		}
@@ -121,21 +122,20 @@
 		// If the field label wasn't passed we use the field name
 		$label = ($label == '') ? $field : $label;
 
-		// Is the field name an array?  We test for the existence of a bracket "[" in
-		// the field name to determine this.  If it is an array, we break it apart
+		// 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
-		if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches))
+		if (preg_match_all('/\[(.*?)\]/', $field, $matches))
 		{
 			// Note: Due to a bug in current() that affects some versions
 			// of PHP we can not pass function call directly into it
 			$x = explode('[', $field);
 			$indexes[] = current($x);
 
-			for ($i = 0; $i < count($matches['0']); $i++)
+			for ($i = 0, $c = count($matches[0]); $i < $c; $i++)
 			{
-				if ($matches['1'][$i] != '')
+				if ($matches[1][$i] != '')
 				{
-					$indexes[] = $matches['1'][$i];
+					$indexes[] = $matches[1][$i];
 				}
 			}
 
@@ -162,14 +162,31 @@
 	}
 
 	// --------------------------------------------------------------------
+	
+	/**
+	 * By default, form validation uses the $_POST array to validate
+	 * 
+	 * If an array is set through this method, then this array will
+	 * be used instead of the $_POST array
+	 * 
+	 * @param array $data 
+	 */
+	public function set_data($data = '')
+	{
+		if ( ! empty($data) && is_array($data))
+		{
+			$this->validation_data = $data;		
+		}
+	}
+	
+	// --------------------------------------------------------------------
 
 	/**
 	 * 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.
+	 * name has to match the function name that it corresponds to.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	string
@@ -193,7 +210,6 @@
 	 *
 	 * Permits a prefix/suffix to be added to each error message
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	void
@@ -213,7 +229,6 @@
 	 *
 	 * Gets the error message associated with a particular field
 	 *
-	 * @access	public
 	 * @param	string	the field name
 	 * @return	void
 	 */
@@ -240,11 +255,24 @@
 	// --------------------------------------------------------------------
 
 	/**
+	 * Get Array of Error Messages
+	 *
+	 * Returns the error messages as an array
+	 *
+	 * @return	array
+	 */
+	public function error_array()
+	{
+		return $this->_error_array;
+	}
+
+	// --------------------------------------------------------------------
+
+	/**
 	 * Error String
 	 *
 	 * Returns the error messages as a string, wrapped in the error delimiters
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	str
@@ -287,23 +315,26 @@
 	 *
 	 * This function does all the work.
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function run($group = '')
 	{
 		// Do we even have any data to process?  Mm?
-		if (count($_POST) == 0)
+		$validation_array = ( ! empty($this->validation_data)) ? $this->validation_data : $_POST;
+		if (count($validation_array) === 0)
 		{
 			return FALSE;
 		}
+		
+		// Clear any previous validation data
+		$this->_reset_validation();
 
 		// Does the _field_data array containing the validation rules exist?
 		// If not, we look to see if they were assigned via a config file
-		if (count($this->_field_data) == 0)
+		if (count($this->_field_data) === 0)
 		{
 			// No validation rules?  We're done...
-			if (count($this->_config_rules) == 0)
+			if (count($this->_config_rules) === 0)
 			{
 				return FALSE;
 			}
@@ -321,7 +352,7 @@
 			}
 
 			// We're we able to set the rules correctly?
-			if (count($this->_field_data) == 0)
+			if (count($this->_field_data) === 0)
 			{
 				log_message('debug', "Unable to find validation rules");
 				return FALSE;
@@ -335,18 +366,18 @@
 		// corresponding $_POST item and test for errors
 		foreach ($this->_field_data as $field => $row)
 		{
-			// Fetch the data from the corresponding $_POST array and cache it in the _field_data array.
+			// 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)
+			if ($row['is_array'] === TRUE)
 			{
-				$this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']);
+				$this->_field_data[$field]['postdata'] = $this->_reduce_array($validation_array, $row['keys']);
 			}
 			else
 			{
-				if (isset($_POST[$field]) AND $_POST[$field] != "")
+				if (isset($validation_array[$field]) AND $validation_array[$field] != "")
 				{
-					$this->_field_data[$field]['postdata'] = $_POST[$field];
+					$this->_field_data[$field]['postdata'] = $validation_array[$field];
 				}
 			}
 
@@ -364,14 +395,7 @@
 		// Now we need to re-set the POST data with the new, processed data
 		$this->_reset_post_array();
 
-		// No errors, validation passes!
-		if ($total_errors == 0)
-		{
-			return TRUE;
-		}
-
-		// Validation fails
-		return FALSE;
+		return ($total_errors === 0);
 	}
 
 	// --------------------------------------------------------------------
@@ -379,7 +403,6 @@
 	/**
 	 * Traverse a multidimensional $_POST array index until the data is found
 	 *
-	 * @access	private
 	 * @param	array
 	 * @param	array
 	 * @param	integer
@@ -387,23 +410,9 @@
 	 */
 	protected function _reduce_array($array, $keys, $i = 0)
 	{
-		if (is_array($array))
+		if (is_array($array) && isset($keys[$i]))
 		{
-			if (isset($keys[$i]))
-			{
-				if (isset($array[$keys[$i]]))
-				{
-					$array = $this->_reduce_array($array[$keys[$i]], $keys, ($i+1));
-				}
-				else
-				{
-					return NULL;
-				}
-			}
-			else
-			{
-				return $array;
-			}
+			return isset($array[$keys[$i]]) ? $this->_reduce_array($array[$keys[$i]], $keys, ($i+1)) : NULL;
 		}
 
 		return $array;
@@ -414,7 +423,6 @@
 	/**
 	 * Re-populate the _POST array with our finalized and processed data
 	 *
-	 * @access	private
 	 * @return	null
 	 */
 	protected function _reset_post_array()
@@ -423,7 +431,7 @@
 		{
 			if ( ! is_null($row['postdata']))
 			{
-				if ($row['is_array'] == FALSE)
+				if ($row['is_array'] === FALSE)
 				{
 					if (isset($_POST[$row['field']]))
 					{
@@ -436,7 +444,7 @@
 					$post_ref =& $_POST;
 
 					// before we assign values, make a reference to the right POST key
-					if (count($row['keys']) == 1)
+					if (count($row['keys']) === 1)
 					{
 						$post_ref =& $post_ref[current($row['keys'])];
 					}
@@ -472,7 +480,6 @@
 	/**
 	 * Executes the Validation routines
 	 *
-	 * @access	private
 	 * @param	array
 	 * @param	array
 	 * @param	mixed
@@ -514,7 +521,7 @@
 		// --------------------------------------------------------------------
 
 		// Isset Test. Typically this rule will only apply to checkboxes.
-		if (is_null($postdata) AND $callback == FALSE)
+		if (is_null($postdata) AND $callback === FALSE)
 		{
 			if (in_array('isset', $rules, TRUE) OR in_array('required', $rules))
 			{
@@ -605,7 +612,7 @@
 				$result = $this->CI->$rule($postdata, $param);
 
 				// Re-assign the result to the master data array
-				if ($_in_array == TRUE)
+				if ($_in_array === TRUE)
 				{
 					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
 				}
@@ -630,7 +637,7 @@
 					{
 						$result = $rule($postdata);
 
-						if ($_in_array == TRUE)
+						if ($_in_array === TRUE)
 						{
 							$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
 						}
@@ -649,7 +656,7 @@
 
 				$result = $this->$rule($postdata, $param);
 
-				if ($_in_array == TRUE)
+				if ($_in_array === TRUE)
 				{
 					$this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result;
 				}
@@ -676,7 +683,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"
-				if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label']))
+				if (isset($this->_field_data[$param], $this->_field_data[$param]['label']))
 				{
 					$param = $this->_translate_fieldname($this->_field_data[$param]['label']);
 				}
@@ -702,7 +709,6 @@
 	/**
 	 * Translate a field name
 	 *
-	 * @access	private
 	 * @param	string	the field name
 	 * @return	string
 	 */
@@ -710,7 +716,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 (substr($fieldname, 0, 5) === 'lang:')
 		{
 			// Grab the variable
 			$line = substr($fieldname, 5);
@@ -733,14 +739,13 @@
 	 * Permits you to repopulate a form field with the value it was submitted
 	 * with, or, if that value doesn't exist, with the default
 	 *
-	 * @access	public
 	 * @param	string	the field name
 	 * @param	string
-	 * @return	void
+	 * @return	string
 	 */
 	public function set_value($field = '', $default = '')
 	{
-		if ( ! isset($this->_field_data[$field]))
+		if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
 		{
 			return $default;
 		}
@@ -763,20 +768,15 @@
 	 * Enables pull-down lists to be set to the value the user
 	 * selected in the event of an error
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
 	public function set_select($field = '', $value = '', $default = FALSE)
 	{
-		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
+		if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
 		{
-			if ($default === TRUE AND count($this->_field_data) === 0)
-			{
-				return ' selected="selected"';
-			}
-			return '';
+			return ($default === TRUE && count($this->_field_data) === 0) ? ' selected="selected"' : '';
 		}
 
 		$field = $this->_field_data[$field]['postdata'];
@@ -788,12 +788,9 @@
 				return '';
 			}
 		}
-		else
+		elseif (($field == '' OR $value == '') OR ($field != $value))
 		{
-			if (($field == '' OR $value == '') OR ($field != $value))
-			{
-				return '';
-			}
+			return '';
 		}
 
 		return ' selected="selected"';
@@ -807,20 +804,15 @@
 	 * Enables radio buttons to be set to the value the user
 	 * selected in the event of an error
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
 	public function set_radio($field = '', $value = '', $default = FALSE)
 	{
-		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
+		if ( ! isset($this->_field_data[$field], $this->_field_data[$field]['postdata']))
 		{
-			if ($default === TRUE AND count($this->_field_data) === 0)
-			{
-				return ' checked="checked"';
-			}
-			return '';
+			return ($default === TRUE && count($this->_field_data) === 0) ? ' checked="checked"' : '';
 		}
 
 		$field = $this->_field_data[$field]['postdata'];
@@ -851,40 +843,14 @@
 	 * Enables checkboxes to be set to the value the user
 	 * selected in the event of an error
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	string
 	 */
 	public function set_checkbox($field = '', $value = '', $default = FALSE)
 	{
-		if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata']))
-		{
-			if ($default === TRUE AND count($this->_field_data) === 0)
-			{
-				return ' checked="checked"';
-			}
-			return '';
-		}
-
-		$field = $this->_field_data[$field]['postdata'];
-
-		if (is_array($field))
-		{
-			if ( ! in_array($value, $field))
-			{
-				return '';
-			}
-		}
-		else
-		{
-			if (($field == '' OR $value == '') OR ($field != $value))
-			{
-				return '';
-			}
-		}
-
-		return ' checked="checked"';
+		// Logic is exactly the same as for radio fields
+		return $this->set_radio($field, $value, $default);
 	}
 
 	// --------------------------------------------------------------------
@@ -892,20 +858,12 @@
 	/**
 	 * Required
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function required($str)
 	{
-		if ( ! is_array($str))
-		{
-			return (trim($str) == '') ? FALSE : TRUE;
-		}
-		else
-		{
-			return ( ! empty($str));
-		}
+		return ( ! is_array($str)) ? (trim($str) !== '') : ( ! empty($str));
 	}
 
 	// --------------------------------------------------------------------
@@ -913,19 +871,13 @@
 	/**
 	 * Performs a Regular Expression match test.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	regex
 	 * @return	bool
 	 */
 	public function regex_match($str, $regex)
 	{
-		if ( ! preg_match($regex, $str))
-		{
-			return FALSE;
-		}
-
-		return  TRUE;
+		return (bool) preg_match($regex, $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -933,29 +885,29 @@
 	/**
 	 * Match one field to another
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	field
 	 * @return	bool
 	 */
 	public function matches($str, $field)
 	{
-		if ( ! isset($_POST[$field]))
+		$validation_array = ( ! empty($this->validation_data)) ? $this->validation_data : $_POST;		
+		if ( ! isset($validation_array[$field]))
 		{
 			return FALSE;
 		}
 
-		$field = $_POST[$field];
-
-		return ($str !== $field) ? FALSE : TRUE;
+		return ($str === $validation_array[$field]);
 	}
 
 	// --------------------------------------------------------------------
 
 	/**
-	 * Match one field to another
+	 * Is Unique
 	 *
-	 * @access	public
+	 * Check if the input value doesn't already exist
+	 * in the specified database field.
+	 *
 	 * @param	string
 	 * @param	field
 	 * @return	bool
@@ -976,24 +928,23 @@
 	/**
 	 * Minimum Length
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	value
 	 * @return	bool
 	 */
 	public function min_length($str, $val)
 	{
-		if (preg_match("/[^0-9]/", $val))
+		if (preg_match('/[^0-9]/', $val))
 		{
 			return FALSE;
 		}
 
 		if (function_exists('mb_strlen'))
 		{
-			return (mb_strlen($str) < $val) ? FALSE : TRUE;
+			return ! (mb_strlen($str) < $val);
 		}
 
-		return (strlen($str) < $val) ? FALSE : TRUE;
+		return ! (strlen($str) < $val);
 	}
 
 	// --------------------------------------------------------------------
@@ -1001,24 +952,23 @@
 	/**
 	 * Max Length
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	value
 	 * @return	bool
 	 */
 	public function max_length($str, $val)
 	{
-		if (preg_match("/[^0-9]/", $val))
+		if (preg_match('/[^0-9]/', $val))
 		{
 			return FALSE;
 		}
 
 		if (function_exists('mb_strlen'))
 		{
-			return (mb_strlen($str) > $val) ? FALSE : TRUE;
+			return ! (mb_strlen($str) > $val);
 		}
 
-		return (strlen($str) > $val) ? FALSE : TRUE;
+		return ! (strlen($str) > $val);
 	}
 
 	// --------------------------------------------------------------------
@@ -1026,24 +976,23 @@
 	/**
 	 * Exact Length
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	value
 	 * @return	bool
 	 */
 	public function exact_length($str, $val)
 	{
-		if (preg_match("/[^0-9]/", $val))
+		if (preg_match('/[^0-9]/', $val))
 		{
 			return FALSE;
 		}
 
 		if (function_exists('mb_strlen'))
 		{
-			return (mb_strlen($str) != $val) ? FALSE : TRUE;
+			return (mb_strlen($str) == $val);
 		}
 
-		return (strlen($str) != $val) ? FALSE : TRUE;
+		return (strlen($str) == $val);
 	}
 
 	// --------------------------------------------------------------------
@@ -1051,13 +1000,12 @@
 	/**
 	 * Valid Email
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function valid_email($str)
 	{
-		return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
+		return (bool) preg_match('/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1065,7 +1013,6 @@
 	/**
 	 * Valid Emails
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -1078,7 +1025,7 @@
 
 		foreach (explode(',', $str) as $email)
 		{
-			if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE)
+			if (trim($email) !== '' && $this->valid_email(trim($email)) === FALSE)
 			{
 				return FALSE;
 			}
@@ -1092,7 +1039,6 @@
 	/**
 	 * Validate IP Address
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -1106,13 +1052,12 @@
 	/**
 	 * Alpha
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function alpha($str)
 	{
-		return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE;
+		return (bool) preg_match('/^[a-z]+$/i', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1120,13 +1065,12 @@
 	/**
 	 * Alpha-numeric
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function alpha_numeric($str)
 	{
-		return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE;
+		return (bool) preg_match('/^[a-z0-9]+$/i', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1134,13 +1078,12 @@
 	/**
 	 * Alpha-numeric with underscores and dashes
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function alpha_dash($str)
 	{
-		return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE;
+		return (bool) preg_match('/^[a-z0-9_-]+$/i', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1148,13 +1091,12 @@
 	/**
 	 * Numeric
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function numeric($str)
 	{
-		return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
+		return (bool) preg_match('/^[\-+]?[0-9]*\.?[0-9]+$/', $str);
 
 	}
 
@@ -1163,13 +1105,12 @@
 	/**
 	 * Is Numeric
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function is_numeric($str)
 	{
-		return ( ! is_numeric($str)) ? FALSE : TRUE;
+		return is_numeric($str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1177,7 +1118,6 @@
 	/**
 	 * Integer
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -1191,7 +1131,6 @@
 	/**
 	 * Decimal number
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -1205,7 +1144,6 @@
 	/**
 	 * Greather than
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -1223,7 +1161,6 @@
 	/**
 	 * Less than
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -1241,13 +1178,12 @@
 	/**
 	 * Is a Natural number  (0,1,2,3, etc.)
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function is_natural($str)
 	{
-		return (bool) preg_match( '/^[0-9]+$/', $str);
+		return (bool) preg_match('/^[0-9]+$/', $str);
 	}
 
 	// --------------------------------------------------------------------
@@ -1255,23 +1191,12 @@
 	/**
 	 * Is a Natural number, but not a zero  (1,2,3, etc.)
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function is_natural_no_zero($str)
 	{
-		if ( ! preg_match( '/^[0-9]+$/', $str))
-		{
-			return FALSE;
-		}
-
-		if ($str == 0)
-		{
-			return FALSE;
-		}
-
-		return TRUE;
+		return ($str != 0 && preg_match('/^[0-9]+$/', $str));
 	}
 
 	// --------------------------------------------------------------------
@@ -1282,7 +1207,6 @@
 	 * Tests a string for characters outside of the Base64 alphabet
 	 * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -1299,7 +1223,6 @@
 	 * This function allows HTML to be safely shown in a form.
 	 * Special characters are converted.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -1320,7 +1243,7 @@
 			return $data;
 		}
 
-		return str_replace(array("'", '"', '<', '>'), array("&#39;", "&quot;", '&lt;', '&gt;'), stripslashes($data));
+		return str_replace(array("'", '"', '<', '>'), array('&#39;', '&quot;', '&lt;', '&gt;'), stripslashes($data));
 	}
 
 	// --------------------------------------------------------------------
@@ -1328,7 +1251,6 @@
 	/**
 	 * Prep URL
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -1339,7 +1261,7 @@
 			return '';
 		}
 
-		if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://')
+		if (substr($str, 0, 7) !== 'http://' && substr($str, 0, 8) !== 'https://')
 		{
 			$str = 'http://'.$str;
 		}
@@ -1352,7 +1274,6 @@
 	/**
 	 * Strip Image Tags
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -1366,7 +1287,6 @@
 	/**
 	 * XSS Clean
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -1380,7 +1300,6 @@
 	/**
 	 * Convert PHP tags to entities
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -1388,9 +1307,26 @@
 	{
 		return str_replace(array('<?php', '<?PHP', '<?', '?>'),  array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
 	}
-
+	
+	// --------------------------------------------------------------------
+	
+    /**
+     * Reset validation vars
+	 * 
+	 * Prevents subsequent validation routines from being affected by the 
+	 * results of any previous validation routine due to the CI singleton.
+	 * 
+     * @return void
+     */
+    protected function _reset_validation()
+    {
+		$this->_field_data = array();
+		$this->_config_rules = array();
+		$this->_error_array = array();
+		$this->_error_messages = array();
+		$this->error_string = '';
+    }
 }
-// END Form Validation Class
 
 /* End of file Form_validation.php */
 /* Location: ./system/libraries/Form_validation.php */
diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php
index 99850a9..ab395b0 100644
--- a/system/libraries/Ftp.php
+++ b/system/libraries/Ftp.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php
index 20ca1f0..9826eab 100644
--- a/system/libraries/Image_lib.php
+++ b/system/libraries/Image_lib.php
@@ -1,4 +1,4 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Image Manipulation class
  *
@@ -67,8 +65,8 @@
 	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
-	public $wm_font_color		= '#ffffff';	// Text color
-	public $wm_shadow_color	= '';			// Dropshadow color
+	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
 
@@ -85,15 +83,9 @@
 	public $create_fnc			= 'imagecreatetruecolor';
 	public $copy_fnc			= 'imagecopyresampled';
 	public $error_msg			= array();
-	public $wm_use_drop_shadow	= FALSE;
+	protected $wm_use_drop_shadow	= FALSE;
 	public $wm_use_truetype	= FALSE;
 
-	/**
-	 * Constructor
-	 *
-	 * @param	string
-	 * @return	void
-	 */
 	public function __construct($props = array())
 	{
 		if (count($props) > 0)
@@ -101,7 +93,7 @@
 			$this->initialize($props);
 		}
 
-		log_message('debug', "Image Lib Class Initialized");
+		log_message('debug', 'Image Lib Class Initialized');
 	}
 
 	// --------------------------------------------------------------------
@@ -111,7 +103,6 @@
 	 *
 	 * Resets values in case this class is used in a loop
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function clear()
@@ -154,42 +145,58 @@
 	/**
 	 * initialize image preferences
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	bool
 	 */
 	public function initialize($props = array())
 	{
-		/*
-		 * Convert array elements into class variables
-		 */
+		// Convert array elements into class variables
 		if (count($props) > 0)
 		{
 			foreach ($props as $key => $val)
 			{
-				$this->$key = $val;
+				if (property_exists($this, $key))
+				{
+					if (in_array($key, array('wm_font_color', 'wm_shadow_color')))
+					{
+						if (preg_match('/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i', $val, $matches))
+						{
+							/* $matches[1] contains our hex color value, but it might be
+							 * both in the full 6-length format or the shortened 3-length
+							 * value.
+							 * We'll later need the full version, so we keep it if it's
+							 * already there and if not - we'll convert to it. We can
+							 * access string characters by their index as in an array,
+							 * so we'll do that and use concatenation to form the final
+							 * value:
+							 */
+							$val = (strlen($matches[1]) === 6)
+								? '#'.$matches[1]
+								: '#'.$matches[1][0].$matches[1][0].$matches[1][1].$matches[1][1].$matches[1][2].$matches[1][2];
+						}
+						else
+						{
+							continue;
+						}
+					}
+
+					$this->$key = $val;
+				}
 			}
 		}
 
-		/*
-		 * Is there a source image?
-		 *
-		 * If not, there's no reason to continue
-		 *
-		 */
+		// Is there a source image? If not, there's no reason to continue
 		if ($this->source_image == '')
 		{
 			$this->set_error('imglib_source_image_required');
 			return FALSE;
 		}
 
-		/*
-		 * Is getimagesize() Available?
+		/* Is getimagesize() available?
 		 *
 		 * We use it to determine the image properties (width/height).
-		 * Note:  We need to figure out how to determine image
+		 * Note: We need to figure out how to determine image
 		 * properties using ImageMagick and NetPBM
-		 *
 		 */
 		if ( ! function_exists('getimagesize'))
 		{
@@ -199,17 +206,15 @@
 
 		$this->image_library = strtolower($this->image_library);
 
-		/*
-		 * Set the full server path
+		/* Set the full server path
 		 *
 		 * The source image may or may not contain a path.
 		 * Either way, we'll try use realpath to generate the
 		 * full server path in order to more reliably read it.
-		 *
 		 */
-		if (function_exists('realpath') AND @realpath($this->source_image) !== FALSE)
+		if (function_exists('realpath') && @realpath($this->source_image) !== FALSE)
 		{
-			$full_source_path = str_replace("\\", "/", realpath($this->source_image));
+			$full_source_path = str_replace('\\', '/', realpath($this->source_image));
 		}
 		else
 		{
@@ -231,64 +236,58 @@
 		 *
 		 * If the user has set a "new_image" name it means
 		 * we are making a copy of the source image. If not
-		 * it means we are altering the original.  We'll
+		 * it means we are altering the original. We'll
 		 * set the destination filename and path accordingly.
-		 *
 		 */
 		if ($this->new_image == '')
 		{
 			$this->dest_image = $this->source_image;
 			$this->dest_folder = $this->source_folder;
 		}
+		elseif (strpos($this->new_image, '/') === FALSE)
+		{
+			$this->dest_folder = $this->source_folder;
+			$this->dest_image = $this->new_image;
+		}
 		else
 		{
-			if (strpos($this->new_image, '/') === FALSE)
+			if (strpos($this->new_image, '/') === FALSE AND strpos($this->new_image, '\\') === FALSE)
 			{
-				$this->dest_folder = $this->source_folder;
-				$this->dest_image = $this->new_image;
+				$full_dest_path = str_replace('\\', '/', realpath($this->new_image));
 			}
 			else
 			{
-				if (function_exists('realpath') AND @realpath($this->new_image) !== FALSE)
-				{
-					$full_dest_path = str_replace("\\", "/", realpath($this->new_image));
-				}
-				else
-				{
-					$full_dest_path = $this->new_image;
-				}
+				$full_dest_path = $this->new_image;
+			}
 
-				// Is there a file name?
-				if ( ! preg_match("#\.(jpg|jpeg|gif|png)$#i", $full_dest_path))
-				{
-					$this->dest_folder = $full_dest_path.'/';
-					$this->dest_image = $this->source_image;
-				}
-				else
-				{
-					$x = explode('/', $full_dest_path);
-					$this->dest_image = end($x);
-					$this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
-				}
+			// Is there a file name?
+			if ( ! preg_match('#\.(jpg|jpeg|gif|png)$#i', $full_dest_path))
+			{
+				$this->dest_folder = $full_dest_path.'/';
+				$this->dest_image = $this->source_image;
+			}
+			else
+			{
+				$x = explode('/', $full_dest_path);
+				$this->dest_image = end($x);
+				$this->dest_folder = str_replace($this->dest_image, '', $full_dest_path);
 			}
 		}
 
-		/*
-		 * Compile the finalized filenames/paths
+		/* Compile the finalized filenames/paths
 		 *
 		 * We'll create two master strings containing the
 		 * full server path to the source image and the
 		 * full server path to the destination image.
 		 * 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 == '')
 		{
 			$this->thumb_marker = '';
 		}
 
-		$xp	= $this->explode_name($this->dest_image);
+		$xp = $this->explode_name($this->dest_image);
 
 		$filename = $xp['name'];
 		$file_ext = $xp['ext'];
@@ -296,69 +295,58 @@
 		$this->full_src_path = $this->source_folder.$this->source_image;
 		$this->full_dst_path = $this->dest_folder.$filename.$this->thumb_marker.$file_ext;
 
-		/*
-		 * Should we maintain image proportions?
+		/* Should we maintain image proportions?
 		 *
 		 * When creating thumbs or copies, the target width/height
 		 * might not be in correct proportion with the source
-		 * image's width/height.  We'll recalculate it here.
-		 *
+		 * image's width/height. We'll recalculate it here.
 		 */
-		if ($this->maintain_ratio === TRUE && ($this->width != '' AND $this->height != ''))
+		if ($this->maintain_ratio === TRUE && ($this->width != 0 OR $this->height != 0))
 		{
 			$this->image_reproportion();
 		}
 
-		/*
-		 * Was a width and height specified?
+		/* Was a width and height specified?
 		 *
-		 * If the destination width/height was
-		 * not submitted we will use the values
-		 * from the actual file
-		 *
+		 * If the destination width/height was not submitted we
+		 * will use the values from the actual file
 		 */
 		if ($this->width == '')
+		{
 			$this->width = $this->orig_width;
+		}
 
 		if ($this->height == '')
+		{
 			$this->height = $this->orig_height;
+		}
 
 		// Set the quality
-		$this->quality = trim(str_replace("%", "", $this->quality));
+		$this->quality = trim(str_replace('%', '', $this->quality));
 
-		if ($this->quality == '' OR $this->quality == 0 OR ! is_numeric($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 ! is_numeric($this->x_axis)) ? 0 : $this->x_axis;
-		$this->y_axis = ($this->y_axis == '' OR ! is_numeric($this->y_axis)) ? 0 : $this->y_axis;
+		$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;
 
 		// Watermark-related Stuff...
-		if ($this->wm_font_color != '')
-		{
-			if (strlen($this->wm_font_color) == 6)
-			{
-				$this->wm_font_color = '#'.$this->wm_font_color;
-			}
-		}
-
-		if ($this->wm_shadow_color != '')
-		{
-			if (strlen($this->wm_shadow_color) == 6)
-			{
-				$this->wm_shadow_color = '#'.$this->wm_shadow_color;
-			}
-		}
-
 		if ($this->wm_overlay_path != '')
 		{
-			$this->wm_overlay_path = str_replace("\\", "/", realpath($this->wm_overlay_path));
+			$this->wm_overlay_path = str_replace('\\', '/', realpath($this->wm_overlay_path));
 		}
 
 		if ($this->wm_shadow_color != '')
 		{
 			$this->wm_use_drop_shadow = TRUE;
 		}
+		elseif ($this->wm_use_drop_shadow == TRUE && $this->wm_shadow_color == '')
+		{
+			$this->wm_use_drop_shadow = FALSE;
+		}
 
 		if ($this->wm_font_path != '')
 		{
@@ -376,18 +364,11 @@
 	 * This is a wrapper function that chooses the proper
 	 * resize function based on the protocol specified
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function resize()
 	{
-		$protocol = 'image_process_'.$this->image_library;
-
-		if (preg_match('/gd2$/i', $protocol))
-		{
-			$protocol = 'image_process_gd';
-		}
-
+		$protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
 		return $this->$protocol('resize');
 	}
 
@@ -399,18 +380,11 @@
 	 * This is a wrapper function that chooses the proper
 	 * cropping function based on the protocol specified
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function crop()
 	{
-		$protocol = 'image_process_'.$this->image_library;
-
-		if (preg_match('/gd2$/i', $protocol))
-		{
-			$protocol = 'image_process_gd';
-		}
-
+		$protocol = ($this->image_library === 'gd2') ? 'image_process_gd' : 'image_process_'.$this->image_library;
 		return $this->$protocol('crop');
 	}
 
@@ -422,7 +396,6 @@
 	 * This is a wrapper function that chooses the proper
 	 * rotation function based on the protocol specified
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function rotate()
@@ -448,23 +421,16 @@
 			$this->height	= $this->orig_height;
 		}
 
-
 		// Choose resizing function
-		if ($this->image_library == 'imagemagick' OR $this->image_library == 'netpbm')
+		if ($this->image_library === 'imagemagick' OR $this->image_library === 'netpbm')
 		{
 			$protocol = 'image_process_'.$this->image_library;
-
 			return $this->$protocol('rotate');
 		}
 
-		if ($this->rotation_angle == 'hor' OR $this->rotation_angle == 'vrt')
-		{
-			return $this->image_mirror_gd();
-		}
-		else
-		{
-			return $this->image_rotate_gd();
-		}
+		return ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
+			? $this->image_mirror_gd()
+			: $this->image_rotate_gd();
 	}
 
 	// --------------------------------------------------------------------
@@ -474,7 +440,6 @@
 	 *
 	 * This function will resize or crop
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -484,26 +449,20 @@
 
 		// 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)
+		if ($this->dynamic_output === FALSE && $this->orig_width == $this->width && $this->orig_height == $this->height)
 		{
-			if ($this->orig_width == $this->width AND $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)
-				{
-					if (@copy($this->full_src_path, $this->full_dst_path))
-					{
-						@chmod($this->full_dst_path, FILE_WRITE_MODE);
-					}
-				}
-
-				return TRUE;
+				@chmod($this->full_dst_path, FILE_WRITE_MODE);
 			}
+
+			return TRUE;
 		}
 
 		// Let's set up our values based on the action
 		if ($action == 'crop')
 		{
-			//  Reassign the source width/height if cropping
+			// Reassign the source width/height if cropping
 			$this->orig_width  = $this->width;
 			$this->orig_height = $this->height;
 
@@ -527,14 +486,15 @@
 			return FALSE;
 		}
 
-		//  Create The Image
-		//
-		//  old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
-		//  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' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE)
-		if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor'))
+		/* Create the image
+		 *
+		 * Old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater"
+		 * 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'))
 		{
 			$create	= 'imagecreatetruecolor';
 			$copy	= 'imagecopyresampled';
@@ -555,21 +515,17 @@
 
 		$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
+		// Show the image
 		if ($this->dynamic_output == TRUE)
 		{
 			$this->image_display_gd($dst_img);
 		}
-		else
+		elseif ( ! $this->image_save_gd($dst_img)) // Or save it
 		{
-			// Or save it
-			if ( ! $this->image_save_gd($dst_img))
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
 
-		//  Kill the file handles
+		// Kill the file handles
 		imagedestroy($dst_img);
 		imagedestroy($src_img);
 
@@ -586,7 +542,6 @@
 	 *
 	 * This function will resize, crop or rotate
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -599,44 +554,34 @@
 			return FALSE;
 		}
 
-		if ( ! preg_match("/convert$/i", $this->library_path))
+		if ( ! preg_match('/convert$/i', $this->library_path))
 		{
-			$this->library_path = rtrim($this->library_path, '/').'/';
-
-			$this->library_path .= 'convert';
+			$this->library_path = rtrim($this->library_path, '/').'/convert';
 		}
 
 		// Execute the command
-		$cmd = $this->library_path." -quality ".$this->quality;
+		$cmd = $this->library_path.' -quality '.$this->quality;
 
 		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";
+			$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')
 		{
-			switch ($this->rotation_angle)
-			{
-				case 'hor'	: $angle = '-flop';
-					break;
-				case 'vrt'	: $angle = '-flip';
-					break;
-				default		: $angle = '-rotate '.$this->rotation_angle;
-					break;
-			}
+			$angle = ($this->rotation_angle === 'hor' OR $this->rotation_angle === 'vrt')
+					? '-flop' : '-rotate '.$this->rotation_angle;
 
-			$cmd .= " ".$angle." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
+			$cmd .= ' '.$angle.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
 		}
-		else  // Resize
+		else // Resize
 		{
-			$cmd .= " -resize ".$this->width."x".$this->height." \"$this->full_src_path\" \"$this->full_dst_path\" 2>&1";
+			$cmd .= ' -resize '.$this->width.'x'.$this->height.' "'.$this->full_src_path.'" "'.$this->full_dst_path.'" 2>&1';
 		}
 
 		$retval = 1;
-
 		@exec($cmd, $output, $retval);
 
-		//	Did it work?
+		// Did it work?
 		if ($retval > 0)
 		{
 			$this->set_error('imglib_image_process_failed');
@@ -656,7 +601,6 @@
 	 *
 	 * This function will resize, crop or rotate
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
@@ -668,7 +612,7 @@
 			return FALSE;
 		}
 
-		//  Build the resizing command
+		// Build the resizing command
 		switch ($this->image_type)
 		{
 			case 1 :
@@ -715,10 +659,9 @@
 		$cmd = $this->library_path.$cmd_in.' '.$this->full_src_path.' | '.$cmd_inner.' | '.$cmd_out.' > '.$this->dest_folder.'netpbm.tmp';
 
 		$retval = 1;
-
 		@exec($cmd, $output, $retval);
 
-		//  Did it work?
+		// Did it work?
 		if ($retval > 0)
 		{
 			$this->set_error('imglib_image_process_failed');
@@ -729,7 +672,7 @@
 		// If you try manipulating the original it fails so
 		// we have to rename the temp file.
 		copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path);
-		unlink ($this->dest_folder.'netpbm.tmp');
+		unlink($this->dest_folder.'netpbm.tmp');
 		@chmod($this->full_dst_path, FILE_WRITE_MODE);
 
 		return TRUE;
@@ -740,12 +683,11 @@
 	/**
 	 * Image Rotate Using GD
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function image_rotate_gd()
 	{
-		//  Create the image handle
+		// Create the image handle
 		if ( ! ($src_img = $this->image_create_gd()))
 		{
 			return FALSE;
@@ -758,29 +700,24 @@
 
 		$white	= imagecolorallocate($src_img, 255, 255, 255);
 
-		//  Rotate it!
+		// Rotate it!
 		$dst_img = imagerotate($src_img, $this->rotation_angle, $white);
 
-		//  Save the Image
+		// Show the image
 		if ($this->dynamic_output == TRUE)
 		{
 			$this->image_display_gd($dst_img);
 		}
-		else
+		elseif ( ! $this->image_save_gd($dst_img)) // ... or save it
 		{
-			// Or save it
-			if ( ! $this->image_save_gd($dst_img))
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
 
-		//  Kill the file handles
+		// Kill the file handles
 		imagedestroy($dst_img);
 		imagedestroy($src_img);
 
 		// Set the file to 777
-
 		@chmod($this->full_dst_path, FILE_WRITE_MODE);
 
 		return TRUE;
@@ -793,7 +730,6 @@
 	 *
 	 * This function will flip horizontal or vertical
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function image_mirror_gd()
@@ -806,13 +742,10 @@
 		$width  = $this->orig_width;
 		$height = $this->orig_height;
 
-		if ($this->rotation_angle == 'hor')
+		if ($this->rotation_angle === 'hor')
 		{
-			for ($i = 0; $i < $height; $i++)
+			for ($i = 0; $i < $height; $i++, $left = 0, $right = $width-1)
 			{
-				$left  = 0;
-				$right = $width-1;
-
 				while ($left < $right)
 				{
 					$cl = imagecolorat($src_img, $left, $i);
@@ -828,11 +761,8 @@
 		}
 		else
 		{
-			for ($i = 0; $i < $width; $i++)
+			for ($i = 0; $i < $width; $i++, $top = 0, $bot = $height-1)
 			{
-				$top = 0;
-				$bot = $height-1;
-
 				while ($top < $bot)
 				{
 					$ct = imagecolorat($src_img, $i, $top);
@@ -847,21 +777,17 @@
 			}
 		}
 
-		//  Show the image
+		// Show the image
 		if ($this->dynamic_output == TRUE)
 		{
 			$this->image_display_gd($src_img);
 		}
-		else
+		elseif ( ! $this->image_save_gd($src_img)) // ... or save it
 		{
-			// Or save it
-			if ( ! $this->image_save_gd($src_img))
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
 
-		//  Kill the file handles
+		// Kill the file handles
 		imagedestroy($src_img);
 
 		// Set the file to 777
@@ -878,20 +804,12 @@
 	 * This is a wrapper function that chooses the type
 	 * of watermarking based on the specified preference.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	bool
 	 */
 	public function watermark()
 	{
-		if ($this->wm_type == 'overlay')
-		{
-			return $this->overlay_watermark();
-		}
-		else
-		{
-			return $this->text_watermark();
-		}
+		return ($this->wm_type === 'overlay') ? $this->overlay_watermark() : $this->text_watermark();
 	}
 
 	// --------------------------------------------------------------------
@@ -899,7 +817,6 @@
 	/**
 	 * Watermark - Graphic Version
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function overlay_watermark()
@@ -910,28 +827,28 @@
 			return FALSE;
 		}
 
-		//  Fetch source image properties
+		// Fetch source image properties
 		$this->get_image_properties();
 
-		//  Fetch watermark image properties
-		$props			= $this->get_image_properties($this->wm_overlay_path, TRUE);
+		// Fetch watermark image properties
+		$props		= $this->get_image_properties($this->wm_overlay_path, TRUE);
 		$wm_img_type	= $props['image_type'];
-		$wm_width		= $props['width'];
-		$wm_height		= $props['height'];
+		$wm_width	= $props['width'];
+		$wm_height	= $props['height'];
 
-		//  Create two image resources
+		// Create two image resources
 		$wm_img  = $this->image_create_gd($this->wm_overlay_path, $wm_img_type);
 		$src_img = $this->image_create_gd($this->full_src_path);
 
 		// Reverse the offset if necessary
 		// When the image is positioned at the bottom
 		// we don't want the vertical offset to push it
-		// further down.  We want the reverse, so we'll
-		// invert the offset.  Same with the horizontal
+		// further down. We want the reverse, so we'll
+		// invert the offset. Same with the horizontal
 		// offset when the image is at the right
 
-		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
-		$this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
+		$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')
 			$this->wm_vrt_offset = $this->wm_vrt_offset * -1;
@@ -939,34 +856,32 @@
 		if ($this->wm_hor_alignment == 'R')
 			$this->wm_hor_offset = $this->wm_hor_offset * -1;
 
-		//  Set the base x and y axis values
+		// Set the base x and y axis values
 		$x_axis = $this->wm_hor_offset + $this->wm_padding;
 		$y_axis = $this->wm_vrt_offset + $this->wm_padding;
 
-		//  Set the vertical position
-		switch ($this->wm_vrt_alignment)
+		// Set the vertical position
+		if ($this->wm_vrt_alignment === 'M')
 		{
-			case 'T':
-				break;
-			case 'M':	$y_axis += ($this->orig_height / 2) - ($wm_height / 2);
-				break;
-			case 'B':	$y_axis += $this->orig_height - $wm_height;
-				break;
+			$y_axis += ($this->orig_height / 2) - ($wm_height / 2);
+		}
+		elseif ($this->wm_vrt_alignment === 'B')
+		{
+			$y_axis += $this->orig_height - $wm_height;
 		}
 
-		//  Set the horizontal position
-		switch ($this->wm_hor_alignment)
+		// Set the horizontal position
+		if ($this->wm_hor_alignment === 'C')
 		{
-			case 'L':
-				break;
-			case 'C':	$x_axis += ($this->orig_width / 2) - ($wm_width / 2);
-				break;
-			case 'R':	$x_axis += $this->orig_width - $wm_width;
-				break;
+			$x_axis += ($this->orig_width / 2) - ($wm_width / 2);
+		}
+		elseif ($this->wm_hor_alignment === 'R')
+		{
+			$x_axis += $this->orig_width - $wm_width;
 		}
 
 		//  Build the finalized image
-		if ($wm_img_type == 3 AND function_exists('imagealphablending'))
+		if ($wm_img_type == 3 && function_exists('imagealphablending'))
 		{
 			@imagealphablending($src_img, TRUE);
 		}
@@ -988,17 +903,14 @@
 			imagecopymerge($src_img, $wm_img, $x_axis, $y_axis, 0, 0, $wm_width, $wm_height, $this->wm_opacity);
 		}
 
-		//  Output the image
+		// Output the image
 		if ($this->dynamic_output == TRUE)
 		{
 			$this->image_display_gd($src_img);
 		}
-		else
+		elseif ( ! $this->image_save_gd($src_img)) // ... or save it
 		{
-			if ( ! $this->image_save_gd($src_img))
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
 
 		imagedestroy($src_img);
@@ -1012,7 +924,6 @@
 	/**
 	 * Watermark - Text Version
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function text_watermark()
@@ -1022,35 +933,20 @@
 			return FALSE;
 		}
 
-		if ($this->wm_use_truetype == TRUE AND ! 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;
 		}
 
-		//  Fetch source image properties
+		// Fetch source image properties
 		$this->get_image_properties();
 
-		// Set RGB values for text and shadow
-		$this->wm_font_color	= str_replace('#', '', $this->wm_font_color);
-		$this->wm_shadow_color	= str_replace('#', '', $this->wm_shadow_color);
-
-		$R1 = hexdec(substr($this->wm_font_color, 0, 2));
-		$G1 = hexdec(substr($this->wm_font_color, 2, 2));
-		$B1 = hexdec(substr($this->wm_font_color, 4, 2));
-
-		$R2 = hexdec(substr($this->wm_shadow_color, 0, 2));
-		$G2 = hexdec(substr($this->wm_shadow_color, 2, 2));
-		$B2 = hexdec(substr($this->wm_shadow_color, 4, 2));
-
-		$txt_color	= imagecolorclosest($src_img, $R1, $G1, $B1);
-		$drp_color	= imagecolorclosest($src_img, $R2, $G2, $B2);
-
 		// Reverse the vertical offset
 		// When the image is positioned at the bottom
 		// we don't want the vertical offset to push it
-		// further down.  We want the reverse, so we'll
-		// invert the offset.  Note: The horizontal
+		// further down. We want the reverse, so we'll
+		// invert the offset. Note: The horizontal
 		// offset flips itself automatically
 
 		if ($this->wm_vrt_alignment == 'B')
@@ -1065,7 +961,9 @@
 		if ($this->wm_use_truetype == TRUE)
 		{
 			if ($this->wm_font_size == '')
-				$this->wm_font_size = '17';
+			{
+				$this->wm_font_size = 17;
+			}
 
 			$fontwidth  = $this->wm_font_size-($this->wm_font_size/4);
 			$fontheight = $this->wm_font_size;
@@ -1081,58 +979,64 @@
 		$x_axis = $this->wm_hor_offset + $this->wm_padding;
 		$y_axis = $this->wm_vrt_offset + $this->wm_padding;
 
-		// Set verticle alignment
 		if ($this->wm_use_drop_shadow == FALSE)
 			$this->wm_shadow_distance = 0;
 
 		$this->wm_vrt_alignment = strtoupper(substr($this->wm_vrt_alignment, 0, 1));
 		$this->wm_hor_alignment = strtoupper(substr($this->wm_hor_alignment, 0, 1));
 
-		switch ($this->wm_vrt_alignment)
+		// Set verticle alignment
+		if ($this->wm_vrt_alignment === 'M')
 		{
-			case	 "T" :
-				break;
-			case "M":	$y_axis += ($this->orig_height/2)+($fontheight/2);
-				break;
-			case "B":	$y_axis += ($this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight/2));
-				break;
+			$y_axis += ($this->orig_height / 2) + ($fontheight / 2);
+		}
+		elseif ($this->wm_vrt_alignment === 'B')
+		{
+			$y_axis += $this->orig_height - $fontheight - $this->wm_shadow_distance - ($fontheight / 2);
 		}
 
 		$x_shad = $x_axis + $this->wm_shadow_distance;
 		$y_shad = $y_axis + $this->wm_shadow_distance;
 
-		// Set horizontal alignment
-		switch ($this->wm_hor_alignment)
+		if ($this->wm_use_drop_shadow)
 		{
-			case "L":
-				break;
-			case "R":
-						if ($this->wm_use_drop_shadow)
-							$x_shad += ($this->orig_width - $fontwidth*strlen($this->wm_text));
-							$x_axis += ($this->orig_width - $fontwidth*strlen($this->wm_text));
-				break;
-			case "C":
-						if ($this->wm_use_drop_shadow)
-							$x_shad += floor(($this->orig_width - $fontwidth*strlen($this->wm_text))/2);
-							$x_axis += floor(($this->orig_width  -$fontwidth*strlen($this->wm_text))/2);
-				break;
-		}
+			// Set horizontal alignment
+			if ($this->wm_hor_alignment === 'R')
+			{
+				$x_shad += $this->orig_width - ($fontwidth * strlen($this->wm_text));
+				$x_axis += $this->orig_width - ($fontwidth * strlen($this->wm_text));
+			}
+			elseif ($this->wm_hor_alignment === 'C')
+			{
+				$x_shad += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
+				$x_axis += floor(($this->orig_width - ($fontwidth * strlen($this->wm_text))) / 2);
+			}
 
-		//  Add the text to the source image
-		if ($this->wm_use_truetype)
-		{
-			if ($this->wm_use_drop_shadow)
+			/* Set RGB values for text and shadow
+			 *
+			 * First character is #, so we don't really need it.
+			 * Get the rest of the string and split it into 2-length
+			 * hex values:
+			 */
+			$txt_color = str_split(substr($this->wm_font_color, 1, 6), 2);
+			$txt_color = imagecolorclosest($src_img, hexdec($txt_color[0]), hexdec($txt_color[1]), hexdec($txt_color[2]));
+			$drp_color = str_split(substr($this->wm_shadow_color, 1, 6), 2);
+			$drp_color = imagecolorclosest($src_img, hexdec($drp_color[0]), hexdec($drp_color[1]), hexdec($drp_color[2]));
+
+			// Add the text to the source image
+			if ($this->wm_use_truetype)
+			{
 				imagettftext($src_img, $this->wm_font_size, 0, $x_shad, $y_shad, $drp_color, $this->wm_font_path, $this->wm_text);
 				imagettftext($src_img, $this->wm_font_size, 0, $x_axis, $y_axis, $txt_color, $this->wm_font_path, $this->wm_text);
-		}
-		else
-		{
-			if ($this->wm_use_drop_shadow)
+			}
+			else
+			{
 				imagestring($src_img, $this->wm_font_size, $x_shad, $y_shad, $this->wm_text, $drp_color);
 				imagestring($src_img, $this->wm_font_size, $x_axis, $y_axis, $this->wm_text, $txt_color);
+			}
 		}
 
-		//  Output the final image
+		// Output the final image
 		if ($this->dynamic_output == TRUE)
 		{
 			$this->image_display_gd($src_img);
@@ -1155,7 +1059,6 @@
 	 * This simply creates an image resource handle
 	 * based on the type of image being processed
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	resource
 	 */
@@ -1212,7 +1115,6 @@
 	 * Takes an image resource as input and writes the file
 	 * to the specified destination
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	bool
 	 */
@@ -1273,14 +1175,13 @@
 	/**
 	 * Dynamically outputs an image
 	 *
-	 * @access	public
 	 * @param	resource
 	 * @return	void
 	 */
 	public function image_display_gd($resource)
 	{
-		header("Content-Disposition: filename={$this->source_image};");
-		header("Content-Type: {$this->mime_type}");
+		header('Content-Disposition: filename='.$this->source_image.';');
+		header('Content-Type: '.$this->mime_type);
 		header('Content-Transfer-Encoding: binary');
 		header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT');
 
@@ -1309,38 +1210,47 @@
 	 * This function lets us re-proportion the width/height
 	 * if users choose to maintain the aspect ratio when resizing.
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function image_reproportion()
 	{
-		if ( ! is_numeric($this->width) OR ! is_numeric($this->height) OR $this->width == 0 OR $this->height == 0)
-			return;
-
-		if ( ! is_numeric($this->orig_width) OR ! is_numeric($this->orig_height) OR $this->orig_width == 0 OR $this->orig_height == 0)
-			return;
-
-		$new_width	= ceil($this->orig_width*$this->height/$this->orig_height);
-		$new_height	= ceil($this->width*$this->orig_height/$this->orig_width);
-
-		$ratio = (($this->orig_height/$this->orig_width) - ($this->height/$this->width));
-
-		if ($this->master_dim != 'width' AND $this->master_dim != 'height')
+		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))
 		{
-			$this->master_dim = ($ratio < 0) ? 'width' : 'height';
+			return;
 		}
 
-		if (($this->width != $new_width) AND ($this->height != $new_height))
+		// Sanitize so we don't call preg_match() anymore
+		$this->width = (int) $this->width;
+		$this->height = (int) $this->height;
+
+		if ($this->master_dim !== 'width' && $this->master_dim !== 'height')
 		{
-			if ($this->master_dim == 'height')
+			if ($this->width > 0 && $this->height > 0)
 			{
-				$this->width = $new_width;
+				$this->master_dim = ((($this->orig_height/$this->orig_width) - ($this->height/$this->width)) < 0)
+							? 'width' : 'height';
 			}
 			else
 			{
-				$this->height = $new_height;
+				$this->master_dim = ($this->height === 0) ? 'width' : 'height';
 			}
 		}
+		elseif (($this->master_dim === 'width' && $this->width === 0)
+			OR ($this->master_dim === 'height' && $this->height === 0))
+		{
+			return;
+		}
+
+		if ($this->master_dim === 'width')
+		{
+			$this->height = (int) ceil($this->width*$this->orig_height/$this->orig_width);
+		}
+		else
+		{
+			$this->width = (int) ceil($this->orig_width*$this->height/$this->orig_height);
+		}
 	}
 
 	// --------------------------------------------------------------------
@@ -1350,7 +1260,6 @@
 	 *
 	 * A helper function that gets info about the file
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	mixed
 	 */
@@ -1360,7 +1269,9 @@
 		// find a way to determine this using IM or NetPBM
 
 		if ($path == '')
+		{
 			$path = $this->full_src_path;
+		}
 
 		if ( ! file_exists($path))
 		{
@@ -1369,26 +1280,24 @@
 		}
 
 		$vals = getimagesize($path);
-
 		$types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
-
-		$mime = (isset($types[$vals['2']])) ? 'image/'.$types[$vals['2']] : 'image/jpg';
+		$mime = (isset($types[$vals[2]])) ? 'image/'.$types[$vals[2]] : 'image/jpg';
 
 		if ($return == TRUE)
 		{
-			$v['width']			= $vals['0'];
-			$v['height']		= $vals['1'];
-			$v['image_type']	= $vals['2'];
-			$v['size_str']		= $vals['3'];
-			$v['mime_type']		= $mime;
-
-			return $v;
+			return array(
+					'width' =>	$vals[0],
+					'height' =>	$vals[1],
+					'image_type' =>	$vals[2],
+					'size_str' =>	$vals[3],
+					'mime_type' =>	$mime
+				);
 		}
 
-		$this->orig_width	= $vals['0'];
-		$this->orig_height	= $vals['1'];
-		$this->image_type	= $vals['2'];
-		$this->size_str		= $vals['3'];
+		$this->orig_width	= $vals[0];
+		$this->orig_height	= $vals[1];
+		$this->image_type	= $vals[2];
+		$this->size_str		= $vals[3];
 		$this->mime_type	= $mime;
 
 		return TRUE;
@@ -1400,17 +1309,16 @@
 	 * Size calculator
 	 *
 	 * This function takes a known width x height and
-	 * recalculates it to a new size.  Only one
+	 * recalculates it to a new size. Only one
 	 * new variable needs to be known
 	 *
 	 *	$props = array(
-	 *					'width'			=> $width,
-	 *					'height'		=> $height,
-	 *					'new_width'		=> 40,
-	 *					'new_height'	=> ''
-	 *				  );
+	 *			'width'		=> $width,
+	 *			'height'	=> $height,
+	 *			'new_width'	=> 40,
+	 *			'new_height'	=> ''
+	 *		);
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	array
 	 */
@@ -1453,12 +1361,11 @@
 	 *
 	 * This is a helper function that extracts the extension
 	 * from the source_image.  This function lets us deal with
-	 * source_images with multiple periods, like:  my.cool.jpg
+	 * source_images with multiple periods, like: my.cool.jpg
 	 * It returns an associative array with two elements:
 	 * $array['ext']  = '.jpg';
 	 * $array['name'] = 'my.cool';
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	array
 	 */
@@ -1475,17 +1382,16 @@
 	/**
 	 * Is GD Installed?
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function gd_loaded()
 	{
 		if ( ! extension_loaded('gd'))
 		{
-			if ( ! dl('gd.so'))
-			{
-				return FALSE;
-			}
+			/* As it is stated in the PHP manual, dl() is not always available
+			 * and even if so - it could generate an E_WARNING message on failure
+			 */
+			return (function_exists('dl') && @dl('gd.so'));
 		}
 
 		return TRUE;
@@ -1496,7 +1402,6 @@
 	/**
 	 * Get GD version
 	 *
-	 * @access	public
 	 * @return	mixed
 	 */
 	public function gd_version()
@@ -1504,9 +1409,7 @@
 		if (function_exists('gd_info'))
 		{
 			$gd_version = @gd_info();
-			$gd_version = preg_replace("/\D/", "", $gd_version['GD Version']);
-
-			return $gd_version;
+			return preg_replace('/\D/', '', $gd_version['GD Version']);
 		}
 
 		return FALSE;
@@ -1517,7 +1420,6 @@
 	/**
 	 * Set error message
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
@@ -1549,17 +1451,15 @@
 	/**
 	 * Show error messages
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
 	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 Image_lib Class
 
 /* End of file Image_lib.php */
 /* Location: ./system/libraries/Image_lib.php */
diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php
index 15887cb..33df600 100644
--- a/system/libraries/Javascript.php
+++ b/system/libraries/Javascript.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -38,7 +38,7 @@
  */
 class CI_Javascript {
 
-	var $_javascript_location = 'js';
+	protected $_javascript_location = 'js';
 
 	public function __construct($params = array())
 	{
@@ -64,7 +64,7 @@
 		log_message('debug', "Javascript Class Initialized and loaded.  Driver used: $js_library_driver");
 	}
 
-	// --------------------------------------------------------------------	
+	// --------------------------------------------------------------------
 	// Event Code
 	// --------------------------------------------------------------------
 
@@ -73,12 +73,11 @@
 	 *
 	 * Outputs a javascript library blur event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function blur($element = 'this', $js = '')
+	public function blur($element = 'this', $js = '')
 	{
 		return $this->js->_blur($element, $js);
 	}
@@ -90,12 +89,11 @@
 	 *
 	 * Outputs a javascript library change event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function change($element = 'this', $js = '')
+	public function change($element = 'this', $js = '')
 	{
 		return $this->js->_change($element, $js);
 	}
@@ -107,13 +105,12 @@
 	 *
 	 * Outputs a javascript library click event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @param	boolean	whether or not to return false
 	 * @return	string
 	 */
-	function click($element = 'this', $js = '', $ret_false = TRUE)
+	public function click($element = 'this', $js = '', $ret_false = TRUE)
 	{
 		return $this->js->_click($element, $js, $ret_false);
 	}
@@ -125,12 +122,11 @@
 	 *
 	 * Outputs a javascript library dblclick event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function dblclick($element = 'this', $js = '')
+	public function dblclick($element = 'this', $js = '')
 	{
 		return $this->js->_dblclick($element, $js);
 	}
@@ -142,12 +138,11 @@
 	 *
 	 * Outputs a javascript library error event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function error($element = 'this', $js = '')
+	public function error($element = 'this', $js = '')
 	{
 		return $this->js->_error($element, $js);
 	}
@@ -159,12 +154,11 @@
 	 *
 	 * Outputs a javascript library focus event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function focus($element = 'this', $js = '')
+	public function focus($element = 'this', $js = '')
 	{
 		return $this->js->__add_event($focus, $js);
 	}
@@ -176,13 +170,12 @@
 	 *
 	 * Outputs a javascript library hover event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- Javascript code for mouse over
 	 * @param	string	- Javascript code for mouse out
 	 * @return	string
 	 */
-	function hover($element = 'this', $over, $out)
+	public function hover($element = 'this', $over, $out)
 	{
 		return $this->js->__hover($element, $over, $out);
 	}
@@ -194,12 +187,11 @@
 	 *
 	 * Outputs a javascript library keydown event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function keydown($element = 'this', $js = '')
+	public function keydown($element = 'this', $js = '')
 	{
 		return $this->js->_keydown($element, $js);
 	}
@@ -211,12 +203,11 @@
 	 *
 	 * Outputs a javascript library keydown event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function keyup($element = 'this', $js = '')
+	public function keyup($element = 'this', $js = '')
 	{
 		return $this->js->_keyup($element, $js);
 	}
@@ -228,12 +219,11 @@
 	 *
 	 * Outputs a javascript library load event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function load($element = 'this', $js = '')
+	public function load($element = 'this', $js = '')
 	{
 		return $this->js->_load($element, $js);
 	}
@@ -245,12 +235,11 @@
 	 *
 	 * Outputs a javascript library mousedown event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function mousedown($element = 'this', $js = '')
+	public function mousedown($element = 'this', $js = '')
 	{
 		return $this->js->_mousedown($element, $js);
 	}
@@ -262,12 +251,11 @@
 	 *
 	 * Outputs a javascript library mouseout event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function mouseout($element = 'this', $js = '')
+	public function mouseout($element = 'this', $js = '')
 	{
 		return $this->js->_mouseout($element, $js);
 	}
@@ -279,12 +267,11 @@
 	 *
 	 * Outputs a javascript library mouseover event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function mouseover($element = 'this', $js = '')
+	public function mouseover($element = 'this', $js = '')
 	{
 		return $this->js->_mouseover($element, $js);
 	}
@@ -296,12 +283,11 @@
 	 *
 	 * Outputs a javascript library mouseup event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function mouseup($element = 'this', $js = '')
+	public function mouseup($element = 'this', $js = '')
 	{
 		return $this->js->_mouseup($element, $js);
 	}
@@ -313,11 +299,10 @@
 	 *
 	 * Outputs the called javascript to the screen
 	 *
-	 * @access	public
 	 * @param	string	The code to output
 	 * @return	string
 	 */
-	function output($js)
+	public function output($js)
 	{
 		return $this->js->_output($js);
 	}
@@ -329,12 +314,11 @@
 	 *
 	 * Outputs a javascript library mouseup event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function ready($js)
+	public function ready($js)
 	{
 		return $this->js->_document_ready($js);
 	}
@@ -346,12 +330,11 @@
 	 *
 	 * Outputs a javascript library resize event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function resize($element = 'this', $js = '')
+	public function resize($element = 'this', $js = '')
 	{
 		return $this->js->_resize($element, $js);
 	}
@@ -363,12 +346,11 @@
 	 *
 	 * Outputs a javascript library scroll event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function scroll($element = 'this', $js = '')
+	public function scroll($element = 'this', $js = '')
 	{
 		return $this->js->_scroll($element, $js);
 	}
@@ -380,17 +362,16 @@
 	 *
 	 * Outputs a javascript library unload event
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function unload($element = 'this', $js = '')
+	public function unload($element = 'this', $js = '')
 	{
 		return $this->js->_unload($element, $js);
 	}
 
-	// --------------------------------------------------------------------	
+	// --------------------------------------------------------------------
 	// Effects
 	// --------------------------------------------------------------------
 
@@ -400,12 +381,11 @@
 	 *
 	 * Outputs a javascript library addClass event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- Class to add
 	 * @return	string
 	 */
-	function addClass($element = 'this', $class = '')
+	public function addClass($element = 'this', $class = '')
 	{
 		return $this->js->_addClass($element, $class);
 	}
@@ -417,13 +397,12 @@
 	 *
 	 * Outputs a javascript library animate event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function animate($element = 'this', $params = array(), $speed = '', $extra = '')
+	public function animate($element = 'this', $params = array(), $speed = '', $extra = '')
 	{
 		return $this->js->_animate($element, $params, $speed, $extra);
 	}
@@ -435,13 +414,12 @@
 	 *
 	 * Outputs a javascript library hide event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function fadeIn($element = 'this', $speed = '', $callback = '')
+	public function fadeIn($element = 'this', $speed = '', $callback = '')
 	{
 		return $this->js->_fadeIn($element, $speed, $callback);
 	}
@@ -453,13 +431,12 @@
 	 *
 	 * Outputs a javascript library hide event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function fadeOut($element = 'this', $speed = '', $callback = '')
+	public function fadeOut($element = 'this', $speed = '', $callback = '')
 	{
 		return $this->js->_fadeOut($element, $speed, $callback);
 	}
@@ -470,13 +447,12 @@
 	 *
 	 * Outputs a javascript library slideUp event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function slideUp($element = 'this', $speed = '', $callback = '')
+	public function slideUp($element = 'this', $speed = '', $callback = '')
 	{
 		return $this->js->_slideUp($element, $speed, $callback);
 
@@ -489,12 +465,11 @@
 	 *
 	 * Outputs a javascript library removeClass event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- Class to add
 	 * @return	string
 	 */
-	function removeClass($element = 'this', $class = '')
+	public function removeClass($element = 'this', $class = '')
 	{
 		return $this->js->_removeClass($element, $class);
 	}
@@ -506,13 +481,12 @@
 	 *
 	 * Outputs a javascript library slideDown event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function slideDown($element = 'this', $speed = '', $callback = '')
+	public function slideDown($element = 'this', $speed = '', $callback = '')
 	{
 		return $this->js->_slideDown($element, $speed, $callback);
 	}
@@ -524,13 +498,12 @@
 	 *
 	 * Outputs a javascript library slideToggle event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function slideToggle($element = 'this', $speed = '', $callback = '')
+	public function slideToggle($element = 'this', $speed = '', $callback = '')
 	{
 		return $this->js->_slideToggle($element, $speed, $callback);
 
@@ -543,13 +516,12 @@
 	 *
 	 * Outputs a javascript library hide action
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function hide($element = 'this', $speed = '', $callback = '')
+	public function hide($element = 'this', $speed = '', $callback = '')
 	{
 		return $this->js->_hide($element, $speed, $callback);
 	}
@@ -561,11 +533,10 @@
 	 *
 	 * Outputs a javascript library toggle event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @return	string
 	 */
-	function toggle($element = 'this')
+	public function toggle($element = 'this')
 	{
 		return $this->js->_toggle($element);
 
@@ -578,11 +549,10 @@
 	 *
 	 * Outputs a javascript library toggle class event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @return	string
 	 */
-	function toggleClass($element = 'this', $class='')
+	public function toggleClass($element = 'this', $class='')
 	{
 		return $this->js->_toggleClass($element, $class);
 	}
@@ -594,13 +564,12 @@
 	 *
 	 * Outputs a javascript library show event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function show($element = 'this', $speed = '', $callback = '')
+	public function show($element = 'this', $speed = '', $callback = '')
 	{
 		return $this->js->_show($element, $speed, $callback);
 	}
@@ -613,11 +582,10 @@
 	 *
 	 * gather together all script needing to be output
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @return	string
 	 */
-	function compile($view_var = 'script_foot', $script_tags = TRUE)
+	public function compile($view_var = 'script_foot', $script_tags = TRUE)
 	{
 		$this->js->_compile($view_var, $script_tags);
 	}
@@ -627,10 +595,9 @@
 	 *
 	 * Clears any previous javascript collected for output
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function clear_compile()
+	public function clear_compile()
 	{
 		$this->js->_clear_compile();
 	}
@@ -642,11 +609,10 @@
 	 *
 	 * Outputs a <script> tag with the source as an external js file
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @return	string
 	 */
-	function external($external_file = '', $relative = FALSE)
+	public function external($external_file = '', $relative = FALSE)
 	{
 		if ($external_file !== '')
 		{
@@ -660,7 +626,7 @@
 			}
 		}
 
-		if ($relative === TRUE OR strncmp($external_file, 'http://', 7) == 0 OR strncmp($external_file, 'https://', 8) == 0)
+		if ($relative === TRUE OR strncmp($external_file, 'http://', 7) === 0 OR strncmp($external_file, 'https://', 8) === 0)
 		{
 			$str = $this->_open_script($external_file);
 		}
@@ -673,8 +639,7 @@
 			$str = $this->_open_script($this->CI->config->slash_item('base_url').$this->_javascript_location.$external_file);
 		}
 
-		$str .= $this->_close_script();
-		return $str;
+		return $str.$this->_close_script();
 	}
 
 	// --------------------------------------------------------------------
@@ -684,20 +649,17 @@
 	 *
 	 * Outputs a <script> tag
 	 *
-	 * @access	public
 	 * @param	string	The element to attach the event to
 	 * @param	boolean	If a CDATA section should be added
 	 * @return	string
 	 */
-	function inline($script, $cdata = TRUE)
+	public function inline($script, $cdata = TRUE)
 	{
-		$str = $this->_open_script();
-		$str .= ($cdata) ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n";
-		$str .= $this->_close_script();
-
-		return $str;
+		return $this->_open_script()
+			. ($cdata ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n")
+			. $this->_close_script();
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -705,15 +667,13 @@
 	 *
 	 * Outputs an opening <script>
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	function _open_script($src = '')
+	protected function _open_script($src = '')
 	{
-		$str = '<script type="text/javascript" charset="'.strtolower($this->CI->config->item('charset')).'"';
-		$str .= ($src == '') ? '>' : ' src="'.$src.'">';
-		return $str;
+		return '<script type="text/javascript" charset="'.strtolower($this->CI->config->item('charset')).'"'
+			. ($src == '' ? '>' : ' src="'.$src.'">');
 	}
 
 	// --------------------------------------------------------------------
@@ -723,11 +683,10 @@
 	 *
 	 * Outputs an closing </script>
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
 	 */
-	function _close_script($extra = "\n")
+	protected function _close_script($extra = "\n")
 	{
 		return "</script>$extra";
 	}
@@ -744,13 +703,12 @@
 	 *
 	 * Outputs a javascript library slideDown event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function update($element = 'this', $speed = '', $callback = '')
+	public function update($element = 'this', $speed = '', $callback = '')
 	{
 		return $this->js->_updater($element, $speed, $callback);
 	}
@@ -766,7 +724,7 @@
 	 * @param	bool	match array types (defaults to objects)
 	 * @return	string	a json formatted string
 	 */
-	function generate_json($result = NULL, $match_array_type = FALSE)
+	public function generate_json($result = NULL, $match_array_type = FALSE)
 	{
 		// JSON data can optionally be passed to this function
 		// either as a database result object or an array, or a user supplied array
@@ -827,11 +785,10 @@
 	 *
 	 * Checks for an associative array
 	 *
-	 * @access	public
 	 * @param	type
 	 * @return	type
 	 */
-	function _is_associative_array($arr)
+	protected function _is_associative_array($arr)
 	{
 		foreach (array_keys($arr) as $key => $val)
 		{
@@ -851,11 +808,10 @@
 	 *
 	 * Ensures a standard json value and escapes values
 	 *
-	 * @access	public
 	 * @param	type
 	 * @return	type
 	 */
-	function _prep_args($result, $is_key = FALSE)
+	protected function _prep_args($result, $is_key = FALSE)
 	{
 		if (is_null($result))
 		{
@@ -867,7 +823,7 @@
 		}
 		elseif (is_string($result) OR $is_key)
 		{
-			return '"'.str_replace(array('\\', "\t", "\n", "\r", '"', '/'), array('\\\\', '\\t', '\\n', "\\r", '\"', '\/'), $result).'"';			
+			return '"'.str_replace(array('\\', "\t", "\n", "\r", '"', '/'), array('\\\\', '\\t', '\\n', "\\r", '\"', '\/'), $result).'"';
 		}
 		elseif (is_scalar($result))
 		{
@@ -880,4 +836,4 @@
 // END Javascript Class
 
 /* End of file Javascript.php */
-/* Location: ./system/libraries/Javascript.php */
\ No newline at end of file
+/* Location: ./system/libraries/Javascript.php */
diff --git a/system/libraries/Log.php b/system/libraries/Log.php
index 7f3a307..944173f 100644
--- a/system/libraries/Log.php
+++ b/system/libraries/Log.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/libraries/Migration.php b/system/libraries/Migration.php
index eb5161d..d070972 100644
--- a/system/libraries/Migration.php
+++ b/system/libraries/Migration.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2006 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @copyright	Copyright (c) 2006 - 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 3.0
@@ -322,7 +322,7 @@
 	 */
 	protected function _get_version()
 	{
-		$row = $this->db->get($this->_migration_table)->row();
+		$row = $this->db->select('version')->get($this->_migration_table)->row();
 		return $row ? $row->version : 0;
 	}
 
diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php
index eea953a..35ac541 100644
--- a/system/libraries/Pagination.php
+++ b/system/libraries/Pagination.php
@@ -1,4 +1,4 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -128,10 +128,10 @@
 		}
 
 		// Calculate the total number of pages
-		$num_pages = ceil($this->total_rows / $this->per_page);
+		$num_pages = (int) ceil($this->total_rows / $this->per_page);
 
 		// Is there only one page? Hm... nothing more to do here then.
-		if ($num_pages == 1)
+		if ($num_pages === 1)
 		{
 			return '';
 		}
@@ -142,45 +142,37 @@
 		// Determine the current page number.
 		$CI =& get_instance();
 
+		// See if we are using a prefix or suffix on links
+		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)
 			{
-				$this->cur_page = $CI->input->get($this->query_string_segment);
-
-				// Prep the current page - no funny business!
-				$this->cur_page = (int) $this->cur_page;
+				$this->cur_page = (int) $CI->input->get($this->query_string_segment);
 			}
 		}
-		else
+		elseif ( ! $this->cur_page AND $CI->uri->segment($this->uri_segment) != $base_page)
 		{
-			if ($CI->uri->segment($this->uri_segment) != $base_page)
-			{
-				$this->cur_page = $CI->uri->segment($this->uri_segment);
-
-				// Prep the current page - no funny business!
-				$this->cur_page = (int) $this->cur_page;
-			}
+			$this->cur_page = (int) $CI->uri->segment($this->uri_segment);
 		}
 
-		// Set current page to 1 if using page numbers instead of offset
-		if ($this->use_page_numbers AND $this->cur_page == 0)
+		// 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 AND $this->cur_page == 0))
 		{
 			$this->cur_page = $base_page;
 		}
 
-		$this->num_links = (int)$this->num_links;
+		$this->num_links = (int) $this->num_links;
 
 		if ($this->num_links < 1)
 		{
 			show_error('Your number of links must be a positive number.');
 		}
 
-		if ( ! is_numeric($this->cur_page))
-		{
-			$this->cur_page = $base_page;
-		}
-
 		// Is the page number beyond the result range?
 		// If so we show the last page
 		if ($this->use_page_numbers)
@@ -236,13 +228,13 @@
 		{
 			$i = ($this->use_page_numbers) ? $uri_page_number - 1 : $uri_page_number - $this->per_page;
 
-			if (($i == 0 OR ($this->use_page_numbers && $i == 1)) AND $this->first_url != '')
+			if ($i == $base_page AND $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 == 0) ? '' : $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;
 			}
 
@@ -310,4 +302,4 @@
 // END Pagination Class
 
 /* End of file Pagination.php */
-/* Location: ./system/libraries/Pagination.php */
\ No newline at end of file
+/* Location: ./system/libraries/Pagination.php */
diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php
index 39aa61e..3212482 100644
--- a/system/libraries/Parser.php
+++ b/system/libraries/Parser.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php
index 8a2568d..04216be 100644
--- a/system/libraries/Profiler.php
+++ b/system/libraries/Profiler.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -126,12 +126,10 @@
 		{
 			// 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))
+			if (preg_match('/(.+?)_end/i', $key, $match)
+				AND isset($this->CI->benchmark->marker[$match[1].'_end'], $this->CI->benchmark->marker[$match[1].'_start']))
 			{
-				if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start']))
-				{
-					$profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
-				}
+				$profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key);
 			}
 		}
 
@@ -139,12 +137,11 @@
 		// 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
 
-		$output  = "\n\n";
-		$output .= '<fieldset id="ci_profiler_benchmarks" style="border:1px solid #900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-		$output .= "\n";
-		$output .= '<legend style="color:#900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_benchmarks').'&nbsp;&nbsp;</legend>';
-		$output .= "\n";
-		$output .= "\n\n<table style='width:100%'>\n";
+		$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";
 
 		foreach ($profile as $key => $val)
 		{
@@ -152,10 +149,7 @@
 			$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 .= "</table>\n";
-		$output .= "</fieldset>";
-
-		return $output;
+		return $output."</table>\n</fieldset>";
 	}
 
 	// --------------------------------------------------------------------
@@ -178,19 +172,16 @@
 			}
 		}
 
-		if (count($dbs) == 0)
+		if (count($dbs) === 0)
 		{
-			$output  = "\n\n";
-			$output .= '<fieldset id="ci_profiler_queries" style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-			$output .= "\n";
-			$output .= '<legend style="color:#0000FF;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_queries').'&nbsp;&nbsp;</legend>';
-			$output .= "\n";
-			$output .= "\n\n<table style='border:none; width:100%;'>\n";
-			$output .="<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";
-			$output .= "</table>\n";
-			$output .= "</fieldset>";
-
-			return $output;
+			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>";
 		}
 
 		// Load the text helper so we can highlight the SQL
@@ -205,8 +196,6 @@
 
 		foreach ($dbs as $db)
 		{
-			$count++;
-
 			$hide_queries = (count($db->queries) > $this->_query_toggle_count) ? ' display:none' : '';
 
 			$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>)';
@@ -216,13 +205,12 @@
 				$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">';
-			$output .= "\n";
-			$output .= '<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>';
-			$output .= "\n";
-			$output .= "\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)
+			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";
 			}
@@ -243,8 +231,7 @@
 				}
 			}
 
-			$output .= "</table>\n";
-			$output .= "</fieldset>";
+			$output .= "</table>\n</fieldset>";
 
 		}
 
@@ -261,13 +248,13 @@
 	 */
 	protected function _compile_get()
 	{
-		$output  = "\n\n";
-		$output .= '<fieldset id="ci_profiler_get" style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-		$output .= "\n";
-		$output .= '<legend style="color:#cd6e00;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_get_data').'&nbsp;&nbsp;</legend>';
-		$output .= "\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)
+		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>";
 		}
@@ -282,23 +269,15 @@
 					$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;'>";
-				if (is_array($val))
-				{
-					$output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>";
-				}
-				else
-				{
-					$output .= htmlspecialchars(stripslashes($val));
-				}
-				$output .= "</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";
 		}
-		$output .= "</fieldset>";
 
-		return $output;
+		return $output.'</fieldset>';
 	}
 
 	// --------------------------------------------------------------------
@@ -310,11 +289,11 @@
 	 */
 	protected function _compile_post()
 	{
-		$output  = "\n\n";
-		$output .= '<fieldset id="ci_profiler_post" style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-		$output .= "\n";
-		$output .= '<legend style="color:#009900;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_post_data').'&nbsp;&nbsp;</legend>';
-		$output .= "\n";
+		$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";
 
 		if (count($_POST) == 0)
 		{
@@ -332,7 +311,7 @@
 				}
 
 				$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))
+				if (is_array($val) OR is_object($val))
 				{
 					$output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, TRUE))) . "</pre>";
 				}
@@ -345,9 +324,8 @@
 
 			$output .= "</table>\n";
 		}
-		$output .= "</fieldset>";
 
-		return $output;
+		return $output.'</fieldset>';
 	}
 
 	// --------------------------------------------------------------------
@@ -359,24 +337,13 @@
 	 */
 	protected function _compile_uri_string()
 	{
-		$output  = "\n\n";
-		$output .= '<fieldset id="ci_profiler_uri_string" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-		$output .= "\n";
-		$output .= '<legend style="color:#000;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_uri_string').'&nbsp;&nbsp;</legend>';
-		$output .= "\n";
-
-		if ($this->CI->uri->uri_string == '')
-		{
-			$output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_uri')."</div>";
-		}
-		else
-		{
-			$output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>";
-		}
-
-		$output .= "</fieldset>";
-
-		return $output;
+		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>';
 	}
 
 	// --------------------------------------------------------------------
@@ -388,17 +355,12 @@
 	 */
 	protected function _compile_controller_info()
 	{
-		$output  = "\n\n";
-		$output .= '<fieldset id="ci_profiler_controller_info" style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-		$output .= "\n";
-		$output .= '<legend style="color:#995300;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_controller_info').'&nbsp;&nbsp;</legend>';
-		$output .= "\n";
-
-		$output .= "<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class()."/".$this->CI->router->fetch_method()."</div>";
-
-		$output .= "</fieldset>";
-
-		return $output;
+		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>';
 	}
 
 	// --------------------------------------------------------------------
@@ -412,24 +374,13 @@
 	 */
 	protected function _compile_memory_usage()
 	{
-		$output  = "\n\n";
-		$output .= '<fieldset id="ci_profiler_memory_usage" style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-		$output .= "\n";
-		$output .= '<legend style="color:#5a0099;">&nbsp;&nbsp;'.$this->CI->lang->line('profiler_memory_usage').'&nbsp;&nbsp;</legend>';
-		$output .= "\n";
-
-		if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '')
-		{
-			$output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".number_format($usage).' bytes</div>';
-		}
-		else
-		{
-			$output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory')."</div>";
-		}
-
-		$output .= "</fieldset>";
-
-		return $output;
+		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>';
 	}
 
 	// --------------------------------------------------------------------
@@ -443,13 +394,11 @@
 	 */
 	protected function _compile_http_headers()
 	{
-		$output  = "\n\n";
-		$output .= '<fieldset id="ci_profiler_http_headers" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-		$output .= "\n";
-		$output .= '<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>';
-		$output .= "\n";
-
-		$output .= "\n\n<table style='width:100%;display:none' id='ci_profiler_httpheaders_table'>\n";
+		$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";
 
 		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)
 		{
@@ -457,10 +406,7 @@
 			$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";
 		}
 
-		$output .= "</table>\n";
-		$output .= "</fieldset>";
-
-		return $output;
+		return $output."</table>\n</fieldset>";
 	}
 
 	// --------------------------------------------------------------------
@@ -474,17 +420,15 @@
 	 */
 	protected function _compile_config()
 	{
-		$output  = "\n\n";
-		$output .= '<fieldset id="ci_profiler_config" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">';
-		$output .= "\n";
-		$output .= '<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>';
-		$output .= "\n";
+		$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";
 
-		$output .= "\n\n<table style='width:100%; display:none' id='ci_profiler_config_table'>\n";
-
-		foreach ($this->CI->config->config as $config=>$val)
+		foreach ($this->CI->config->config as $config => $val)
 		{
-			if (is_array($val))
+			if (is_array($val) OR is_object($val))
 			{
 				$val = print_r($val, TRUE);
 			}
@@ -492,10 +436,7 @@
 			$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 .= "</table>\n";
-		$output .= "</fieldset>";
-
-		return $output;
+		return $output."</table>\n</fieldset>";
 	}
 
 	// --------------------------------------------------------------------
@@ -512,13 +453,13 @@
 			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">';
-		$output .= '<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>';
-		$output .= "<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)
 		{
-			if (is_array($val) || is_object($val))
+			if (is_array($val) OR is_object($val))
 			{
 				$val = print_r($val, TRUE);
 			}
@@ -526,9 +467,7 @@
 			$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 .= '</table>';
-		$output .= "</fieldset>";
-		return $output;
+		return $output."</table>\n</fieldset>";
 	}
 
 	// --------------------------------------------------------------------
@@ -553,18 +492,14 @@
 			}
 		}
 
-		if ($fields_displayed == 0)
+		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 .= '</div>';
-
-		return $output;
+		return $output.'</div>';
 	}
 }
 
-// END CI_Profiler class
-
 /* End of file Profiler.php */
 /* Location: ./system/libraries/Profiler.php */
diff --git a/system/libraries/Session.php b/system/libraries/Session.php
index 08d2ba4..dd50a91 100644
--- a/system/libraries/Session.php
+++ b/system/libraries/Session.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,15 +18,13 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
  */
 
-// ------------------------------------------------------------------------
-
 /**
  * Session Class
  *
@@ -38,26 +36,26 @@
  */
 class CI_Session {
 
-	var $sess_encrypt_cookie		= FALSE;
-	var $sess_use_database			= FALSE;
-	var $sess_table_name			= '';
-	var $sess_expiration			= 7200;
-	var $sess_expire_on_close		= FALSE;
-	var $sess_match_ip				= FALSE;
-	var $sess_match_useragent		= TRUE;
-	var $sess_cookie_name			= 'ci_session';
-	var $cookie_prefix				= '';
-	var $cookie_path				= '';
-	var $cookie_domain				= '';
-	var $cookie_secure				= FALSE;
-	var $sess_time_to_update		= 300;
-	var $encryption_key				= '';
-	var $flashdata_key				= 'flash';
-	var $time_reference				= 'time';
-	var $gc_probability				= 5;
-	var $userdata					= array();
-	var $CI;
-	var $now;
+	public $sess_encrypt_cookie		= FALSE;
+	public $sess_use_database		= FALSE;
+	public $sess_table_name			= '';
+	public $sess_expiration			= 7200;
+	public $sess_expire_on_close		= FALSE;
+	public $sess_match_ip			= FALSE;
+	public $sess_match_useragent		= TRUE;
+	public $sess_cookie_name		= 'ci_session';
+	public $cookie_prefix			= '';
+	public $cookie_path			= '';
+	public $cookie_domain			= '';
+	public $cookie_secure			= FALSE;
+	public $sess_time_to_update		= 300;
+	public $encryption_key			= '';
+	public $flashdata_key			= 'flash';
+	public $time_reference			= 'time';
+	public $gc_probability			= 5;
+	public $userdata			= array();
+	public $CI;
+	public $now;
 
 	/**
 	 * Session Constructor
@@ -67,7 +65,7 @@
 	 */
 	public function __construct($params = array())
 	{
-		log_message('debug', "Session Class Initialized");
+		log_message('debug', 'Session Class Initialized');
 
 		// Set the super object to a local variable for use throughout the class
 		$this->CI =& get_instance();
@@ -93,14 +91,14 @@
 			$this->CI->load->library('encrypt');
 		}
 
-		// Are we using a database?  If so, load it
-		if ($this->sess_use_database === TRUE AND $this->sess_table_name != '')
+		// Are we using a database? If so, load it
+		if ($this->sess_use_database === TRUE && $this->sess_table_name != '')
 		{
 			$this->CI->load->database();
 		}
 
-		// Set the "now" time.  Can either be GMT or server time, based on the
-		// config prefs.  We use this to set the "last activity" time
+		// Set the "now" time. Can either be GMT or server time, based on the
+		// config prefs. We use this to set the "last activity" time
 		$this->now = $this->_get_time();
 
 		// Set the session length. If the session expiration is
@@ -109,12 +107,12 @@
 		{
 			$this->sess_expiration = (60*60*24*365*2);
 		}
-		
+
 		// Set the cookie name
 		$this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name;
 
 		// Run the Session routine. If a session doesn't exist we'll
-		// create a new one.  If it does, we'll update it.
+		// create a new one. If it does, we'll update it.
 		if ( ! $this->sess_read())
 		{
 			$this->sess_create();
@@ -133,7 +131,7 @@
 		// Delete expired sessions if necessary
 		$this->_sess_gc();
 
-		log_message('debug', "Session routines successfully run");
+		log_message('debug', 'Session routines successfully run');
 	}
 
 	// --------------------------------------------------------------------
@@ -141,10 +139,9 @@
 	/**
 	 * Fetch the current session data if it exists
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
-	function sess_read()
+	public function sess_read()
 	{
 		// Fetch the cookie
 		$session = $this->CI->input->cookie($this->sess_cookie_name);
@@ -167,7 +164,7 @@
 			$hash	 = substr($session, strlen($session)-32); // get last 32 chars
 			$session = substr($session, 0, strlen($session)-32);
 
-			// Does the md5 hash match?  This is to prevent manipulation of session data in userspace
+			// Does the md5 hash match? This is to prevent manipulation of session data in userspace
 			if ($hash !==  md5($session.$this->encryption_key))
 			{
 				log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.');
@@ -180,7 +177,7 @@
 		$session = $this->_unserialize($session);
 
 		// Is the session data we unserialized an array with the correct format?
-		if ( ! is_array($session) OR ! isset($session['session_id']) OR ! isset($session['ip_address']) OR ! isset($session['user_agent']) OR ! isset($session['last_activity']))
+		if ( ! is_array($session) OR ! isset($session['session_id'], $session['ip_address'], $session['user_agent'], $session['last_activity']))
 		{
 			$this->sess_destroy();
 			return FALSE;
@@ -193,15 +190,15 @@
 			return FALSE;
 		}
 
-		// Does the IP Match?
-		if ($this->sess_match_ip == TRUE AND $session['ip_address'] != $this->CI->input->ip_address())
+		// Does the IP match?
+		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 AND 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;
@@ -222,10 +219,10 @@
 				$this->CI->db->where('user_agent', $session['user_agent']);
 			}
 
-			$query = $this->CI->db->get($this->sess_table_name);
+			$query = $this->CI->db->limit(1)->get($this->sess_table_name);
 
-			// No result?  Kill it!
-			if ($query->num_rows() == 0)
+			// No result? Kill it!
+			if ($query->num_rows() === 0)
 			{
 				$this->sess_destroy();
 				return FALSE;
@@ -233,7 +230,7 @@
 
 			// Is there custom data?  If so, add it to the main session array
 			$row = $query->row();
-			if (isset($row->user_data) AND $row->user_data != '')
+			if (isset($row->user_data) && $row->user_data != '')
 			{
 				$custom_data = $this->_unserialize($row->user_data);
 
@@ -259,10 +256,9 @@
 	/**
 	 * Write the session data
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function sess_write()
+	public function sess_write()
 	{
 		// Are we saving custom data to the DB?  If not, all we do is update the cookie
 		if ($this->sess_use_database === FALSE)
@@ -284,7 +280,7 @@
 			$cookie_userdata[$val] = $this->userdata[$val];
 		}
 
-		// Did we find any custom data?  If not, we turn the empty array into a string
+		// Did we find any custom data? If not, we turn the empty array into a string
 		// since there's no reason to serialize and store an empty array in the DB
 		if (count($custom_userdata) === 0)
 		{
@@ -300,7 +296,7 @@
 		$this->CI->db->where('session_id', $this->userdata['session_id']);
 		$this->CI->db->update($this->sess_table_name, array('last_activity' => $this->userdata['last_activity'], 'user_data' => $custom_userdata));
 
-		// Write the cookie.  Notice that we manually pass the cookie data array to the
+		// Write the cookie. Notice that we manually pass the cookie data array to the
 		// _set_cookie() function. Normally that function will store $this->userdata, but
 		// in this case that array contains custom data, which we do not want in the cookie.
 		$this->_set_cookie($cookie_userdata);
@@ -311,28 +307,27 @@
 	/**
 	 * Create a new session
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function sess_create()
+	public function sess_create()
 	{
 		$sessid = '';
-		while (strlen($sessid) < 32)
+		do
 		{
 			$sessid .= mt_rand(0, mt_getrandmax());
 		}
+		while (strlen($sessid) < 32);
 
 		// To make the session ID even more secure we'll combine it with the user's IP
 		$sessid .= $this->CI->input->ip_address();
 
 		$this->userdata = array(
-							'session_id'	=> md5(uniqid($sessid, TRUE)),
-							'ip_address'	=> $this->CI->input->ip_address(),
-							'user_agent'	=> substr($this->CI->input->user_agent(), 0, 120),
-							'last_activity'	=> $this->now,
-							'user_data'		=> ''
-							);
-
+					'session_id'	=> md5(uniqid($sessid, TRUE)),
+					'ip_address'	=> $this->CI->input->ip_address(),
+					'user_agent'	=> substr($this->CI->input->user_agent(), 0, 120),
+					'last_activity'	=> $this->now,
+					'user_data'	=> ''
+				);
 
 		// Save the data to the DB if needed
 		if ($this->sess_use_database === TRUE)
@@ -349,10 +344,9 @@
 	/**
 	 * Update an existing session
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function sess_update()
+	public function sess_update()
 	{
 		// We only update the session every five minutes by default
 		if (($this->userdata['last_activity'] + $this->sess_time_to_update) >= $this->now)
@@ -360,29 +354,52 @@
 			return;
 		}
 
+		// _set_cookie() will handle this for us if we aren't using database sessions
+		// by pushing all userdata to the cookie.
+		$cookie_data = NULL;
+
+		/* Changing the session ID during an AJAX call causes problems,
+		 * so we'll only update our last_activity
+		 */
+		if ($this->CI->input->is_ajax_request())
+		{
+			$this->userdata['last_activity'] = $this->now;
+
+			// Update the session ID and last_activity field in the DB if needed
+			if ($this->sess_use_database === TRUE)
+			{
+				// set cookie explicitly to only have our session data
+				$cookie_data = array();
+				foreach (array('session_id','ip_address','user_agent','last_activity') as $val)
+				{
+					$cookie_data[$val] = $this->userdata[$val];
+				}
+
+				$this->CI->db->query($this->CI->db->update_string($this->sess_table_name,
+											array('last_activity' => $this->userdata['last_activity']),
+											array('session_id' => $this->userdata['session_id'])));
+			}
+
+			return $this->_set_cookie($cookie_data);
+		}
+
 		// Save the old session id so we know which record to
 		// update in the database if we need it
 		$old_sessid = $this->userdata['session_id'];
 		$new_sessid = '';
-		while (strlen($new_sessid) < 32)
+		do
 		{
 			$new_sessid .= mt_rand(0, mt_getrandmax());
 		}
+		while (strlen($new_sessid) < 32);
 
 		// To make the session ID even more secure we'll combine it with the user's IP
 		$new_sessid .= $this->CI->input->ip_address();
 
-		// Turn it into a hash
-		$new_sessid = md5(uniqid($new_sessid, TRUE));
-
-		// Update the session data in the session data array
-		$this->userdata['session_id'] = $new_sessid;
+		// Turn it into a hash and update the session data array
+		$this->userdata['session_id'] = $new_sessid = md5(uniqid($new_sessid, TRUE));
 		$this->userdata['last_activity'] = $this->now;
 
-		// _set_cookie() will handle this for us if we aren't using database sessions
-		// by pushing all userdata to the cookie.
-		$cookie_data = NULL;
-
 		// Update the session ID and last_activity field in the DB if needed
 		if ($this->sess_use_database === TRUE)
 		{
@@ -405,13 +422,12 @@
 	/**
 	 * Destroy the current session
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function sess_destroy()
+	public function sess_destroy()
 	{
 		// Kill the session DB row
-		if ($this->sess_use_database === TRUE AND isset($this->userdata['session_id']))
+		if ($this->sess_use_database === TRUE && isset($this->userdata['session_id']))
 		{
 			$this->CI->db->where('session_id', $this->userdata['session_id']);
 			$this->CI->db->delete($this->sess_table_name);
@@ -419,13 +435,13 @@
 
 		// Kill the cookie
 		setcookie(
-					$this->sess_cookie_name,
-					addslashes(serialize(array())),
-					($this->now - 31500000),
-					$this->cookie_path,
-					$this->cookie_domain,
-					0
-				);
+				$this->sess_cookie_name,
+				addslashes(serialize(array())),
+				($this->now - 31500000),
+				$this->cookie_path,
+				$this->cookie_domain,
+				0
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -433,11 +449,10 @@
 	/**
 	 * Fetch a specific item from the session array
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function userdata($item)
+	public function userdata($item)
 	{
 		return ( ! isset($this->userdata[$item])) ? FALSE : $this->userdata[$item];
 	}
@@ -447,10 +462,9 @@
 	/**
 	 * Fetch all session data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function all_userdata()
+	public function all_userdata()
 	{
 		return $this->userdata;
 	}
@@ -460,12 +474,11 @@
 	/**
 	 * Add or change data in the "userdata" array
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @param	string
 	 * @return	void
 	 */
-	function set_userdata($newdata = array(), $newval = '')
+	public function set_userdata($newdata = array(), $newval = '')
 	{
 		if (is_string($newdata))
 		{
@@ -488,10 +501,9 @@
 	/**
 	 * Delete a session variable from the "userdata" array
 	 *
-	 * @access	array
 	 * @return	void
 	 */
-	function unset_userdata($newdata = array())
+	public function unset_userdata($newdata = array())
 	{
 		if (is_string($newdata))
 		{
@@ -515,12 +527,11 @@
 	 * Add or change flashdata, only available
 	 * until the next request
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @param	string
 	 * @return	void
 	 */
-	function set_flashdata($newdata = array(), $newval = '')
+	public function set_flashdata($newdata = array(), $newval = '')
 	{
 		if (is_string($newdata))
 		{
@@ -531,8 +542,7 @@
 		{
 			foreach ($newdata as $key => $val)
 			{
-				$flashdata_key = $this->flashdata_key.':new:'.$key;
-				$this->set_userdata($flashdata_key, $val);
+				$this->set_userdata($this->flashdata_key.':new:'.$key, $val);
 			}
 		}
 	}
@@ -542,21 +552,18 @@
 	/**
 	 * Keeps existing flashdata available to next request.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
-	function keep_flashdata($key)
+	public function keep_flashdata($key)
 	{
-		// 'old' flashdata gets removed.  Here we mark all
+		// '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
 		// provided cannot be found
-		$old_flashdata_key = $this->flashdata_key.':old:'.$key;
-		$value = $this->userdata($old_flashdata_key);
+		$value = $this->userdata($this->flashdata_key.':old:'.$key);
 
-		$new_flashdata_key = $this->flashdata_key.':new:'.$key;
-		$this->set_userdata($new_flashdata_key, $value);
+		$this->set_userdata($this->flashdata_key.':new:'.$key, $value);
 	}
 
 	// ------------------------------------------------------------------------
@@ -564,14 +571,12 @@
 	/**
 	 * Fetch a specific flashdata item from the session array
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function flashdata($key)
+	public function flashdata($key)
 	{
-		$flashdata_key = $this->flashdata_key.':old:'.$key;
-		return $this->userdata($flashdata_key);
+		return $this->userdata($this->flashdata_key.':old:'.$key);
 	}
 
 	// ------------------------------------------------------------------------
@@ -580,10 +585,9 @@
 	 * Identifies flashdata as 'old' for removal
 	 * when _flashdata_sweep() runs.
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _flashdata_mark()
+	protected function _flashdata_mark()
 	{
 		$userdata = $this->all_userdata();
 		foreach ($userdata as $name => $value)
@@ -591,8 +595,7 @@
 			$parts = explode(':new:', $name);
 			if (is_array($parts) && count($parts) === 2)
 			{
-				$new_name = $this->flashdata_key.':old:'.$parts[1];
-				$this->set_userdata($new_name, $value);
+				$this->set_userdata($this->flashdata_key.':old:'.$parts[1], $value);
 				$this->unset_userdata($name);
 			}
 		}
@@ -603,11 +606,9 @@
 	/**
 	 * Removes all flashdata marked as 'old'
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-
-	function _flashdata_sweep()
+	protected function _flashdata_sweep()
 	{
 		$userdata = $this->all_userdata();
 		foreach ($userdata as $key => $value)
@@ -625,22 +626,13 @@
 	/**
 	 * Get the "now" time
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _get_time()
+	protected function _get_time()
 	{
-		if (strtolower($this->time_reference) == 'gmt')
-		{
-			$now = time();
-			$time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));
-		}
-		else
-		{
-			$time = time();
-		}
-
-		return $time;
+		return (strtolower($this->time_reference) === 'gmt')
+			? mktime(gmdate('H'), gmdate('i'), gmdate('s'), gmdate('m'), gmdate('d'), gmdate('Y'))
+			: time();
 	}
 
 	// --------------------------------------------------------------------
@@ -648,10 +640,9 @@
 	/**
 	 * Write the session cookie
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function _set_cookie($cookie_data = NULL)
+	protected function _set_cookie($cookie_data = NULL)
 	{
 		if (is_null($cookie_data))
 		{
@@ -675,13 +666,13 @@
 
 		// Set the cookie
 		setcookie(
-					$this->sess_cookie_name,
-					$cookie_data,
-					$expire,
-					$this->cookie_path,
-					$this->cookie_domain,
-					$this->cookie_secure
-				);
+				$this->sess_cookie_name,
+				$cookie_data,
+				$expire,
+				$this->cookie_path,
+				$this->cookie_domain,
+				$this->cookie_secure
+			);
 	}
 
 	// --------------------------------------------------------------------
@@ -692,34 +683,32 @@
 	 * This function first converts any slashes found in the array to a temporary
 	 * marker, so when it gets unserialized the slashes will be preserved
 	 *
-	 * @access	private
 	 * @param	array
 	 * @return	string
 	 */
-	function _serialize($data)
+	protected function _serialize($data)
 	{
 		if (is_array($data))
 		{
 			array_walk_recursive($data, array(&$this, '_escape_slashes'));
 		}
-		else
+		elseif (is_string($data))
 		{
-			if (is_string($data))
-			{
-				$data = str_replace('\\', '{{slash}}', $data);
-			}
+			$data = str_replace('\\', '{{slash}}', $data);
 		}
 		return serialize($data);
 	}
-	
+
 	/**
 	 * Escape slashes
 	 *
 	 * This function converts any slashes found into a temporary marker
 	 *
-	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	void
 	 */
-	function _escape_slashes(&$val, $key)
+	protected function _escape_slashes(&$val, $key)
 	{
 		if (is_string($val))
 		{
@@ -735,11 +724,10 @@
 	 * This function unserializes a data string, then converts any
 	 * temporary slash markers back to actual slashes
 	 *
-	 * @access	private
 	 * @param	array
 	 * @return	string
 	 */
-	function _unserialize($data)
+	protected function _unserialize($data)
 	{
 		$data = @unserialize(strip_slashes($data));
 
@@ -751,15 +739,17 @@
 
 		return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data;
 	}
-	
+
 	/**
 	 * Unescape slashes
 	 *
 	 * This function converts any slash markers back into actual slashes
 	 *
-	 * @access	private
+	 * @param	string
+	 * @param	string
+	 * @return	void
 	 */
-	function _unescape_slashes(&$val, $key)
+	protected function _unescape_slashes(&$val, $key)
 	{
 		if (is_string($val))
 		{
@@ -775,10 +765,9 @@
 	 * This deletes expired session rows from database
 	 * if the probability percentage is met
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function _sess_gc()
+	protected function _sess_gc()
 	{
 		if ($this->sess_use_database != TRUE)
 		{
@@ -797,9 +786,7 @@
 		}
 	}
 
-
 }
-// END Session Class
 
 /* End of file Session.php */
-/* Location: ./system/libraries/Session.php */
\ No newline at end of file
+/* Location: ./system/libraries/Session.php */
diff --git a/system/libraries/Sha1.php b/system/libraries/Sha1.php
deleted file mode 100644
index 477b92b..0000000
--- a/system/libraries/Sha1.php
+++ /dev/null
@@ -1,263 +0,0 @@
-<?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 - 2011, 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
- */
-
-// ------------------------------------------------------------------------
-
-/**
- * SHA1 Encoding Class
- *
- * Purpose: Provides 160 bit hashing using The Secure Hash Algorithm
- * developed at the National Institute of Standards and Technology. The 40
- * character SHA1 message hash is computationally infeasible to crack.
- *
- * This class is a fallback for servers that are not running PHP greater than
- * 4.3, or do not have the MHASH library.
- *
- * This class is based on two scripts:
- *
- * Marcus Campbell's PHP implementation (GNU license)
- * http://www.tecknik.net/sha-1/
- *
- * ...which is based on Paul Johnston's JavaScript version
- * (BSD license). http://pajhome.org.uk/
- *
- * I encapsulated the functions and wrote one additional method to fix
- * a hex conversion bug. - Rick Ellis
- *
- * @package		CodeIgniter
- * @subpackage	Libraries
- * @category	Encryption
- * @author		EllisLab Dev Team
- * @link		http://codeigniter.com/user_guide/libraries/encryption.html
- */
-class CI_SHA1 {
-
-	public function __construct()
-	{
-		log_message('debug', "SHA1 Class Initialized");
-	}
-
-	/**
-	 * Generate the Hash
-	 *
-	 * @access	public
-	 * @param	string
-	 * @return	string
-	 */
-	function generate($str)
-	{
-		$n = ((strlen($str) + 8) >> 6) + 1;
-
-		for ($i = 0; $i < $n * 16; $i++)
-		{
-			$x[$i] = 0;
-		}
-
-		for ($i = 0; $i < strlen($str); $i++)
-		{
-			$x[$i >> 2] |= ord(substr($str, $i, 1)) << (24 - ($i % 4) * 8);
-		}
-
-		$x[$i >> 2] |= 0x80 << (24 - ($i % 4) * 8);
-
-		$x[$n * 16 - 1] = strlen($str) * 8;
-
-		$a =  1732584193;
-		$b = -271733879;
-		$c = -1732584194;
-		$d =  271733878;
-		$e = -1009589776;
-
-		for ($i = 0; $i < count($x); $i += 16)
-		{
-			$olda = $a;
-			$oldb = $b;
-			$oldc = $c;
-			$oldd = $d;
-			$olde = $e;
-
-			for ($j = 0; $j < 80; $j++)
-			{
-				if ($j < 16)
-				{
-					$w[$j] = $x[$i + $j];
-				}
-				else
-				{
-					$w[$j] = $this->_rol($w[$j - 3] ^ $w[$j - 8] ^ $w[$j - 14] ^ $w[$j - 16], 1);
-				}
-
-				$t = $this->_safe_add($this->_safe_add($this->_rol($a, 5), $this->_ft($j, $b, $c, $d)), $this->_safe_add($this->_safe_add($e, $w[$j]), $this->_kt($j)));
-
-				$e = $d;
-				$d = $c;
-				$c = $this->_rol($b, 30);
-				$b = $a;
-				$a = $t;
-			}
-
-			$a = $this->_safe_add($a, $olda);
-			$b = $this->_safe_add($b, $oldb);
-			$c = $this->_safe_add($c, $oldc);
-			$d = $this->_safe_add($d, $oldd);
-			$e = $this->_safe_add($e, $olde);
-		}
-
-		return $this->_hex($a).$this->_hex($b).$this->_hex($c).$this->_hex($d).$this->_hex($e);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Convert a decimal to hex
-	 *
-	 * @access	private
-	 * @param	string
-	 * @return	string
-	 */
-	function _hex($str)
-	{
-		$str = dechex($str);
-
-		if (strlen($str) == 7)
-		{
-			$str = '0'.$str;
-		}
-
-		return $str;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 *  Return result based on iteration
-	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _ft($t, $b, $c, $d)
-	{
-		if ($t < 20)
-			return ($b & $c) | ((~$b) & $d);
-		if ($t < 40)
-			return $b ^ $c ^ $d;
-		if ($t < 60)
-			return ($b & $c) | ($b & $d) | ($c & $d);
-
-		return $b ^ $c ^ $d;
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Determine the additive constant
-	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _kt($t)
-	{
-		if ($t < 20)
-		{
-			return 1518500249;
-		}
-		else if ($t < 40)
-		{
-			return 1859775393;
-		}
-		else if ($t < 60)
-		{
-			return -1894007588;
-		}
-		else
-		{
-			return -899497514;
-		}
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Add integers, wrapping at 2^32
-	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _safe_add($x, $y)
-	{
-		$lsw = ($x & 0xFFFF) + ($y & 0xFFFF);
-		$msw = ($x >> 16) + ($y >> 16) + ($lsw >> 16);
-
-		return ($msw << 16) | ($lsw & 0xFFFF);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Bitwise rotate a 32-bit number
-	 *
-	 * @access	private
-	 * @return	integer
-	 */
-	function _rol($num, $cnt)
-	{
-		return ($num << $cnt) | $this->_zero_fill($num, 32 - $cnt);
-	}
-
-	// --------------------------------------------------------------------
-
-	/**
-	 * Pad string with zero
-	 *
-	 * @access	private
-	 * @return	string
-	 */
-	function _zero_fill($a, $b)
-	{
-		$bin = decbin($a);
-
-		if (strlen($bin) < $b)
-		{
-			$bin = 0;
-		}
-		else
-		{
-			$bin = substr($bin, 0, strlen($bin) - $b);
-		}
-
-		for ($i=0; $i < $b; $i++)
-		{
-			$bin = "0".$bin;
-		}
-
-		return bindec($bin);
-	}
-}
-// END CI_SHA
-
-/* End of file Sha1.php */
-/* Location: ./system/libraries/Sha1.php */
diff --git a/system/libraries/Table.php b/system/libraries/Table.php
index 8d0e11a..fb154e5 100644
--- a/system/libraries/Table.php
+++ b/system/libraries/Table.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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.3.1
@@ -40,14 +40,14 @@
  */
 class CI_Table {
 
-	var $rows				= array();
-	var $heading			= array();
-	var $auto_heading		= TRUE;
-	var $caption			= NULL;
-	var $template			= NULL;
-	var $newline			= "\n";
-	var $empty_cells		= "";
-	var	$function			= FALSE;
+	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;
 
 	public function __construct()
 	{
@@ -59,11 +59,10 @@
 	/**
 	 * Set the template
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	void
 	 */
-	function set_template($template)
+	public function set_template($template)
 	{
 		if ( ! is_array($template))
 		{
@@ -80,11 +79,10 @@
 	 *
 	 * Can be passed as an array or discreet params
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	void
 	 */
-	function set_heading()
+	public function set_heading()
 	{
 		$args = func_get_args();
 		$this->heading = $this->_prep_args($args);
@@ -98,14 +96,13 @@
 	 * columns.  This allows a single array with many elements to  be
 	 * displayed in a table that has a fixed column count.
 	 *
-	 * @access	public
 	 * @param	array
 	 * @param	int
 	 * @return	void
 	 */
-	function make_columns($array = array(), $col_limit = 0)
+	public function make_columns($array = array(), $col_limit = 0)
 	{
-		if ( ! is_array($array) OR count($array) == 0)
+		if ( ! is_array($array) OR count($array) === 0)
 		{
 			return FALSE;
 		}
@@ -120,7 +117,7 @@
 		}
 
 		$new = array();
-		while (count($array) > 0)
+		do
 		{
 			$temp = array_splice($array, 0, $col_limit);
 
@@ -134,6 +131,7 @@
 
 			$new[] = $temp;
 		}
+		while (count($array) > 0);
 
 		return $new;
 	}
@@ -145,11 +143,10 @@
 	 *
 	 * Can be passed as an array or discreet params
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	void
 	 */
-	function set_empty($value)
+	public function set_empty($value)
 	{
 		$this->empty_cells = $value;
 	}
@@ -161,11 +158,10 @@
 	 *
 	 * Can be passed as an array or discreet params
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	void
 	 */
-	function add_row()
+	public function add_row()
 	{
 		$args = func_get_args();
 		$this->rows[] = $this->_prep_args($args);
@@ -178,16 +174,15 @@
 	 *
 	 * Ensures a standard associative array format for all cell data
 	 *
-	 * @access	public
 	 * @param	type
 	 * @return	type
 	 */
-	function _prep_args($args)
+	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]) AND (count($args) === 1 && is_array($args[0])))
 		{
 			// args sent as indexed array
 			if ( ! isset($args[0]['data']))
@@ -224,11 +219,10 @@
 	/**
 	 * Add a table caption
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
-	function set_caption($caption)
+	public function set_caption($caption)
 	{
 		$this->caption = $caption;
 	}
@@ -238,11 +232,10 @@
 	/**
 	 * Generate the table
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @return	string
 	 */
-	function generate($table_data = NULL)
+	public function generate($table_data = NULL)
 	{
 		// The table data can optionally be passed to this function
 		// either as a database result object or an array
@@ -254,13 +247,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 AND $this->auto_heading == FALSE) ? FALSE : TRUE;
 				$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)
+		if (count($this->heading) === 0 AND count($this->rows) === 0)
 		{
 			return 'Undefined table data';
 		}
@@ -273,24 +266,18 @@
 
 		// Build the table!
 
-		$out = $this->template['table_open'];
-		$out .= $this->newline;
+		$out = $this->template['table_open'].$this->newline;
 
 		// Add any caption here
 		if ($this->caption)
 		{
-			$out .= $this->newline;
-			$out .= '<caption>' . $this->caption . '</caption>';
-			$out .= $this->newline;
+			$out .= $this->newline.'<caption>'.$this->caption.'</caption>'.$this->newline;
 		}
 
 		// Is there a table heading to display?
 		if (count($this->heading) > 0)
 		{
-			$out .= $this->template['thead_open'];
-			$out .= $this->newline;
-			$out .= $this->template['heading_row_start'];
-			$out .= $this->newline;
+			$out .= $this->template['thead_open'].$this->newline.$this->template['heading_row_start'].$this->newline;
 
 			foreach ($this->heading as $heading)
 			{
@@ -304,22 +291,16 @@
 					}
 				}
 
-				$out .= $temp;
-				$out .= isset($heading['data']) ? $heading['data'] : '';
-				$out .= $this->template['heading_cell_end'];
+				$out .= $temp.(isset($heading['data']) ? $heading['data'] : '').$this->template['heading_cell_end'];
 			}
 
-			$out .= $this->template['heading_row_end'];
-			$out .= $this->newline;
-			$out .= $this->template['thead_close'];
-			$out .= $this->newline;
+			$out .= $this->template['heading_row_end'].$this->newline.$this->template['thead_close'].$this->newline;
 		}
 
 		// Build the table rows
 		if (count($this->rows) > 0)
 		{
-			$out .= $this->template['tbody_open'];
-			$out .= $this->newline;
+			$out .= $this->template['tbody_open'].$this->newline;
 
 			$i = 1;
 			foreach ($this->rows as $row)
@@ -332,8 +313,7 @@
 				// We use modulus to alternate the row colors
 				$name = (fmod($i++, 2)) ? '' : 'alt_';
 
-				$out .= $this->template['row_'.$name.'start'];
-				$out .= $this->newline;
+				$out .= $this->template['row_'.$name.'start'].$this->newline;
 
 				foreach ($row as $cell)
 				{
@@ -341,7 +321,7 @@
 
 					foreach ($cell as $key => $val)
 					{
-						if ($key != 'data')
+						if ($key !== 'data')
 						{
 							$temp = str_replace('<td', "<td $key='$val'", $temp);
 						}
@@ -369,12 +349,10 @@
 					$out .= $this->template['cell_'.$name.'end'];
 				}
 
-				$out .= $this->template['row_'.$name.'end'];
-				$out .= $this->newline;
+				$out .= $this->template['row_'.$name.'end'].$this->newline;
 			}
 
-			$out .= $this->template['tbody_close'];
-			$out .= $this->newline;
+			$out .= $this->template['tbody_close'].$this->newline;
 		}
 
 		$out .= $this->template['table_close'];
@@ -390,10 +368,9 @@
 	/**
 	 * Clears the table arrays.  Useful if multiple tables are being generated
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function clear()
+	public function clear()
 	{
 		$this->rows				= array();
 		$this->heading			= array();
@@ -405,11 +382,10 @@
 	/**
 	 * Set table data from a database result object
 	 *
-	 * @access	public
 	 * @param	object
 	 * @return	void
 	 */
-	function _set_from_object($query)
+	protected function _set_from_object($query)
 	{
 		if ( ! is_object($query))
 		{
@@ -417,7 +393,7 @@
 		}
 
 		// First generate the headings from the table column names
-		if (count($this->heading) == 0)
+		if (count($this->heading) === 0)
 		{
 			if ( ! method_exists($query, 'list_fields'))
 			{
@@ -443,13 +419,12 @@
 	/**
 	 * Set table data from an array
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	void
 	 */
-	function _set_from_array($data, $set_heading = TRUE)
+	protected function _set_from_array($data, $set_heading = TRUE)
 	{
-		if ( ! is_array($data) OR count($data) == 0)
+		if ( ! is_array($data) OR count($data) === 0)
 		{
 			return FALSE;
 		}
@@ -458,7 +433,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 AND count($data) > 1 AND count($this->heading) === 0 AND $set_heading == TRUE)
 			{
 				$this->heading = $this->_prep_args($row);
 			}
@@ -466,8 +441,6 @@
 			{
 				$this->rows[] = $this->_prep_args($row);
 			}
-
-			$i++;
 		}
 	}
 
@@ -476,10 +449,9 @@
 	/**
 	 * Compile Template
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _compile_template()
+	protected function _compile_template()
 	{
 		if ($this->template == NULL)
 		{
@@ -502,10 +474,9 @@
 	/**
 	 * Default Template
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _default_template()
+	protected function _default_template()
 	{
 		return  array (
 						'table_open'			=> '<table border="0" cellpadding="4" cellspacing="0">',
@@ -538,6 +509,5 @@
 
 }
 
-
 /* End of file Table.php */
 /* Location: ./system/libraries/Table.php */
diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php
index 1e59283..79a0091 100644
--- a/system/libraries/Trackback.php
+++ b/system/libraries/Trackback.php
@@ -1,4 +1,4 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -47,11 +47,6 @@
 	public $response		= '';
 	public $error_msg		= array();
 
-	/**
-	 * Constructor
-	 *
-	 * @access	public
-	 */
 	public function __construct()
 	{
 		log_message('debug', "Trackback Class Initialized");
@@ -62,7 +57,6 @@
 	/**
 	 * Send Trackback
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	bool
 	 */
@@ -96,20 +90,9 @@
 			}
 
 			// Convert High ASCII Characters
-			if ($this->convert_ascii == TRUE)
+			if ($this->convert_ascii == TRUE && in_array($item, array('excerpt', 'title', 'blog_name')))
 			{
-				if ($item == 'excerpt')
-				{
-					$$item = $this->convert_ascii($$item);
-				}
-				elseif ($item == 'title')
-				{
-					$$item = $this->convert_ascii($$item);
-				}
-				elseif ($item == 'blog_name')
-				{
-					$$item = $this->convert_ascii($$item);
-				}
+				$$item = $this->convert_ascii($$item);
 			}
 		}
 
@@ -144,7 +127,6 @@
 	 * If the data is valid it is set to the $this->data array
 	 * so that it can be inserted into a database.
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function receive()
@@ -186,7 +168,6 @@
 	 * sends the "incomplete information" error, as that's
 	 * the most common one.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
@@ -204,7 +185,6 @@
 	 * This should be called when a trackback has been
 	 * successfully received and inserted.
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function send_success()
@@ -218,7 +198,6 @@
 	/**
 	 * Fetch a particular item
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -235,7 +214,6 @@
 	 * Opens a socket connection and passes the data to
 	 * the server.  Returns TRUE on success, FALSE on failure
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	bool
@@ -280,15 +258,9 @@
 		@fclose($fp);
 
 
-		if (stristr($this->response, '<error>0</error>') === FALSE)
+		if (stripos($this->response, '<error>0</error>') === FALSE)
 		{
-			$message = 'An unknown error was encountered';
-
-			if (preg_match("/<message>(.*?)<\/message>/is", $this->response, $match))
-			{
-				$message = trim($match['1']);
-			}
-
+			$message = (preg_match('/<message>(.*?)<\/message>/is', $this->response, $match)) ? trim($match[1]) : 'An unknown error was encountered';
 			$this->set_error($message);
 			return FALSE;
 		}
@@ -305,7 +277,6 @@
 	 * It takes a string of URLs (separated by comma or
 	 * space) and puts each URL into an array
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -318,7 +289,7 @@
 		$urls = str_replace(",,", ",", $urls);
 
 		// Remove any comma that might be at the end
-		if (substr($urls, -1) == ",")
+		if (substr($urls, -1) === ',')
 		{
 			$urls = substr($urls, 0, -1);
 		}
@@ -341,7 +312,6 @@
 	 *
 	 * Simply adds "http://" if missing
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -349,9 +319,9 @@
 	{
 		$url = trim($url);
 
-		if (substr($url, 0, 4) != "http")
+		if (strpos($url, 'http') !== 0)
 		{
-			$url = "http://".$url;
+			$url = 'http://'.$url;
 		}
 	}
 
@@ -360,7 +330,6 @@
 	/**
 	 * Find the Trackback URL's ID
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -409,7 +378,6 @@
 	/**
 	 * Convert Reserved XML characters to Entities
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -417,15 +385,13 @@
 	{
 		$temp = '__TEMP_AMPERSANDS__';
 
-		$str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
-		$str = preg_replace("/&(\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 = preg_replace("/$temp(\d+);/","&#\\1;",$str);
-		$str = preg_replace("/$temp(\w+);/","&\\1;", $str);
+		$str = preg_replace(array("/$temp(\d+);/", "/$temp(\w+);/"), array('&#\\1;', '&\\1;'), $str);
 
 		return $str;
 	}
@@ -437,7 +403,6 @@
 	 *
 	 * Limits the string based on the character count. Will preserve complete words.
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	integer
 	 * @param	string
@@ -457,13 +422,13 @@
 			return $str;
 		}
 
-		$out = "";
+		$out = '';
 		foreach (explode(' ', trim($str)) as $val)
 		{
 			$out .= $val.' ';
 			if (strlen($out) >= $n)
 			{
-				return trim($out).$end_char;
+				return rtrim($out).$end_char;
 			}
 		}
 	}
@@ -476,7 +441,6 @@
 	 * Converts Hight ascii text and MS Word special chars
 	 * to character entities
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
@@ -496,16 +460,16 @@
 			}
 			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;
@@ -522,7 +486,6 @@
 	/**
 	 * Set error message
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
@@ -537,7 +500,6 @@
 	/**
 	 * Show error messages
 	 *
-	 * @access	public
 	 * @param	string
 	 * @param	string
 	 * @return	string
diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php
index af6ca2b..46c73ef 100644
--- a/system/libraries/Typography.php
+++ b/system/libraries/Typography.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -31,7 +31,7 @@
  * Typography Class
  *
  *
- * @access		private
+ * @access		protected
  * @category	Helpers
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/libraries/typography.html
@@ -39,22 +39,22 @@
 class CI_Typography {
 
 	// Block level elements that should not be wrapped inside <p> tags
-	var $block_elements = 'address|blockquote|div|dl|fieldset|form|h\d|hr|noscript|object|ol|p|pre|script|table|ul';
+	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.
-	var $skip_elements	= 'p|pre|ol|ul|dl|object|table|h\d';
+	public $skip_elements	= 'p|pre|ol|ul|dl|object|table|h\d';
 
 	// Tags we want the parser to completely ignore when splitting the string.
-	var $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';
+	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
-	var $inner_block_required = array('blockquote');
+	public $inner_block_required = array('blockquote');
 
 	// the last block element parsed
-	var $last_block_element = '';
+	public $last_block_element = '';
 
 	// whether or not to protect quotes within { curly braces }
-	var $protect_braced_quotes = FALSE;
+	public $protect_braced_quotes = FALSE;
 
 	/**
 	 * Auto Typography
@@ -72,7 +72,7 @@
 	 * @param	bool	whether to reduce more then two consecutive newlines to two
 	 * @return	string
 	 */
-	function auto_typography($str, $reduce_linebreaks = FALSE)
+	public function auto_typography($str, $reduce_linebreaks = FALSE)
 	{
 		if ($str == '')
 		{
@@ -127,35 +127,32 @@
 		// adversely affected if they are split out so we'll convert the opening bracket < temporarily to: {@TAG}
 		$str = preg_replace("#<(/*)(".$this->inline_elements.")([ >])#i", "{@TAG}\\1\\2\\3", $str);
 
-		// Split the string at every tag.  This expression creates an array with this prototype:
-		//
-		//	[array]
-		//	{
-		//		[0] = <opening tag>
-		//		[1] = Content...
-		//		[2] = <closing tag>
-		//		Etc...
-		//	}
+		/* Split the string at every tag. This expression creates an array with this prototype:
+		 *
+		 *	[array]
+		 *	{
+		 *		[0] = <opening tag>
+		 *		[1] = Content...
+		 *		[2] = <closing tag>
+		 *		Etc...
+		 *	}
+		 */
 		$chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
 
 		// Build our finalized string.  We cycle through the array, skipping tags, and processing the contained text
 		$str = '';
 		$process = TRUE;
 		$paragraph = FALSE;
-		$current_chunk = 0;
-		$total_chunks = count($chunks);
 
-		foreach ($chunks as $chunk)
+		for ($i = 0, $c = count($chunks) - 1; $i <= $c; $i++)
 		{
-			$current_chunk++;
-
 			// Are we dealing with a tag? If so, we'll skip the processing for this cycle.
 			// Well also set the "process" flag which allows us to skip <pre> tags and a few other things.
-			if (preg_match("#<(/*)(".$this->block_elements.").*?>#", $chunk, $match))
+			if (preg_match("#<(/*)(".$this->block_elements.").*?>#", $chunks[$i], $match))
 			{
 				if (preg_match("#".$this->skip_elements."#", $match[2]))
 				{
-					$process =  ($match[1] == '/') ? TRUE : FALSE;
+					$process = ($match[1] === '/');
 				}
 
 				if ($match[1] == '')
@@ -163,24 +160,24 @@
 					$this->last_block_element = $match[2];
 				}
 
-				$str .= $chunk;
+				$str .= $chunks[$i];
 				continue;
 			}
 
-			if ($process == FALSE)
+			if ($process === FALSE)
 			{
-				$str .= $chunk;
+				$str .= $chunks[$i];
 				continue;
 			}
 
 			//  Force a newline to make sure end tags get processed by _format_newlines()
-			if ($current_chunk == $total_chunks)
+			if ($i === $c)
 			{
-				$chunk .= "\n";
+				$chunks[$i] .= "\n";
 			}
 
 			//  Convert Newlines into <p> and <br /> tags
-			$str .= $this->_format_newlines($chunk);
+			$str .= $this->_format_newlines($chunks[$i]);
 		}
 
 		// No opening block level tag?  Add it if needed.
@@ -265,7 +262,7 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function format_characters($str)
+	public function format_characters($str)
 	{
 		static $table;
 
@@ -325,18 +322,13 @@
 	 *
 	 * Converts newline characters into either <p> tags or <br />
 	 *
-	 * @access	public
+	 * @access	protected
 	 * @param	string
 	 * @return	string
 	 */
-	function _format_newlines($str)
+	protected function _format_newlines($str)
 	{
-		if ($str == '')
-		{
-			return $str;
-		}
-
-		if (strpos($str, "\n") === FALSE  && ! in_array($this->last_block_element, $this->inner_block_required))
+		if ($str == '' OR (strpos($str, "\n") === FALSE AND ! in_array($this->last_block_element, $this->inner_block_required)))
 		{
 			return $str;
 		}
@@ -373,11 +365,11 @@
 	 * and we don't want double dashes converted to emdash entities, so they are marked with {@DD}
 	 * likewise double spaces are converted to {@NBS} to prevent entity conversion
 	 *
-	 * @access	public
+	 * @access	protected
 	 * @param	array
 	 * @return	string
 	 */
-	function _protect_characters($match)
+	protected function _protect_characters($match)
 	{
 		return str_replace(array("'",'"','--','  '), array('{@SQ}', '{@DQ}', '{@DD}', '{@NBS}'), $match[0]);
 	}
@@ -391,25 +383,16 @@
 	 * @param	string
 	 * @return	string
 	 */
-	function nl2br_except_pre($str)
+	public function nl2br_except_pre($str)
 	{
-		$ex = explode("pre>",$str);
-		$ct = count($ex);
-
-		$newstr = "";
-		for ($i = 0; $i < $ct; $i++)
+		$newstr = '';
+		for ($ex = explode('pre>', $str), $ct = count($ex), $i = 0; $i < $ct; $i++)
 		{
-			if (($i % 2) == 0)
+			$newstr .= (($i % 2) === 0) ? nl2br($ex[$i]) : $ex[$i];
+			if ($ct - 1 !== $i)
 			{
-				$newstr .= nl2br($ex[$i]);
+				$newstr .= 'pre>';
 			}
-			else
-			{
-				$newstr .= $ex[$i];
-			}
-
-			if ($ct - 1 != $i)
-				$newstr .= "pre>";
 		}
 
 		return $newstr;
diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php
index 7afe40b..38d767c 100644
--- a/system/libraries/Unit_test.php
+++ b/system/libraries/Unit_test.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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.3.1
@@ -40,12 +40,12 @@
  */
 class CI_Unit_test {
 
-	var $active					= TRUE;
-	var $results				= array();
-	var $strict					= FALSE;
-	var $_template				= NULL;
-	var $_template_rows			= NULL;
-	var $_test_items_visible	= array();
+	public $active					= TRUE;
+	public $results				= array();
+	public $strict					= FALSE;
+	protected $_template				= NULL;
+	protected $_template_rows			= NULL;
+	protected $_test_items_visible	= array();
 
 	public function __construct()
 	{
@@ -70,11 +70,10 @@
 	 *
 	 * Runs the supplied tests
 	 *
-	 * @access	public
 	 * @param	array
 	 * @return	void
 	 */
-	function set_test_items($items = array())
+	public function set_test_items($items = array())
 	{
 		if ( ! empty($items) AND is_array($items))
 		{
@@ -89,13 +88,12 @@
 	 *
 	 * Runs the supplied tests
 	 *
-	 * @access	public
 	 * @param	mixed
 	 * @param	mixed
 	 * @param	string
 	 * @return	string
 	 */
-	function run($test, $expected = TRUE, $test_name = 'undefined', $notes = '')
+	public function run($test, $expected = TRUE, $test_name = 'undefined', $notes = '')
 	{
 		if ($this->active == FALSE)
 		{
@@ -110,11 +108,7 @@
 		}
 		else
 		{
-			if ($this->strict == TRUE)
-				$result = ($test === $expected) ? TRUE : FALSE;
-			else
-				$result = ($test == $expected) ? TRUE : FALSE;
-
+			$result = ($this->strict == TRUE) ? ($test === $expected) : ($test == $expected);
 			$extype = gettype($expected);
 		}
 
@@ -142,12 +136,11 @@
 	 *
 	 * Displays a table with the test data
 	 *
-	 * @access	public
 	 * @return	string
 	 */
-	function report($result = array())
+	public function report($result = array())
 	{
-		if (count($result) == 0)
+		if (count($result) === 0)
 		{
 			$result = $this->result();
 		}
@@ -176,10 +169,7 @@
 					}
 				}
 
-				$temp = $this->_template_rows;
-				$temp = str_replace('{item}', $key, $temp);
-				$temp = str_replace('{result}', $val, $temp);
-				$table .= $temp;
+				$table .= str_replace(array('{item}', '{result}'), array($key, $val), $this->_template_rows);
 			}
 
 			$r .= str_replace('{rows}', $table, $this->_template);
@@ -195,13 +185,12 @@
 	 *
 	 * Causes the evaluation to use === rather than ==
 	 *
-	 * @access	public
 	 * @param	bool
 	 * @return	null
 	 */
-	function use_strict($state = TRUE)
+	public function use_strict($state = TRUE)
 	{
-		$this->strict = ($state == FALSE) ? FALSE : TRUE;
+		$this->strict = (bool) $state;
 	}
 
 	// --------------------------------------------------------------------
@@ -211,13 +200,12 @@
 	 *
 	 * Enables/disables unit testing
 	 *
-	 * @access	public
 	 * @param	bool
 	 * @return	null
 	 */
-	function active($state = TRUE)
+	public function active($state = TRUE)
 	{
-		$this->active = ($state == FALSE) ? FALSE : TRUE;
+		$this->active = (bool) $state;
 	}
 
 	// --------------------------------------------------------------------
@@ -227,15 +215,14 @@
 	 *
 	 * Returns the raw result data
 	 *
-	 * @access	public
 	 * @return	array
 	 */
-	function result($results = array())
+	public function result($results = array())
 	{
 		$CI =& get_instance();
 		$CI->load->language('unit_test');
 
-		if (count($results) == 0)
+		if (count($results) === 0)
 		{
 			$results = $this->results;
 		}
@@ -285,11 +272,10 @@
 	 *
 	 * This lets us set the template to be used to display results
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	void
 	 */
-	function set_template($template)
+	public function set_template($template)
 	{
 		$this->_template = $template;
 	}
@@ -301,19 +287,17 @@
 	 *
 	 * This lets us show file names and line numbers
 	 *
-	 * @access	private
 	 * @return	array
 	 */
-	function _backtrace()
+	protected function _backtrace()
 	{
 		if (function_exists('debug_backtrace'))
 		{
 			$back = debug_backtrace();
-
-			$file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file'];
-			$line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line'];
-
-			return array('file' => $file, 'line' => $line);
+			return array(
+					'file' => (isset($back[1]['file']) ? $back[1]['file'] : ''),
+					'line' => (isset($back[1]['line']) ? $back[1]['line'] : '')
+				);
 		}
 		return array('file' => 'Unknown', 'line' => 'Unknown');
 	}
@@ -323,19 +307,14 @@
 	/**
 	 * Get Default Template
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _default_template()
+	protected function _default_template()
 	{
-		$this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">';
-		$this->_template .= '{rows}';
-		$this->_template .= "\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>';
-		$this->_template_rows .= "\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>';
-		$this->_template_rows .= "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>';
-		$this->_template_rows .= "\n\t".'</tr>';
+		$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>";
 	}
 
 	// --------------------------------------------------------------------
@@ -345,30 +324,23 @@
 	 *
 	 * Harvests the data within the template {pseudo-variables}
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	function _parse_template()
+	protected function _parse_template()
 	{
 		if ( ! is_null($this->_template_rows))
 		{
 			return;
 		}
 
-		if (is_null($this->_template))
+		if (is_null($this->_template) OR ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))
 		{
 			$this->_default_template();
 			return;
 		}
 
-		if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match))
-		{
-			$this->_default_template();
-			return;
-		}
-
-		$this->_template_rows = $match['1'];
-		$this->_template = str_replace($match['0'], '{rows}', $this->_template);
+		$this->_template_rows = $match[1];
+		$this->_template = str_replace($match[0], '{rows}', $this->_template);
 	}
 
 }
@@ -377,8 +349,6 @@
 /**
  * Helper functions to test boolean true/false
  *
- *
- * @access	private
  * @return	bool
  */
 function is_true($test)
diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php
index 826bcce..89575c8 100644
--- a/system/libraries/Upload.php
+++ b/system/libraries/Upload.php
@@ -1,4 +1,4 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 /**
  * CodeIgniter
  *
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -593,16 +593,17 @@
 	/**
 	 * Verify that the filetype is allowed
 	 *
+	 * @param	bool
 	 * @return	bool
 	 */
 	public function is_allowed_filetype($ignore_mime = FALSE)
 	{
-		if ($this->allowed_types == '*')
+		if ($this->allowed_types === '*')
 		{
 			return TRUE;
 		}
 
-		if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types))
+		if ( ! is_array($this->allowed_types) OR count($this->allowed_types) === 0)
 		{
 			$this->set_error('upload_no_file_types');
 			return FALSE;
@@ -618,12 +619,9 @@
 		// Images get some additional checks
 		$image_types = array('gif', 'jpg', 'jpeg', 'png', 'jpe');
 
-		if (in_array($ext, $image_types))
+		if (in_array($ext, $image_types) && @getimagesize($this->file_temp) === FALSE)
 		{
-			if (getimagesize($this->file_temp) === FALSE)
-			{
-				return FALSE;
-			}
+			return FALSE;
 		}
 
 		if ($ignore_mime === TRUE)
@@ -640,7 +638,7 @@
 				return TRUE;
 			}
 		}
-		elseif ($mime == $this->file_type)
+		elseif ($mime === $this->file_type)
 		{
 				return TRUE;
 		}
@@ -960,7 +958,7 @@
 			}
 			elseif (is_file(APPPATH.'config/mimes.php'))
 			{
-				include(APPPATH.'config//mimes.php');
+				include(APPPATH.'config/mimes.php');
 			}
 			else
 			{
@@ -1026,47 +1024,104 @@
 	 */
 	protected function _file_mime_type($file)
 	{
-		// Use if the Fileinfo extension, if available (only versions above 5.3 support the FILEINFO_MIME_TYPE flag)
-		if ( (float) substr(phpversion(), 0, 3) >= 5.3 && function_exists('finfo_file'))
+		// We'll need this to validate the MIME info string (e.g. text/plain; charset=us-ascii)
+		$regexp = '/^([a-z\-]+\/[a-z0-9\-\.\+]+)(;\s.+)?$/';
+
+		/* Fileinfo extension - most reliable method
+		 *
+		 * Unfortunately, prior to PHP 5.3 - it's only available as a PECL extension and the
+		 * more convenient FILEINFO_MIME_TYPE flag doesn't exist.
+		 */
+		if (function_exists('finfo_file'))
 		{
-			$finfo = new finfo(FILEINFO_MIME_TYPE);
-			if ($finfo !== FALSE) // This is possible, if there is no magic MIME database file found on the system
+			$finfo = finfo_open(FILEINFO_MIME);
+			if (is_resource($finfo)) // It is possible that a FALSE value is returned, if there is no magic MIME database file found on the system
 			{
-				$file_type = $finfo->file($file['tmp_name']);
+				$mime = @finfo_file($finfo, $file['tmp_name']);
+				finfo_close($finfo);
 
 				/* According to the comments section of the PHP manual page,
 				 * it is possible that this function returns an empty string
 				 * for some files (e.g. if they don't exist in the magic MIME database)
 				 */
-				if (strlen($file_type) > 1)
+				if (is_string($mime) && preg_match($regexp, $mime, $matches))
 				{
-					$this->file_type = $file_type;
+					$this->file_type = $matches[1];
 					return;
 				}
 			}
 		}
 
-		// Fall back to the deprecated mime_content_type(), if available
+		/* This is an ugly hack, but UNIX-type systems provide a "native" way to detect the file type,
+		 * which is still more secure than depending on the value of $_FILES[$field]['type'], and as it
+		 * was reported in issue #750 (https://github.com/EllisLab/CodeIgniter/issues/750) - it's better
+		 * than mime_content_type() as well, hence the attempts to try calling the command line with
+		 * three different functions.
+		 *
+		 * Notes:
+		 *	- the DIRECTORY_SEPARATOR comparison ensures that we're not on a Windows system
+		 *	- many system admins would disable the exec(), shell_exec(), popen() and similar functions
+		 *	  due to security concerns, hence the function_exists() checks
+		 */
+		if (DIRECTORY_SEPARATOR !== '\\')
+		{
+			$cmd = 'file --brief --mime ' . escapeshellarg($file['tmp_name']) . ' 2>&1';
+
+			if (function_exists('exec'))
+			{
+				/* This might look confusing, as $mime is being populated with all of the output when set in the second parameter.
+				 * However, we only neeed the last line, which is the actual return value of exec(), and as such - it overwrites
+				 * anything that could already be set for $mime previously. This effectively makes the second parameter a dummy
+				 * value, which is only put to allow us to get the return status code.
+				 */
+				$mime = @exec($cmd, $mime, $return_status);
+				if ($return_status === 0 && is_string($mime) && preg_match($regexp, $mime, $matches))
+				{
+					$this->file_type = $matches[1];
+					return;
+				}
+			}
+
+			if ( (bool) @ini_get('safe_mode') === FALSE && function_exists('shell_exec'))
+			{
+				$mime = @shell_exec($cmd);
+				if (strlen($mime) > 0)
+				{
+					$mime = explode("\n", trim($mime));
+					if (preg_match($regexp, $mime[(count($mime) - 1)], $matches))
+					{
+						$this->file_type = $matches[1];
+						return;
+					}
+				}
+			}
+
+			if (function_exists('popen'))
+			{
+				$proc = @popen($cmd, 'r');
+				if (is_resource($proc))
+				{
+					$mime = @fread($proc, 512);
+					@pclose($proc);
+					if ($mime !== FALSE)
+					{
+						$mime = explode("\n", trim($mime));
+						if (preg_match($regexp, $mime[(count($mime) - 1)], $matches))
+						{
+							$this->file_type = $matches[1];
+							return;
+						}
+					}
+				}
+			}
+		}
+
+		// Fall back to the deprecated mime_content_type(), if available (still better than $_FILES[$field]['type'])
 		if (function_exists('mime_content_type'))
 		{
 			$this->file_type = @mime_content_type($file['tmp_name']);
-			return;
-		}
-
-		/* This is an ugly hack, but UNIX-type systems provide a native way to detect the file type,
-		 * which is still more secure than depending on the value of $_FILES[$field]['type'].
-		 *
-		 * Notes:
-		 *	- a 'W' in the substr() expression bellow, would mean that we're using Windows
-		 *	- many system admins would disable the exec() function due to security concerns, hence the function_exists() check
-		 */
-		if (DIRECTORY_SEPARATOR !== '\\' && function_exists('exec'))
-		{
-			$output = array();
-			@exec('file --brief --mime-type ' . escapeshellarg($file['tmp_path']), $output, $return_code);
-			if ($return_code === 0 && strlen($output[0]) > 0) // A return status code != 0 would mean failed execution
+			if (strlen($this->file_type) > 0) // It's possible that mime_content_type() returns FALSE or an empty string
 			{
-				$this->file_type = rtrim($output[0]);
 				return;
 			}
 		}
diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php
index a007ace..cd644c0 100644
--- a/system/libraries/User_agent.php
+++ b/system/libraries/User_agent.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -40,32 +40,31 @@
  */
 class CI_User_agent {
 
-	var $agent		= NULL;
+	public $agent		= NULL;
 
-	var $is_browser	= FALSE;
-	var $is_robot	= FALSE;
-	var $is_mobile	= FALSE;
+	public $is_browser	= FALSE;
+	public $is_robot	= FALSE;
+	public $is_mobile	= FALSE;
 
-	var $languages	= array();
-	var $charsets	= array();
+	public $languages	= array();
+	public $charsets	= array();
 
-	var $platforms	= array();
-	var $browsers	= array();
-	var $mobiles	= array();
-	var $robots		= array();
+	public $platforms	= array();
+	public $browsers	= array();
+	public $mobiles		= array();
+	public $robots		= array();
 
-	var $platform	= '';
-	var $browser	= '';
-	var $version	= '';
-	var $mobile		= '';
-	var $robot		= '';
+	public $platform	= '';
+	public $browser		= '';
+	public $version		= '';
+	public $mobile		= '';
+	public $robot		= '';
 
 	/**
 	 * Constructor
 	 *
 	 * Sets the User Agent and runs the compilation routine
 	 *
-	 * @access	public
 	 * @return	void
 	 */
 	public function __construct()
@@ -91,10 +90,9 @@
 	/**
 	 * Compile the User Agent Data
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	private function _load_agent_file()
+	protected function _load_agent_file()
 	{
 		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php'))
 		{
@@ -147,10 +145,9 @@
 	/**
 	 * Compile the User Agent Data
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	private function _compile_data()
+	protected function _compile_data()
 	{
 		$this->_set_platform();
 
@@ -168,10 +165,9 @@
 	/**
 	 * Set the Platform
 	 *
-	 * @access	private
 	 * @return	mixed
 	 */
-	private function _set_platform()
+	protected function _set_platform()
 	{
 		if (is_array($this->platforms) AND count($this->platforms) > 0)
 		{
@@ -192,10 +188,9 @@
 	/**
 	 * Set the Browser
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	private function _set_browser()
+	protected function _set_browser()
 	{
 		if (is_array($this->browsers) AND count($this->browsers) > 0)
 		{
@@ -219,10 +214,9 @@
 	/**
 	 * Set the Robot
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	private function _set_robot()
+	protected function _set_robot()
 	{
 		if (is_array($this->robots) AND count($this->robots) > 0)
 		{
@@ -244,10 +238,9 @@
 	/**
 	 * Set the Mobile Device
 	 *
-	 * @access	private
 	 * @return	bool
 	 */
-	private function _set_mobile()
+	protected function _set_mobile()
 	{
 		if (is_array($this->mobiles) AND count($this->mobiles) > 0)
 		{
@@ -269,19 +262,16 @@
 	/**
 	 * Set the accepted languages
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	private function _set_languages()
+	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) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '')
 		{
-			$languages = preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE'])));
-
-			$this->languages = explode(',', $languages);
+			$this->languages = explode(',', preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE']))));
 		}
 
-		if (count($this->languages) == 0)
+		if (count($this->languages) === 0)
 		{
 			$this->languages = array('Undefined');
 		}
@@ -292,19 +282,16 @@
 	/**
 	 * Set the accepted character sets
 	 *
-	 * @access	private
 	 * @return	void
 	 */
-	private function _set_charsets()
+	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) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '')
 		{
-			$charsets = preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET'])));
-
-			$this->charsets = explode(',', $charsets);
+			$this->charsets = explode(',', preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET']))));
 		}
 
-		if (count($this->charsets) == 0)
+		if (count($this->charsets) === 0)
 		{
 			$this->charsets = array('Undefined');
 		}
@@ -315,7 +302,6 @@
 	/**
 	 * Is Browser
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function is_browser($key = NULL)
@@ -340,7 +326,6 @@
 	/**
 	 * Is Robot
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function is_robot($key = NULL)
@@ -365,7 +350,6 @@
 	/**
 	 * Is Mobile
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function is_mobile($key = NULL)
@@ -390,16 +374,11 @@
 	/**
 	 * Is this a referral from another site?
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function is_referral()
 	{
-		if ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '')
-		{
-			return FALSE;
-		}
-		return TRUE;
+		return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE;
 	}
 
 	// --------------------------------------------------------------------
@@ -407,7 +386,6 @@
 	/**
 	 * Agent String
 	 *
-	 * @access	public
 	 * @return	string
 	 */
 	public function agent_string()
@@ -420,7 +398,6 @@
 	/**
 	 * Get Platform
 	 *
-	 * @access	public
 	 * @return	string
 	 */
 	public function platform()
@@ -433,7 +410,6 @@
 	/**
 	 * Get Browser Name
 	 *
-	 * @access	public
 	 * @return	string
 	 */
 	public function browser()
@@ -446,7 +422,6 @@
 	/**
 	 * Get the Browser Version
 	 *
-	 * @access	public
 	 * @return	string
 	 */
 	public function version()
@@ -459,7 +434,6 @@
 	/**
 	 * Get The Robot Name
 	 *
-	 * @access	public
 	 * @return	string
 	 */
 	public function robot()
@@ -471,7 +445,6 @@
 	/**
 	 * Get the Mobile Device
 	 *
-	 * @access	public
 	 * @return	string
 	 */
 	public function mobile()
@@ -484,7 +457,6 @@
 	/**
 	 * Get the referrer
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function referrer()
@@ -497,12 +469,11 @@
 	/**
 	 * Get the accepted languages
 	 *
-	 * @access	public
 	 * @return	array
 	 */
 	public function languages()
 	{
-		if (count($this->languages) == 0)
+		if (count($this->languages) === 0)
 		{
 			$this->_set_languages();
 		}
@@ -515,12 +486,11 @@
 	/**
 	 * Get the accepted Character Sets
 	 *
-	 * @access	public
 	 * @return	array
 	 */
 	public function charsets()
 	{
-		if (count($this->charsets) == 0)
+		if (count($this->charsets) === 0)
 		{
 			$this->_set_charsets();
 		}
@@ -533,7 +503,6 @@
 	/**
 	 * Test for a particular language
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function accept_lang($lang = 'en')
@@ -546,7 +515,6 @@
 	/**
 	 * Test for a particular character set
 	 *
-	 * @access	public
 	 * @return	bool
 	 */
 	public function accept_charset($charset = 'utf-8')
@@ -556,6 +524,5 @@
 
 }
 
-
 /* End of file User_agent.php */
 /* Location: ./system/libraries/User_agent.php */
diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php
index 7b1e3fa..730a0fc 100644
--- a/system/libraries/Xmlrpc.php
+++ b/system/libraries/Xmlrpc.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -44,38 +44,38 @@
  */
 class CI_Xmlrpc {
 
-	var $debug			= FALSE;	// Debugging on or off
-	var $xmlrpcI4		= 'i4';
-	var $xmlrpcInt		= 'int';
-	var $xmlrpcBoolean	= 'boolean';
-	var $xmlrpcDouble	= 'double';
-	var $xmlrpcString	= 'string';
-	var $xmlrpcDateTime	= 'dateTime.iso8601';
-	var $xmlrpcBase64	= 'base64';
-	var $xmlrpcArray	= 'array';
-	var $xmlrpcStruct	= 'struct';
+	public $debug		= FALSE;	// Debugging on or off
+	public $xmlrpcI4	= 'i4';
+	public $xmlrpcInt	= 'int';
+	public $xmlrpcBoolean	= 'boolean';
+	public $xmlrpcDouble	= 'double';
+	public $xmlrpcString	= 'string';
+	public $xmlrpcDateTime	= 'dateTime.iso8601';
+	public $xmlrpcBase64	= 'base64';
+	public $xmlrpcArray	= 'array';
+	public $xmlrpcStruct	= 'struct';
 
-	var $xmlrpcTypes	= array();
-	var $valid_parents	= array();
-	var $xmlrpcerr		= array();	// Response numbers
-	var $xmlrpcstr		= array();  // Response strings
+	public $xmlrpcTypes	= array();
+	public $valid_parents	= array();
+	public $xmlrpcerr		= array(); // Response numbers
+	public $xmlrpcstr		= array(); // Response strings
 
-	var $xmlrpc_defencoding = 'UTF-8';
-	var $xmlrpcName			= 'XML-RPC for CodeIgniter';
-	var $xmlrpcVersion		= '1.1';
-	var $xmlrpcerruser		= 800; // Start of user errors
-	var $xmlrpcerrxml		= 100; // Start of XML Parse errors
-	var $xmlrpc_backslash	= ''; // formulate backslashes for escaping regexp
+	public $xmlrpc_defencoding	= 'UTF-8';
+	public $xmlrpcName		= 'XML-RPC for CodeIgniter';
+	public $xmlrpcVersion		= '1.1';
+	public $xmlrpcerruser		= 800; // Start of user errors
+	public $xmlrpcerrxml		= 100; // Start of XML Parse errors
+	public $xmlrpc_backslash	= ''; // formulate backslashes for escaping regexp
 
-	var $client;
-	var $method;
-	var $data;
-	var $message			= '';
-	var $error				= '';		// Error string for request
-	var $result;
-	var $response			= array();  // Response from remote server
+	public $client;
+	public $method;
+	public $data;
+	public $message			= '';
+	public $error			= '';	// Error string for request
+	public $result;
+	public $response		= array();  // Response from remote server
 
-	var $xss_clean			= TRUE;
+	public $xss_clean		= TRUE;
 
 	//-------------------------------------
 	//  VALUES THAT MULTIPLE CLASSES NEED
@@ -83,7 +83,7 @@
 
 	public function __construct($config = array())
 	{
-		$this->xmlrpcName		= $this->xmlrpcName;
+		$this->xmlrpcName	= $this->xmlrpcName;
 		$this->xmlrpc_backslash = chr(92).chr(92);
 
 		// Types for info sent back and forth
@@ -101,23 +101,23 @@
 
 		// 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')
-									 );
+						'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
@@ -128,7 +128,7 @@
 		$this->xmlrpcerr['incorrect_params'] = '3';
 		$this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method';
 		$this->xmlrpcerr['introspect_unknown'] = '4';
-		$this->xmlrpcstr['introspect_unknown'] = "Cannot inspect signature for request: method unknown";
+		$this->xmlrpcstr['introspect_unknown'] = 'Cannot inspect signature for request: method unknown';
 		$this->xmlrpcerr['http_error'] = '5';
 		$this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server.";
 		$this->xmlrpcerr['no_data'] = '6';
@@ -144,7 +144,7 @@
 	//  Initialize Prefs
 	//-------------------------------------
 
-	function initialize($config = array())
+	public function initialize($config = array())
 	{
 		if (count($config) > 0)
 		{
@@ -163,9 +163,9 @@
 	//  Take URL and parse it
 	//-------------------------------------
 
-	function server($url, $port=80)
+	public function server($url, $port=80)
 	{
-		if (substr($url, 0, 4) != "http")
+		if (strpos($url, 'http') !== 0)
 		{
 			$url = "http://".$url;
 		}
@@ -187,7 +187,7 @@
 	//  Set Timeout
 	//-------------------------------------
 
-	function timeout($seconds=5)
+	public function timeout($seconds = 5)
 	{
 		if ( ! is_null($this->client) && is_int($seconds))
 		{
@@ -200,7 +200,7 @@
 	//  Set Methods
 	//-------------------------------------
 
-	function method($function)
+	public function method($function)
 	{
 		$this->method = $function;
 	}
@@ -210,7 +210,7 @@
 	//  Take Array of Data and Create Objects
 	//-------------------------------------
 
-	function request($incoming)
+	public function request($incoming)
 	{
 		if ( ! is_array($incoming))
 		{
@@ -231,42 +231,34 @@
 	//  Set Debug
 	//-------------------------------------
 
-	function set_debug($flag = TRUE)
+	public function set_debug($flag = TRUE)
 	{
-		$this->debug = ($flag == TRUE) ? TRUE : FALSE;
+		$this->debug = ($flag == TRUE);
 	}
 
 	//-------------------------------------
 	//  Values Parsing
 	//-------------------------------------
 
-	function values_parsing($value, $return = FALSE)
+	public function values_parsing($value, $return = FALSE)
 	{
 		if (is_array($value) && array_key_exists(0, $value))
 		{
-			if ( ! isset($value['1']) OR ( ! isset($this->xmlrpcTypes[$value['1']])))
+			if ( ! isset($value[1]) OR ( ! isset($this->xmlrpcTypes[$value[1]])))
 			{
-				if (is_array($value[0]))
-				{
-					$temp = new XML_RPC_Values($value['0'], 'array');
-				}
-				else
-				{
-					$temp = new XML_RPC_Values($value['0'], 'string');
-				}
-			}
-			elseif (is_array($value['0']) && ($value['1'] == 'struct' OR $value['1'] == 'array'))
-			{
-				while (list($k) = each($value['0']))
-				{
-					$value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE);
-				}
-
-				$temp = new XML_RPC_Values($value['0'], $value['1']);
+				$temp = new XML_RPC_Values($value[0], (is_array($value[0]) ? 'array' : 'string'));
 			}
 			else
 			{
-				$temp = new XML_RPC_Values($value['0'], $value['1']);
+				if (is_array($value[0]) && ($value[1] == 'struct' OR $value[1] == 'array'))
+				{
+					while (list($k) = each($value[0]))
+					{
+						$value[0][$k] = $this->values_parsing($value[0][$k], TRUE);
+					}
+				}
+
+				$temp = new XML_RPC_Values($value[0], $value[1]);
 			}
 		}
 		else
@@ -283,24 +275,18 @@
 	//  Sends XML-RPC Request
 	//-------------------------------------
 
-	function send_request()
+	public function send_request()
 	{
 		$this->message = new XML_RPC_Message($this->method,$this->data);
 		$this->message->debug = $this->debug;
 
-		if ( ! $this->result = $this->client->send($this->message))
-		{
-			$this->error = $this->result->errstr;
-			return FALSE;
-		}
-		elseif ( ! is_object($this->result->val))
+		if ( ! $this->result = $this->client->send($this->message) OR ! is_object($this->result->val))
 		{
 			$this->error = $this->result->errstr;
 			return FALSE;
 		}
 
 		$this->response = $this->result->decode();
-
 		return TRUE;
 	}
 	// END
@@ -309,7 +295,7 @@
 	//  Returns Error
 	//-------------------------------------
 
-	function display_error()
+	public function display_error()
 	{
 		return $this->error;
 	}
@@ -319,7 +305,7 @@
 	//  Returns Remote Server Response
 	//-------------------------------------
 
-	function display_response()
+	public function display_response()
 	{
 		return $this->response;
 	}
@@ -329,9 +315,9 @@
 	//  Sends an Error Message for Server Request
 	//-------------------------------------
 
-	function send_error_message($number, $message)
+	public function send_error_message($number, $message)
 	{
-		return new XML_RPC_Response('0',$number, $message);
+		return new XML_RPC_Response(0, $number, $message);
 	}
 	// END
 
@@ -340,14 +326,11 @@
 	//  Send Response for Server Request
 	//-------------------------------------
 
-	function send_response($response)
+	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
-
-		$response = $this->values_parsing($response);
-
-		return new XML_RPC_Response($response);
+		return new XML_RPC_Response($this->values_parsing($response));
 	}
 	// END
 
@@ -364,13 +347,13 @@
  */
 class XML_RPC_Client extends CI_Xmlrpc
 {
-	var $path			= '';
-	var $server			= '';
-	var $port			= 80;
-	var $errno			= '';
-	var $errstring		= '';
-	var $timeout		= 5;
-	var $no_multicall	= FALSE;
+	public $path			= '';
+	public $server			= '';
+	public $port			= 80;
+	public $errno			= '';
+	public $errstring		= '';
+	public $timeout		= 5;
+	public $no_multicall	= FALSE;
 
 	public function __construct($path, $server, $port=80)
 	{
@@ -381,7 +364,7 @@
 		$this->path = $path;
 	}
 
-	function send($msg)
+	public function send($msg)
 	{
 		if (is_array($msg))
 		{
@@ -393,7 +376,7 @@
 		return $this->sendPayload($msg);
 	}
 
-	function sendPayload($msg)
+	public function sendPayload($msg)
 	{
 		$fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout);
 
@@ -411,12 +394,12 @@
 		}
 
 		$r = "\r\n";
-		$op  = "POST {$this->path} HTTP/1.0$r";
-		$op .= "Host: {$this->server}$r";
-		$op .= "Content-Type: text/xml$r";
-		$op .= "User-Agent: {$this->xmlrpcName}$r";
-		$op .= "Content-Length: ".strlen($msg->payload). "$r$r";
-		$op .= $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)))
@@ -430,8 +413,8 @@
 		return $resp;
 	}
 
-} // end class XML_RPC_Client
-
+}
+// end class XML_RPC_Client
 
 /**
  * XML-RPC Response class
@@ -442,11 +425,11 @@
  */
 class XML_RPC_Response
 {
-	var $val = 0;
-	var $errno = 0;
-	var $errstr = '';
-	var $headers = array();
-	var $xss_clean = TRUE;
+	public $val = 0;
+	public $errno = 0;
+	public $errstr = '';
+	public $headers = array();
+	public $xss_clean = TRUE;
 
 	public function __construct($val, $code = 0, $fstr = '')
 	{
@@ -454,7 +437,14 @@
 		{
 			// error
 			$this->errno = $code;
-			$this->errstr = htmlentities($fstr);
+			if ( ! is_php('5.4'))
+			{
+				$this->errstr = htmlspecialchars($fstr, ENT_NOQUOTES, 'UTF-8');
+			}
+			else
+			{
+				$this->errstr = htmlspecialchars($fstr, ENT_XML1 | ENT_NOQUOTES, 'UTF-8');
+			}
 		}
 		else if ( ! is_object($val))
 		{
@@ -468,27 +458,26 @@
 		}
 	}
 
-	function faultCode()
+	public function faultCode()
 	{
 		return $this->errno;
 	}
 
-	function faultString()
+	public function faultString()
 	{
 		return $this->errstr;
 	}
 
-	function value()
+	public function value()
 	{
 		return $this->val;
 	}
 
-	function prepare_response()
+	public function prepare_response()
 	{
-		$result = "<methodResponse>\n";
-		if ($this->errno)
-		{
-			$result .= '<fault>
+		return "<methodResponse>\n"
+			. ($this->errno
+			? '<fault>
 	<value>
 		<struct>
 			<member>
@@ -501,23 +490,16 @@
 			</member>
 		</struct>
 	</value>
-</fault>';
-		}
-		else
-		{
-			$result .= "<params>\n<param>\n" .
-					$this->val->serialize_class() .
-					"</param>\n</params>";
-		}
-		$result .= "\n</methodResponse>";
-		return $result;
+</fault>'
+			: "<params>\n<param>\n".$this->val->serialize_class()."</param>\n</params>")
+			. "\n</methodResponse>";
 	}
 
-	function decode($array=FALSE)
+	public function decode($array = FALSE)
 	{
 		$CI =& get_instance();
-		
-		if ($array !== FALSE && is_array($array))
+
+		if (is_array($array))
 		{
 			while (list($key) = each($array))
 			{
@@ -556,7 +538,7 @@
 	//  XML-RPC Object to PHP Types
 	//-------------------------------------
 
-	function xmlrpc_decoder($xmlrpc_val)
+	public function xmlrpc_decoder($xmlrpc_val)
 	{
 		$kind = $xmlrpc_val->kindOf();
 
@@ -567,12 +549,10 @@
 		elseif ($kind == 'array')
 		{
 			reset($xmlrpc_val->me);
-			list($a,$b) = each($xmlrpc_val->me);
-			$size = count($b);
-
+			$b = current($xmlrpc_val->me);
 			$arr = array();
 
-			for ($i = 0; $i < $size; $i++)
+			for ($i = 0, $size = count($b); $i < $size; $i++)
 			{
 				$arr[] = $this->xmlrpc_decoder($xmlrpc_val->me['array'][$i]);
 			}
@@ -596,7 +576,7 @@
 	//  ISO-8601 time to server or UTC time
 	//-------------------------------------
 
-	function iso8601_decode($time, $utc=0)
+	public function iso8601_decode($time, $utc = 0)
 	{
 		// return a timet in the localtime, or UTC
 		$t = 0;
@@ -608,9 +588,8 @@
 		return $t;
 	}
 
-} // End Response Class
-
-
+}
+// End Response Class
 
 /**
  * XML-RPC Message class
@@ -621,10 +600,10 @@
  */
 class XML_RPC_Message extends CI_Xmlrpc
 {
-	var $payload;
-	var $method_name;
-	var $params			= array();
-	var $xh				= array();
+	public $payload;
+	public $method_name;
+	public $params			= array();
+	public $xh				= array();
 
 	public function __construct($method, $pars=0)
 	{
@@ -633,7 +612,7 @@
 		$this->method_name = $method;
 		if (is_array($pars) && count($pars) > 0)
 		{
-			for ($i=0; $i<count($pars); $i++)
+			for ($i = 0, $c = count($pars); $i < $c; $i++)
 			{
 				// $pars[$i] = XML_RPC_Values
 				$this->params[] = $pars[$i];
@@ -645,13 +624,13 @@
 	//  Create Payload to Send
 	//-------------------------------------
 
-	function createPayload()
+	public function createPayload()
 	{
-		$this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n";
-		$this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n";
-		$this->payload .= "<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; $i<count($this->params); $i++)
+		for ($i = 0, $c = count($this->params); $i < $c; $i++)
 		{
 			// $p = XML_RPC_Values
 			$p = $this->params[$i];
@@ -665,7 +644,7 @@
 	//  Parse External XML-RPC Server's Response
 	//-------------------------------------
 
-	function parseResponse($fp)
+	public function parseResponse($fp)
 	{
 		$data = '';
 
@@ -680,16 +659,14 @@
 
 		if ($this->debug === TRUE)
 		{
-			echo "<pre>";
-			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
-			echo "</pre>";
+			echo "<pre>---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n</pre>";
 		}
 
 		//-------------------------------------
 		//  Check for data
 		//-------------------------------------
 
-		if ($data == "")
+		if ($data === '')
 		{
 			error_log($this->xmlrpcstr['no_data']);
 			$r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
@@ -701,7 +678,7 @@
 		//  Check for HTTP 200 Response
 		//-------------------------------------
 
-		if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data))
+		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 . ')');
@@ -714,13 +691,14 @@
 
 		$parser = xml_parser_create($this->xmlrpc_defencoding);
 
-		$this->xh[$parser]					= array();
-		$this->xh[$parser]['isf']			= 0;
-		$this->xh[$parser]['ac']			= '';
-		$this->xh[$parser]['headers']		= array();
-		$this->xh[$parser]['stack']			= array();
-		$this->xh[$parser]['valuestack']	= array();
-		$this->xh[$parser]['isf_reason']	= 0;
+		$this->xh[$parser] = array(
+						'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);
@@ -769,9 +747,7 @@
 		{
 			if ($this->debug === TRUE)
 			{
-				echo "---Invalid Return---\n";
-				echo $this->xh[$parser]['isf_reason'];
-				echo "---Invalid Return---\n\n";
+				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']);
@@ -801,9 +777,7 @@
 				echo "---END HEADERS---\n\n";
 			}
 
-			echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n";
-
-			echo "---PARSED---\n" ;
+			echo "---DATA---\n".htmlspecialchars($data)."\n---END DATA---\n\n---PARSED---\n";
 			var_dump($this->xh[$parser]['value']);
 			echo "\n---END PARSED---</pre>";
 		}
@@ -813,7 +787,6 @@
 		//-------------------------------------
 
 		$v = $this->xh[$parser]['value'];
-
 		if ($this->xh[$parser]['isf'])
 		{
 			$errno_v = $v->me['struct']['faultCode'];
@@ -855,7 +828,7 @@
 	//  Start Element Handler
 	//-------------------------------------
 
-	function open_tag($the_parser, $name, $attrs)
+	public function open_tag($the_parser, $name, $attrs)
 	{
 		// If invalid nesting, then return
 		if ($this->xh[$the_parser]['isf'] > 1) return;
@@ -957,7 +930,7 @@
 	//  End Element Handler
 	//-------------------------------------
 
-	function closing_tag($the_parser, $name)
+	public function closing_tag($the_parser, $name)
 	{
 		if ($this->xh[$the_parser]['isf'] > 1) return;
 
@@ -1101,7 +1074,7 @@
 	//  Parses Character Data
 	//-------------------------------------
 
-	function character_data($the_parser, $data)
+	public function character_data($the_parser, $data)
 	{
 		if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already
 
@@ -1123,13 +1096,16 @@
 	}
 
 
-	function addParam($par) { $this->params[]=$par; }
+	public function addParam($par)
+	{
+		$this->params[] = $par;
+	}
 
-	function output_parameters($array=FALSE)
+	public function output_parameters($array = FALSE)
 	{
 		$CI =& get_instance();
-		
-		if ($array !== FALSE && is_array($array))
+
+		if (is_array($array))
 		{
 			while (list($key) = each($array))
 			{
@@ -1151,7 +1127,7 @@
 		{
 			$parameters = array();
 
-			for ($i = 0; $i < count($this->params); $i++)
+			for ($i = 0, $c = count($this->params); $i < $c; $i++)
 			{
 				$a_param = $this->decode_message($this->params[$i]);
 
@@ -1170,7 +1146,7 @@
 	}
 
 
-	function decode_message($param)
+	public function decode_message($param)
 	{
 		$kind = $param->kindOf();
 
@@ -1181,11 +1157,10 @@
 		elseif ($kind == 'array')
 		{
 			reset($param->me);
-			list($a,$b) = each($param->me);
-
+			$b = current($param->me);
 			$arr = array();
 
-			for($i = 0; $i < count($b); $i++)
+			for($i = 0, $c = count($b); $i < $c; $i++)
 			{
 				$arr[] = $this->decode_message($param->me['array'][$i]);
 			}
@@ -1195,7 +1170,6 @@
 		elseif ($kind == 'struct')
 		{
 			reset($param->me['struct']);
-
 			$arr = array();
 
 			while (list($key,$value) = each($param->me['struct']))
@@ -1207,9 +1181,8 @@
 		}
 	}
 
-} // End XML_RPC_Messages class
-
-
+}
+// End XML_RPC_Messages class
 
 /**
  * XML-RPC Values class
@@ -1220,10 +1193,10 @@
  */
 class XML_RPC_Values extends CI_Xmlrpc
 {
-	var $me		= array();
-	var $mytype	= 0;
+	public $me	= array();
+	public $mytype	= 0;
 
-	public function __construct($val=-1, $type='')
+	public function __construct($val = -1, $type = '')
 	{
 		parent::__construct();
 
@@ -1246,7 +1219,7 @@
 		}
 	}
 
-	function addScalar($val, $type='string')
+	public function addScalar($val, $type = 'string')
 	{
 		$typeof = $this->xmlrpcTypes[$type];
 
@@ -1264,14 +1237,7 @@
 
 		if ($type == $this->xmlrpcBoolean)
 		{
-			if (strcasecmp($val,'true')==0 OR $val==1 OR ($val==true && strcasecmp($val,'false')))
-			{
-				$val = 1;
-			}
-			else
-			{
-				$val=0;
-			}
+			$val = (strcasecmp($val,'true') === 0 OR $val == 1 OR ($val == true && strcasecmp($val, 'false'))) ? 1 : 0;
 		}
 
 		if ($this->mytype == 2)
@@ -1290,7 +1256,7 @@
 		return 1;
 	}
 
-	function addArray($vals)
+	public function addArray($vals)
 	{
 		if ($this->mytype != 0)
 		{
@@ -1303,7 +1269,7 @@
 		return 1;
 	}
 
-	function addStruct($vals)
+	public function addStruct($vals)
 	{
 		if ($this->mytype != 0)
 		{
@@ -1315,7 +1281,7 @@
 		return 1;
 	}
 
-	function kindOf()
+	public function kindOf()
 	{
 		switch($this->mytype)
 		{
@@ -1333,7 +1299,7 @@
 		}
 	}
 
-	function serializedata($typ, $val)
+	public function serializedata($typ, $val)
 	{
 		$rs = '';
 
@@ -1345,20 +1311,18 @@
 				reset($val);
 				while (list($key2, $val2) = each($val))
 				{
-					$rs .= "<member>\n<name>{$key2}</name>\n";
-					$rs .= $this->serializeval($val2);
-					$rs .= "</member>\n";
+					$rs .= "<member>\n<name>{$key2}</name>\n".$this->serializeval($val2)."</member>\n";
 				}
 				$rs .= '</struct>';
 			break;
 			case 2:
 				// array
 				$rs .= "<array>\n<data>\n";
-				for($i=0; $i < count($val); $i++)
+				for($i = 0, $c = count($val); $i < $c; $i++)
 				{
 					$rs .= $this->serializeval($val[$i]);
 				}
-				$rs.="</data>\n</array>\n";
+				$rs .= "</data>\n</array>\n";
 				break;
 			case 1:
 				// others
@@ -1383,26 +1347,24 @@
 		return $rs;
 	}
 
-	function serialize_class()
+	public function serialize_class()
 	{
 		return $this->serializeval($this);
 	}
 
-	function serializeval($o)
+	public function serializeval($o)
 	{
 		$ar = $o->me;
 		reset($ar);
 
 		list($typ, $val) = each($ar);
-		$rs = "<value>\n".$this->serializedata($typ, $val)."</value>\n";
-		return $rs;
+		return "<value>\n".$this->serializedata($typ, $val)."</value>\n";
 	}
 
-	function scalarval()
+	public function scalarval()
 	{
 		reset($this->me);
-		list($a,$b) = each($this->me);
-		return $b;
+		return current($this->me);
 	}
 
 
@@ -1412,24 +1374,13 @@
 
 	// Useful for sending time in XML-RPC
 
-	function iso8601_encode($time, $utc=0)
+	public function iso8601_encode($time, $utc = 0)
 	{
-		if ($utc == 1)
-		{
-			$t = strftime("%Y%m%dT%H:%i:%s", $time);
-		}
-		else
-		{
-			if (function_exists('gmstrftime'))
-				$t = gmstrftime("%Y%m%dT%H:%i:%s", $time);
-			else
-				$t = strftime("%Y%m%dT%H:%i:%s", $time - date('Z'));
-		}
-		return $t;
+		return ($utc) ? strftime('%Y%m%dT%H:%i:%s', $time) : gmstrftime('%Y%m%dT%H:%i:%s', $time);
 	}
 
 }
 // END XML_RPC_Values Class
 
 /* End of file Xmlrpc.php */
-/* Location: ./system/libraries/Xmlrpc.php */
\ No newline at end of file
+/* Location: ./system/libraries/Xmlrpc.php */
diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php
index 587b750..355d43f 100644
--- a/system/libraries/Xmlrpcs.php
+++ b/system/libraries/Xmlrpcs.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -48,12 +48,11 @@
  */
 class CI_Xmlrpcs extends CI_Xmlrpc
 {
-	var $methods		= array();	//array of methods mapped to function names and signatures
-	var $debug_msg		= '';		// Debug Message
-	var $system_methods = array();	// XML RPC Server methods
-	var $controller_obj;
-
-	var $object			= FALSE;
+	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;
 
 	/**
 	 * Constructor
@@ -80,7 +79,7 @@
 	 * @param	mixed
 	 * @return	void
 	 */
-	function initialize($config=array())
+	public function initialize($config = array())
 	{
 		if (isset($config['functions']) && is_array($config['functions']))
 		{
@@ -111,26 +110,26 @@
 	 * @access	public
 	 * @return	void
 	 */
-	function set_system_methods()
+	public function set_system_methods()
 	{
 		$this->methods = array(
 					'system.listMethods'	 => array(
-													'function' => 'this.listMethods',
-													'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),
-													'docstring' => 'Returns an array of available methods on this server'),
-					'system.methodHelp'		 => array(
-													'function' => 'this.methodHelp',
-													'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),
-													'docstring' => 'Returns a documentation string for the specified method'),
+										'function' => 'this.listMethods',
+										'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString), array($this->xmlrpcArray)),
+										'docstring' => 'Returns an array of available methods on this server'),
+					'system.methodHelp'	 => array(
+										'function' => 'this.methodHelp',
+										'signature' => array(array($this->xmlrpcString, $this->xmlrpcString)),
+										'docstring' => 'Returns a documentation string for the specified method'),
 					'system.methodSignature' => array(
-													'function' => 'this.methodSignature',
-													'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),
-													'docstring' => 'Returns an array describing the return type and required parameters of a method'),
-					'system.multicall'		 => array(
-												'function' => 'this.multicall',
-												'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),
-												'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')
-					);
+										'function' => 'this.methodSignature',
+										'signature' => array(array($this->xmlrpcArray, $this->xmlrpcString)),
+										'docstring' => 'Returns an array describing the return type and required parameters of a method'),
+					'system.multicall'	 => array(
+										'function' => 'this.multicall',
+										'signature' => array(array($this->xmlrpcArray, $this->xmlrpcArray)),
+										'docstring' => 'Combine multiple RPC calls in one request. See http://www.xmlrpc.com/discuss/msgReader$1208 for details')
+				);
 	}
 
 	// --------------------------------------------------------------------
@@ -141,12 +140,10 @@
 	 * @access	public
 	 * @return	void
 	 */
-	function serve()
+	public function serve()
 	{
 		$r = $this->parseRequest();
-		$payload  = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n";
-		$payload .= $this->debug_msg;
-		$payload .= $r->prepare_response();
+		$payload = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n".$this->debug_msg.$r->prepare_response();
 
 		header("Content-Type: text/xml");
 		header("Content-Length: ".strlen($payload));
@@ -165,7 +162,7 @@
 	 * @param	string	docstring
 	 * @return	void
 	 */
-	function add_to_map($methodname, $function, $sig, $doc)
+	public function add_to_map($methodname, $function, $sig, $doc)
 	{
 		$this->methods[$methodname] = array(
 			'function'  => $function,
@@ -183,7 +180,7 @@
 	 * @param	string	data
 	 * @return	object	xmlrpc response
 	 */
-	function parseRequest($data='')
+	public function parseRequest($data = '')
 	{
 		global $HTTP_RAW_POST_DATA;
 
@@ -203,13 +200,14 @@
 		$parser = xml_parser_create($this->xmlrpc_defencoding);
 		$parser_object = new XML_RPC_Message("filler");
 
-		$parser_object->xh[$parser]					= array();
-		$parser_object->xh[$parser]['isf']			= 0;
-		$parser_object->xh[$parser]['isf_reason']	= '';
-		$parser_object->xh[$parser]['params']		= array();
-		$parser_object->xh[$parser]['stack']		= array();
-		$parser_object->xh[$parser]['valuestack']	= array();
-		$parser_object->xh[$parser]['method']		= '';
+		$parser_object->xh[$parser] = array(
+							'isf' =>	0,
+							'isf_reason' =>	'',
+							'params' =>	array(),
+							'stack' =>	array(),
+							'valuestack' =>	array(),
+							'method' =>	''
+						);
 
 		xml_set_object($parser, $parser_object);
 		xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true);
@@ -243,7 +241,7 @@
 			$m = new XML_RPC_Message($parser_object->xh[$parser]['method']);
 			$plist='';
 
-			for ($i=0; $i < count($parser_object->xh[$parser]['params']); $i++)
+			for ($i = 0, $c = count($parser_object->xh[$parser]['params']); $i < $c; $i++)
 			{
 				if ($this->debug === TRUE)
 				{
@@ -255,9 +253,7 @@
 
 			if ($this->debug === TRUE)
 			{
-				echo "<pre>";
-				echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n";
-				echo "</pre>";
+				echo "<pre>---PLIST---\n".$plist."\n---PLIST END---\n\n</pre>";
 			}
 
 			$r = $this->_execute($m);
@@ -284,12 +280,12 @@
 	 * @param	object
 	 * @return	mixed
 	 */
-	function _execute($m)
+	protected function _execute($m)
 	{
 		$methName = $m->method_name;
 
 		// Check to see if it is a system call
-		$system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE;
+		$system_call = (strncmp($methName, 'system', 5) === 0);
 
 		if ($this->xss_clean == FALSE)
 		{
@@ -310,22 +306,20 @@
 		//-------------------------------------
 
 		$method_parts = explode(".", $this->methods[$methName]['function']);
-		$objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE;
+		$objectCall = (isset($method_parts[1]) && $method_parts[1] != '');
 
 		if ($system_call === TRUE)
 		{
-			if ( ! is_callable(array($this,$method_parts['1'])))
+			if ( ! is_callable(array($this,$method_parts[1])))
 			{
 				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
 			}
 		}
 		else
 		{
-			if ($objectCall && ! is_callable(array($method_parts['0'],$method_parts['1'])))
-			{
-				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
-			}
-			elseif ( ! $objectCall && ! is_callable($this->methods[$methName]['function']))
+			if (($objectCall AND ! is_callable(array($method_parts[0], $method_parts[1])))
+				OR ( ! $objectCall AND ! is_callable($this->methods[$methName]['function']))
+			)
 			{
 				return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
 			}
@@ -338,13 +332,13 @@
 		if (isset($this->methods[$methName]['signature']))
 		{
 			$sig = $this->methods[$methName]['signature'];
-			for ($i=0; $i<count($sig); $i++)
+			for ($i = 0, $c = count($sig); $i < $c; $i++)
 			{
 				$current_sig = $sig[$i];
 
-				if (count($current_sig) == count($m->params)+1)
+				if (count($current_sig) === count($m->params)+1)
 				{
-					for ($n=0; $n < count($m->params); $n++)
+					for ($n = 0, $mc = count($m->params); $n < $mc; $n++)
 					{
 						$p = $m->params[$n];
 						$pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf();
@@ -370,7 +364,7 @@
 
 		if ($objectCall === TRUE)
 		{
-			if ($method_parts[0] == "this" && $system_call == TRUE)
+			if ($method_parts[0] === 'this' && $system_call === TRUE)
 			{
 				return call_user_func(array($this, $method_parts[1]), $m);
 			}
@@ -379,11 +373,11 @@
 				if ($this->object === FALSE)
 				{
 					$CI =& get_instance();
-					return $CI->$method_parts['1']($m);
+					return $CI->$method_parts[1]($m);
 				}
 				else
 				{
-					return $this->object->$method_parts['1']($m);
+					return $this->object->$method_parts[1]($m);
 					//return call_user_func(array(&$method_parts['0'],$method_parts['1']), $m);
 				}
 			}
@@ -393,7 +387,7 @@
 			return call_user_func($this->methods[$methName]['function'], $m);
 		}
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -403,7 +397,7 @@
 	 * @param	mixed
 	 * @return	object
 	 */
-	function listMethods($m)
+	public function listMethods($m)
 	{
 		$v = new XML_RPC_Values();
 		$output = array();
@@ -421,7 +415,7 @@
 		$v->addArray($output);
 		return new XML_RPC_Response($v);
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -431,7 +425,7 @@
 	 * @param	mixed
 	 * @return	object
 	 */
-	function methodSignature($m)
+	public function methodSignature($m)
 	{
 		$parameters = $m->output_parameters();
 		$method_name = $parameters[0];
@@ -443,15 +437,15 @@
 				$sigs = array();
 				$signature = $this->methods[$method_name]['signature'];
 
-				for ($i=0; $i < count($signature); $i++)
+				for ($i = 0, $c = count($signature); $i < $c; $i++)
 				{
 					$cursig = array();
 					$inSig = $signature[$i];
-					for ($j=0; $j<count($inSig); $j++)
+					for ($j = 0, $jc = count($inSig); $j < $jc; $j++)
 					{
 						$cursig[]= new XML_RPC_Values($inSig[$j], 'string');
 					}
-					$sigs[]= new XML_RPC_Values($cursig, 'array');
+					$sigs[] = new XML_RPC_Values($cursig, 'array');
 				}
 				$r = new XML_RPC_Response(new XML_RPC_Values($sigs, 'array'));
 			}
@@ -476,7 +470,7 @@
 	 * @param	mixed
 	 * @return	object
 	 */
-	function methodHelp($m)
+	public function methodHelp($m)
 	{
 		$parameters = $m->output_parameters();
 		$method_name = $parameters[0];
@@ -492,7 +486,7 @@
 			return new XML_RPC_Response(0, $this->xmlrpcerr['introspect_unknown'], $this->xmlrpcstr['introspect_unknown']);
 		}
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -502,7 +496,7 @@
 	 * @param	mixed
 	 * @return	object
 	 */
-	function multicall($m)
+	public function multicall($m)
 	{
 		// Disabled
 		return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']);
@@ -519,7 +513,7 @@
 			$m = new XML_RPC_Message($value[0]);
 			$plist='';
 
-			for ($i=0; $i < count($value[1]); $i++)
+			for ($i = 0, $c = count($value[1]); $i < $c; $i++)
 			{
 				$m->addParam(new XML_RPC_Values($value[1][$i], 'string'));
 			}
@@ -546,7 +540,7 @@
 	 * @param	mixed
 	 * @return	object
 	 */
-	function multicall_error($err)
+	public function multicall_error($err)
 	{
 		$str  = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString();
 		$code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode();
@@ -566,7 +560,7 @@
 	 * @param	mixed
 	 * @return	object
 	 */
-	function do_multicall($call)
+	public function do_multicall($call)
 	{
 		if ($call->kindOf() != 'struct')
 		{
@@ -597,11 +591,10 @@
 			return $this->multicall_error('notarray');
 		}
 
-		list($a,$b)=each($params->me);
-		$numParams = count($b);
+		list($a,$b) = each($params->me);
 
 		$msg = new XML_RPC_Message($scalar_value);
-		for ($i = 0; $i < $numParams; $i++)
+		for ($i = 0, $numParams = count($b); $i < $numParams; $i++)
 		{
 			$msg->params[] = $params->me['array'][$i];
 		}
@@ -619,6 +612,5 @@
 }
 // END XML_RPC_Server class
 
-
 /* End of file Xmlrpcs.php */
-/* Location: ./system/libraries/Xmlrpcs.php */
\ No newline at end of file
+/* Location: ./system/libraries/Xmlrpcs.php */
diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php
index 52f1bc3..50e8492 100644
--- a/system/libraries/Zip.php
+++ b/system/libraries/Zip.php
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
diff --git a/system/libraries/javascript/Jquery.php b/system/libraries/javascript/Jquery.php
index 4b8f76a..03574c6 100644
--- a/system/libraries/javascript/Jquery.php
+++ b/system/libraries/javascript/Jquery.php
@@ -1,13 +1,13 @@
-<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
+<?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:
@@ -18,7 +18,7 @@
  *
  * @package		CodeIgniter
  * @author		EllisLab Dev Team
- * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+ * @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
@@ -36,80 +36,77 @@
  * @author		EllisLab Dev Team
  * @link		http://codeigniter.com/user_guide/libraries/javascript.html
  */
- 
+
 class CI_Jquery extends CI_Javascript {
 
-	var $_javascript_folder = 'js';
-	var $jquery_code_for_load = array();
-	var $jquery_code_for_compile = array();
-	var $jquery_corner_active = FALSE;
-	var $jquery_table_sorter_active = FALSE;
-	var $jquery_table_sorter_pager_active = FALSE;
-	var $jquery_ajax_img = '';
+	protected $_javascript_folder = 'js';
+	public $jquery_code_for_load = array();
+	public $jquery_code_for_compile = array();
+	public $jquery_corner_active = FALSE;
+	public $jquery_table_sorter_active = FALSE;
+	public $jquery_table_sorter_pager_active = FALSE;
+	public $jquery_ajax_img = '';
 
 	public function __construct($params)
 	{
-		$this->CI =& get_instance();	
+		$this->CI =& get_instance();
 		extract($params);
 
 		if ($autoload === TRUE)
 		{
-			$this->script();			
+			$this->script();
 		}
-		
+
 		log_message('debug', "Jquery Class Initialized");
 	}
-	
-	// --------------------------------------------------------------------	 
+
+	// --------------------------------------------------------------------
 	// Event Code
-	// --------------------------------------------------------------------	
+	// --------------------------------------------------------------------
 
 	/**
 	 * Blur
 	 *
 	 * Outputs a jQuery blur event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _blur($element = 'this', $js = '')
+	protected function _blur($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'blur');
 	}
-	
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Change
 	 *
 	 * Outputs a jQuery change event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _change($element = 'this', $js = '')
+	protected function _change($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'change');
 	}
-	
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Click
 	 *
 	 * Outputs a jQuery click event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @param	boolean	whether or not to return false
 	 * @return	string
 	 */
-	function _click($element = 'this', $js = '', $ret_false = TRUE)
+	protected function _click($element = 'this', $js = '', $ret_false = TRUE)
 	{
 		if ( ! is_array($js))
 		{
@@ -125,70 +122,66 @@
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Double Click
 	 *
 	 * Outputs a jQuery dblclick event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _dblclick($element = 'this', $js = '')
+	protected function _dblclick($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'dblclick');
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Error
 	 *
 	 * Outputs a jQuery error event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _error($element = 'this', $js = '')
+	protected function _error($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'error');
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Focus
 	 *
 	 * Outputs a jQuery focus event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _focus($element = 'this', $js = '')
+	protected function _focus($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'focus');
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Hover
 	 *
 	 * Outputs a jQuery hover event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @param	string	- Javascript code for mouse over
 	 * @param	string	- Javascript code for mouse out
 	 * @return	string
 	 */
-	function _hover($element = 'this', $over, $out)
+	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";
 
@@ -198,103 +191,97 @@
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Keydown
 	 *
 	 * Outputs a jQuery keydown event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _keydown($element = 'this', $js = '')
+	protected function _keydown($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'keydown');
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Keyup
 	 *
 	 * Outputs a jQuery keydown event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _keyup($element = 'this', $js = '')
+	protected function _keyup($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'keyup');
-	}	
+	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Load
 	 *
 	 * Outputs a jQuery load event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _load($element = 'this', $js = '')
+	protected function _load($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'load');
-	}	
-	
+	}
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Mousedown
 	 *
 	 * Outputs a jQuery mousedown event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _mousedown($element = 'this', $js = '')
+	protected function _mousedown($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'mousedown');
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Mouse Out
 	 *
 	 * Outputs a jQuery mouseout event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _mouseout($element = 'this', $js = '')
+	protected function _mouseout($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'mouseout');
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Mouse Over
 	 *
 	 * Outputs a jQuery mouseover event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _mouseover($element = 'this', $js = '')
+	protected function _mouseover($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'mouseover');
 	}
@@ -306,12 +293,11 @@
 	 *
 	 * Outputs a jQuery mouseup event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _mouseup($element = 'this', $js = '')
+	protected function _mouseup($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'mouseup');
 	}
@@ -323,18 +309,17 @@
 	 *
 	 * Outputs script directly
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _output($array_js = '')
+	protected function _output($array_js = '')
 	{
 		if ( ! is_array($array_js))
 		{
 			$array_js = array($array_js);
 		}
-		
+
 		foreach ($array_js as $js)
 		{
 			$this->jquery_code_for_compile[] = "\t$js\n";
@@ -348,12 +333,11 @@
 	 *
 	 * Outputs a jQuery resize event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _resize($element = 'this', $js = '')
+	protected function _resize($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'resize');
 	}
@@ -365,16 +349,15 @@
 	 *
 	 * Outputs a jQuery scroll event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _scroll($element = 'this', $js = '')
+	protected function _scroll($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'scroll');
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -382,34 +365,31 @@
 	 *
 	 * Outputs a jQuery unload event
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @return	string
 	 */
-	function _unload($element = 'this', $js = '')
+	protected function _unload($element = 'this', $js = '')
 	{
 		return $this->_add_event($element, $js, 'unload');
 	}
 
-	// --------------------------------------------------------------------	 
+	// --------------------------------------------------------------------
 	// Effects
-	// --------------------------------------------------------------------	
-	
+	// --------------------------------------------------------------------
+
 	/**
 	 * Add Class
 	 *
 	 * Outputs a jQuery addClass event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @return	string
 	 */
-	function _addClass($element = 'this', $class='')
+	protected function _addClass($element = 'this', $class='')
 	{
 		$element = $this->_prep_element($element);
-		$str  = "$({$element}).addClass(\"$class\");";
-		return $str;
+		return "$({$element}).addClass(\"$class\");";
 	}
 
 	// --------------------------------------------------------------------
@@ -419,19 +399,18 @@
 	 *
 	 * Outputs a jQuery animate event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function _animate($element = 'this', $params = array(), $speed = '', $extra = '')
+	protected function _animate($element = 'this', $params = array(), $speed = '', $extra = '')
 	{
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
-		
+
 		$animations = "\t\t\t";
-		
+
 		foreach ($params as $param=>$value)
 		{
 			$animations .= $param.': \''.$value.'\', ';
@@ -443,71 +422,63 @@
 		{
 			$speed = ', '.$speed;
 		}
-		
+
 		if ($extra != '')
 		{
 			$extra = ', '.$extra;
 		}
-		
-		$str  = "$({$element}).animate({\n$animations\n\t\t}".$speed.$extra.");";
-		
-		return $str;
+
+		return "$({$element}).animate({\n$animations\n\t\t}".$speed.$extra.");";
 	}
 
 	// --------------------------------------------------------------------
-		
+
 	/**
 	 * Fade In
 	 *
 	 * Outputs a jQuery hide event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function _fadeIn($element = 'this', $speed = '', $callback = '')
+	protected function _fadeIn($element = 'this', $speed = '', $callback = '')
 	{
-		$element = $this->_prep_element($element);	
+		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
-		
+
 		if ($callback != '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
-		
-		$str  = "$({$element}).fadeIn({$speed}{$callback});";
-		
-		return $str;
+
+		return "$({$element}).fadeIn({$speed}{$callback});";
 	}
-		
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Fade Out
 	 *
 	 * Outputs a jQuery hide event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function _fadeOut($element = 'this', $speed = '', $callback = '')
+	protected function _fadeOut($element = 'this', $speed = '', $callback = '')
 	{
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
-		
+
 		if ($callback != '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
-		
-		$str  = "$({$element}).fadeOut({$speed}{$callback});";
-		
-		return $str;
+
+		return "$({$element}).fadeOut({$speed}{$callback});";
 	}
 
 	// --------------------------------------------------------------------
@@ -517,27 +488,24 @@
 	 *
 	 * Outputs a jQuery hide action
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function _hide($element = 'this', $speed = '', $callback = '')
+	protected function _hide($element = 'this', $speed = '', $callback = '')
 	{
-		$element = $this->_prep_element($element);	
+		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
-		
+
 		if ($callback != '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
-		
-		$str  = "$({$element}).hide({$speed}{$callback});";
 
-		return $str;
+		return "$({$element}).hide({$speed}{$callback});";
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -545,163 +513,145 @@
 	 *
 	 * Outputs a jQuery remove class event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @return	string
 	 */
-	function _removeClass($element = 'this', $class='')
+	protected function _removeClass($element = 'this', $class='')
 	{
 		$element = $this->_prep_element($element);
-		$str  = "$({$element}).removeClass(\"$class\");";
-		return $str;
+		return "$({$element}).removeClass(\"$class\");";
 	}
 
 	// --------------------------------------------------------------------
-			
+
 	/**
 	 * Slide Up
 	 *
 	 * Outputs a jQuery slideUp event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function _slideUp($element = 'this', $speed = '', $callback = '')
+	protected function _slideUp($element = 'this', $speed = '', $callback = '')
 	{
-		$element = $this->_prep_element($element);	
+		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
-		
+
 		if ($callback != '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
-		
-		$str  = "$({$element}).slideUp({$speed}{$callback});";
-		
-		return $str;
+
+		return "$({$element}).slideUp({$speed}{$callback});";
 	}
-		
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Slide Down
 	 *
 	 * Outputs a jQuery slideDown event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function _slideDown($element = 'this', $speed = '', $callback = '')
+	protected function _slideDown($element = 'this', $speed = '', $callback = '')
 	{
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
-		
+
 		if ($callback != '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
-		
-		$str  = "$({$element}).slideDown({$speed}{$callback});";
-		
-		return $str;
+
+		return "$({$element}).slideDown({$speed}{$callback});";
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Slide Toggle
 	 *
 	 * Outputs a jQuery slideToggle event
 	 *
-	 * @access	public
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function _slideToggle($element = 'this', $speed = '', $callback = '')
+	protected function _slideToggle($element = 'this', $speed = '', $callback = '')
 	{
 		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
-		
+
 		if ($callback != '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
-		
-		$str  = "$({$element}).slideToggle({$speed}{$callback});";
-		
-		return $str;
+
+		return "$({$element}).slideToggle({$speed}{$callback});";
 	}
-		
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Toggle
 	 *
 	 * Outputs a jQuery toggle event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @return	string
 	 */
-	function _toggle($element = 'this')
+	protected function _toggle($element = 'this')
 	{
 		$element = $this->_prep_element($element);
-		$str  = "$({$element}).toggle();";
-		return $str;
+		return "$({$element}).toggle();";
 	}
-	
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Toggle Class
 	 *
 	 * Outputs a jQuery toggle class event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @return	string
 	 */
-	function _toggleClass($element = 'this', $class='')
+	protected function _toggleClass($element = 'this', $class='')
 	{
 		$element = $this->_prep_element($element);
-		$str  = "$({$element}).toggleClass(\"$class\");";
-		return $str;
+		return "$({$element}).toggleClass(\"$class\");";
 	}
-	
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Show
 	 *
 	 * Outputs a jQuery show event
 	 *
-	 * @access	private
 	 * @param	string	- element
 	 * @param	string	- One of 'slow', 'normal', 'fast', or time in milliseconds
 	 * @param	string	- Javascript callback function
 	 * @return	string
 	 */
-	function _show($element = 'this', $speed = '', $callback = '')
+	protected function _show($element = 'this', $speed = '', $callback = '')
 	{
-		$element = $this->_prep_element($element);	
+		$element = $this->_prep_element($element);
 		$speed = $this->_validate_speed($speed);
-		
+
 		if ($callback != '')
 		{
 			$callback = ", function(){\n{$callback}\n}";
 		}
-		
-		$str  = "$({$element}).show({$speed}{$callback});";
-		
-		return $str;
+
+		return "$({$element}).show({$speed}{$callback});";
 	}
 
 	// --------------------------------------------------------------------
@@ -709,22 +659,20 @@
 	/**
 	 * Updater
 	 *
-	 * An Ajax call that populates the designated DOM node with 
+	 * An Ajax call that populates the designated DOM node with
 	 * returned content
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	the controller to run the call against
 	 * @param	string	optional parameters
 	 * @return	string
 	 */
-	
-	function _updater($container = 'this', $controller, $options = '')
-	{	
+
+	protected function _updater($container = 'this', $controller, $options = '')
+	{
 		$container = $this->_prep_element($container);
-		
 		$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') == '')
 		{
@@ -732,41 +680,38 @@
 		}
 		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
-		$updater .= "\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 != '')
 		{
-			$request_options .= ", {";
-			$request_options .= (is_array($options)) ? "'".implode("', '", $options)."'" : "'".str_replace(":", "':'", $options)."'";
-			$request_options .= "}";
+			$request_options .= ', {'
+					. (is_array($options) ? "'".implode("', '", $options)."'" : "'".str_replace(":", "':'", $options)."'")
+					. '}';
 		}
 
-		$updater .= "\t\t$($container).load('$controller'$request_options);";
-		return $updater;
+		return $updater."\t\t$($container).load('$controller'$request_options);";
 	}
 
 
 	// --------------------------------------------------------------------
 	// Pre-written handy stuff
 	// --------------------------------------------------------------------
-	 
+
 	/**
 	 * Zebra tables
 	 *
-	 * @access	private
 	 * @param	string	table name
 	 * @param	string	plugin location
 	 * @return	string
 	 */
-	function _zebraTables($class = '', $odd = 'odd', $hover = '')
+	protected function _zebraTables($class = '', $odd = 'odd', $hover = '')
 	{
 		$class = ($class != '') ? '.'.$class : '';
-		
 		$zebra  = "\t\$(\"table{$class} tbody tr:nth-child(even)\").addClass(\"{$odd}\");";
 
 		$this->jquery_code_for_compile[] = $zebra;
@@ -779,22 +724,19 @@
 		return $zebra;
 	}
 
-
-
 	// --------------------------------------------------------------------
 	// Plugins
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Corner Plugin
 	 *
 	 * http://www.malsup.com/jquery/corner/
 	 *
-	 * @access	public
 	 * @param	string	target
 	 * @return	string
 	 */
-	function corner($element = '', $corner_style = '')
+	public function corner($element = '', $corner_style = '')
 	{
 		// may want to make this configurable down the road
 		$corner_location = '/plugins/jquery.corner.js';
@@ -806,7 +748,7 @@
 
 		return "$(" . $this->_prep_element($element) . ").corner(".$corner_style.");";
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -814,11 +756,10 @@
 	 *
 	 * Load a thickbox modal window
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function modal($src, $relative = FALSE)
-	{	
+	public function modal($src, $relative = FALSE)
+	{
 		$this->jquery_code_for_load[] = $this->external($src, $relative);
 	}
 
@@ -829,10 +770,9 @@
 	 *
 	 * Load an Effect library
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function effect($src, $relative = FALSE)
+	public function effect($src, $relative = FALSE)
 	{
 		$this->jquery_code_for_load[] = $this->external($src, $relative);
 	}
@@ -844,10 +784,9 @@
 	 *
 	 * Load a plugin library
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function plugin($src, $relative = FALSE)
+	public function plugin($src, $relative = FALSE)
 	{
 		$this->jquery_code_for_load[] = $this->external($src, $relative);
 	}
@@ -859,10 +798,9 @@
 	 *
 	 * Load a user interface library
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function ui($src, $relative = FALSE)
+	public function ui($src, $relative = FALSE)
 	{
 		$this->jquery_code_for_load[] = $this->external($src, $relative);
 	}
@@ -873,10 +811,9 @@
 	 *
 	 * Creates a jQuery sortable
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function sortable($element, $options = array())
+	public function sortable($element, $options = array())
 	{
 
 		if (count($options) > 0)
@@ -901,16 +838,15 @@
 	/**
 	 * Table Sorter Plugin
 	 *
-	 * @access	public
 	 * @param	string	table name
 	 * @param	string	plugin location
 	 * @return	string
 	 */
-	function tablesorter($table = '', $options = '')
+	public function tablesorter($table = '', $options = '')
 	{
 		$this->jquery_code_for_compile[] = "\t$(" . $this->_prep_element($table) . ").tablesorter($options);\n";
 	}
-	
+
 	// --------------------------------------------------------------------
 	// Class functions
 	// --------------------------------------------------------------------
@@ -920,13 +856,12 @@
 	 *
 	 * Constructs the syntax for an event, and adds to into the array for compilation
 	 *
-	 * @access	private
 	 * @param	string	The element to attach the event to
 	 * @param	string	The code to execute
 	 * @param	string	The event to pass
 	 * @return	string
-	 */	
-	function _add_event($element, $js, $event)
+	 */
+	protected function _add_event($element, $js, $event)
 	{
 		if (is_array($js))
 		{
@@ -947,65 +882,61 @@
 	 * As events are specified, they are stored in an array
 	 * This funciton compiles them all for output on a page
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _compile($view_var = 'script_foot', $script_tags = TRUE)
+	protected function _compile($view_var = 'script_foot', $script_tags = TRUE)
 	{
 		// External references
 		$external_scripts = implode('', $this->jquery_code_for_load);
 		$this->CI->load->vars(array('library_src' => $external_scripts));
 
-		if (count($this->jquery_code_for_compile) == 0 )
+		if (count($this->jquery_code_for_compile) === 0)
 		{
 			// no inline references, let's just return
 			return;
 		}
 
 		// Inline references
-		$script = '$(document).ready(function() {' . "\n";
-		$script .= implode('', $this->jquery_code_for_compile);
-		$script .= '});';
-		
+		$script = '$(document).ready(function() {'."\n"
+			. implode('', $this->jquery_code_for_compile)
+			. '});';
+
 		$output = ($script_tags === FALSE) ? $script : $this->inline($script);
 
 		$this->CI->load->vars(array($view_var => $output));
 
 	}
-	
+
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Clear Compile
 	 *
 	 * Clears the array of script events collected for output
 	 *
-	 * @access	public
 	 * @return	void
 	 */
-	function _clear_compile()
+	protected function _clear_compile()
 	{
 		$this->jquery_code_for_compile = array();
 	}
 
 	// --------------------------------------------------------------------
-	
+
 	/**
 	 * Document Ready
 	 *
 	 * A wrapper for writing document.ready()
 	 *
-	 * @access	private
 	 * @return	string
 	 */
-	function _document_ready($js)
+	protected function _document_ready($js)
 	{
 		if ( ! is_array($js))
 		{
-			$js = array ($js);
-
+			$js = array($js);
 		}
-		
+
 		foreach ($js as $script)
 		{
 			$this->jquery_code_for_compile[] = $script;
@@ -1019,17 +950,16 @@
 	 *
 	 * Outputs the script tag that loads the jquery.js file into an HTML document
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function script($library_src = '', $relative = FALSE)
+	public function script($library_src = '', $relative = FALSE)
 	{
 		$library_src = $this->external($library_src, $relative);
 		$this->jquery_code_for_load[] = $library_src;
 		return $library_src;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1039,20 +969,19 @@
 	 * unless the supplied element is the Javascript 'this'
 	 * object, in which case no quotes are added
 	 *
-	 * @access	public
 	 * @param	string
 	 * @return	string
 	 */
-	function _prep_element($element)
+	protected function _prep_element($element)
 	{
 		if ($element != 'this')
 		{
 			$element = '"'.$element.'"';
 		}
-		
+
 		return $element;
 	}
-	
+
 	// --------------------------------------------------------------------
 
 	/**
@@ -1060,25 +989,24 @@
 	 *
 	 * Ensures the speed parameter is valid for jQuery
 	 *
-	 * @access	private
 	 * @param	string
 	 * @return	string
-	 */	
-	function _validate_speed($speed)
+	 */
+	protected function _validate_speed($speed)
 	{
 		if (in_array($speed, array('slow', 'normal', 'fast')))
 		{
-			$speed = '"'.$speed.'"';
+			return '"'.$speed.'"';
 		}
 		elseif (preg_match("/[^0-9]/", $speed))
 		{
-			$speed = '';
+			return '';
 		}
-	
+
 		return $speed;
 	}
 
 }
 
 /* End of file Jquery.php */
-/* Location: ./system/libraries/Jquery.php */
\ No newline at end of file
+/* Location: ./system/libraries/Jquery.php */
diff --git a/user_guide_src/cilexer/cilexer/cilexer.py b/user_guide_src/cilexer/cilexer/cilexer.py
index e571ce6..713268e 100644
--- a/user_guide_src/cilexer/cilexer/cilexer.py
+++ b/user_guide_src/cilexer/cilexer/cilexer.py
@@ -15,7 +15,7 @@
 # through the world wide web, please send an email to
 # licensing@ellislab.com so we can send you a copy immediately.
 # 
-# Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+# Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
 # http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 
 
diff --git a/user_guide_src/source/_themes/eldocs/static/asset/css/common.css b/user_guide_src/source/_themes/eldocs/static/asset/css/common.css
index 45b1fe7..b9e28ae 100644
--- a/user_guide_src/source/_themes/eldocs/static/asset/css/common.css
+++ b/user_guide_src/source/_themes/eldocs/static/asset/css/common.css
@@ -16,7 +16,7 @@
 through the world wide web, please send an email to
 licensing@ellislab.com so we can send you a copy immediately.
 
-Copyright (c) 2008 - 2011, EllisLab, Inc. (http://ellislab.com/)
+Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
 http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 */
 
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 54237e3..e960761 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -24,16 +24,24 @@
    -  Added Windows 7 to the list of user platforms.
    -  Ability to log certain error types, not all under a threshold.
    -  Added support for pem, p10, p12, p7a, p7c, p7m, p7r, p7s, crt, crl, der, kdb, rsa, cer, sst, csr Certs to mimes.php.
-   -  Added support pgp and gpg to mimes.php.
-   -  Added support 3gp, 3g2, mp4, wmv, f4v, vlc Video files to mimes.php.
-   -  Added support m4a, aac, m4u, xspf, au, ac3, flac, ogg Audio files to mimes.php.
+   -  Added support for pgp and gpg to mimes.php.
+   -  Added support for 3gp, 3g2, mp4, wmv, f4v, vlc Video files to mimes.php.
+   -  Added support for m4a, aac, m4u, xspf, au, ac3, flac, ogg Audio files to mimes.php.
+   -  Added support for kmz and kml (Google Earth) files to mimes.php.
+   -  Updated support for doc files in mimes.php.
+   -  Added application/xml for xml and application/xml, text/xsl for xsl in mimes.php.
    -  Changed logger to only chmod when file is first created.
+   -  Removed previously deprecated SHA1 Library.
+   -  Removed previously deprecated use of ``$autoload['core']`` in application/config/autoload.php.
+      Only entries in ``$autoload['libraries']`` are auto-loaded now.
 
 -  Helpers
 
    -  url_title() will now trim extra dashes from beginning and end.
    -  Added XHTML Basic 1.1 doctype to :doc:`HTML Helper <helpers/html_helper>`.
    -  Changed humanize to include a second param for the separator.
+   -  Refactored ``plural()`` and ``singular()`` to avoid double pluralization and support more words.
+   -  Added an optional third parameter to ``force_download()`` that enables/disables sending the actual file MIME type in the Content-Type header (disabled by default).
 
 -  Database
 
@@ -42,31 +50,54 @@
       get_compiled_insert(), get_compiled_update(), get_compiled_delete().
    -  Taking care of LIKE condition when used with MySQL UPDATE statement.
    -  Adding $escape parameter to the order_by function, this enables ordering by custom fields.
+   -  MySQLi driver now uses mysqli_get_server_info() for server version checking.
+   -  MySQLi driver now supports persistent connections when running on PHP >= 5.3.
+   -  Added dsn if the group connections in the config use PDO or any driver which need DSN.
+   -  Improved PDO database support.
+   -  Added Interbase/Firebird database support via the "interbase" driver
+   -  Added an optional database name parameter to db_select().
+   -  Replaced the _error_message() and _error_number() methods with error(), that returns an array containing the last database error code and message.
+   -  Improved version() implementation so that drivers that have a native function to get the version number don't have to be defined in the core DB_driver class.
+   -  Improved support of the PostgreSQL driver, including:
+	 -  pg_version() is now used to get the database version number, when possible.
+	 -  Added db_set_charset() support.
+	 -  Added _optimize_table() support for the :doc:`Database Utility Class <database/utilities>` (rebuilds table indexes).
 
 -  Libraries
 
    -  Added max_filename_increment config setting for Upload library.
    -  CI_Loader::_ci_autoloader() is now a protected method.
    -  Modified valid_ip() to use PHP's filter_var() when possible (>= PHP 5.2) in the :doc:`Form Validation library <libraries/form_validation>`.
-	 -  Added custom filename to Email::attach() as $this->email->attach($filename, $disposition, $newname)
+   -  Added custom filename to Email::attach() as $this->email->attach($filename, $disposition, $newname)
    -  Cart library changes include:
 	 -  It now auto-increments quantity's instead of just resetting it, this is the default behaviour of large e-commerce sites.
 	 -  Product Name strictness can be disabled via the Cart Library by switching "$product_name_safe"
 	 -  Added function remove() to remove a cart item, updating with quantity of 0 seemed like a hack but has remained to retain compatability
+   -  Image manipulation library changes include:
+	 -  The initialize() method now only sets existing class properties.
+	 -  Added support for 3-length hex color values for wm_font_color and wm_shadow_color properties, as well as validation for them.
+	 -  Class properties wm_font_color, wm_shadow_color and wm_use_drop_shadow are now protected, to avoid breaking the text_watermark() method
+	    if they are set manually after initialization.
+	 -  If property maintain_ratio is set to TRUE, image_reproportion() now doesn't need both width and height to be specified.
    -  Minor speed optimizations and method & property visibility declarations in the Calendar Library.
+   -  Removed SHA1 function in the :doc:`Encryption Library <libraries/encryption>`.
+   -  Added $config['csrf_regeneration'] to the CSRF protection in the :doc:`Security library <libraries/security>`, which makes token regeneration optional.
+   -  Added function error_array() to return all error messages as an array in the Form_validation class.
+   -  Added function set_data() to Form_validation library, which can be used in place of the default $_POST array.
+   -  Changed the Session library to select only one row when using database sessions.
 
 -  Core
 
-   -  Changed private functions in CI_URI to protected so MY_URI can
-      override them.
+   -  Changed private functions in CI_URI to protected so MY_URI can override them.
    -  Removed CI_CORE boolean constant from CodeIgniter.php (no longer Reactor and Core versions).
+   -  Added method get_vars() to CI_Loader to retrieve all variables loaded with $this->load->vars().
+   -  is_loaded() function from system/core/Commons.php now returns a reference.
 
 Bug fixes for 3.0
 ------------------
 
 -  Unlink raised an error if cache file did not exist when you try to delete it.
--  Fixed a bug (#181) where a mis-spelling was in the form validation
-   language file.
+-  Fixed a bug (#181) where a mis-spelling was in the form validation language file.
 -  Fixed a bug (#159, #163) that mishandled Active Record nested transactions because _trans_depth was not getting incremented.
 -  Fixed a bug (#737, #75) where pagination anchor class was not set properly when using initialize method.
 -  Fixed a bug (#419) - auto_link() now recognizes URLs that come after a word boundary.
@@ -80,11 +111,59 @@
 -  Fixed a bug in CI_Cart::contents() where if called without a TRUE (or equal) parameter, it would fail due to a typo.
 -  Fixed a bug (#696) - make oci_execute calls inside num_rows non-committing, since they are only there to reset which row is next in line for oci_fetch calls and thus don't need to be committed.
 -  Fixed a bug (#406) - sqlsrv DB driver not reuturning resource on <samp>db_pconnect()</samp>.
+-  Fixed a bug in CI_Image_lib::gd_loaded() where it was possible for the script execution to end or a PHP E_WARNING message to be emitted.
+-  In Pagination library, when use_page_numbers=TRUE previous link and page 1 link do not have the same url
+-  Fixed a bug (#561) - Errors in :doc:`XML-RPC Library <libraries/xmlrpc>` were not properly escaped.
+-  Fixed a bug (#904) - ``CI_Loader::initialize()`` caused a PHP Fatal error to be triggered if error level E_STRICT is used.
+-  Fixed a hosting edge case where an empty $_SERVER['HTTPS'] variable would evaluate to 'on'
+-  Fixed a bug (#154) - ``CI_Session::sess_update()`` caused the session to be destroyed on pages where multiple AJAX requests were executed at once.
+-  Fixed a possible bug in ``CI_Input::is_ajax_request()`` where some clients might not send the X-Requested-With HTTP header value exactly as 'XmlHttpRequest'.
+-  Fixed a bug (#1039) - MySQL's _backup() method failed due to a table name not being escaped.
+-  Fixed a bug (#1070) - CI_DB_driver::initialize() didn't set a character set if a database is not selected.
+-  Fixed a bug (#177) - CI_Form_validation::set_value() didn't set the default value if POST data is NULL.
+-  Fixed a bug (#68, #414) - Oracle's escape_str() didn't properly escape LIKE wild characters.
+-  Fixed a bug (#81) - ODBC's list_fields() and field_data() methods skipped the first column due to odbc_field_*() functions' index starting at 1 instead of 0.
+-  Fixed a bug (#129) - ODBC's num_rows() returned -1 in some cases, due to not all subdrivers supporting the odbc_num_rows() function.
+-  Fixed a bug (#153) - E_NOTICE being generated by getimagesize() in the :doc:`File Uploading Library <libraries/file_uploading>`.
+-  Fixed a bug (#611) - SQLSRV's error handling methods used to issue warnings when there's no actual error.
+-  Fixed a bug (#1036) - is_write_type() method in the :doc:`Database Library <database/index>` didn't return TRUE for RENAME and OPTIMIZE queries.
+-  Fixed a bug in PDO's _version() method where it used to return the client version as opposed to the server one.
+-  Fixed a bug in PDO's insert_id() method where it could've failed if it's used with Postgre versions prior to 8.1.
+-  Fixed a bug in CUBRID's affected_rows() method where a connection resource was passed to cubrid_affected_rows() instead of a result.
+-  Fixed a bug (#638) - db_set_charset() ignored its arguments and always used the configured charset and collation instead.
+-  Fixed a bug (#413) - Oracle's error handling methods used to only return connection-related errors.
+-  Fixed a bug (#804) - Profiler library was trying to handle objects as strings in some cases, resulting in warnings being issued by htmlspecialchars().
+-  Fixed a bug (#1101) - MySQL/MySQLi result method field_data() was implemented as if it was handling a DESCRIBE result instead of the actual result set.
+-  Fixed a bug in Oracle's :doc:`Database Forge Class <database/forge>` method _create_table() where it failed with AUTO_INCREMENT as it's not supported.
+-  Fixed a bug (#1080) - When using the SMTP protocol, the :doc:`Email Library <libraries/email>` send() method was returning TRUE even if the connection/authentication against the server failed.
+
+Version 2.1.1
+=============
+
+Release Date: Not Released
+
+-  General Changes
+   -  Fixed support for docx, xlsx files in mimes.php.
+
+-  Libraries
+   -  Further improved MIME type detection in the :doc:`File Uploading Library <libraries/file_uploading>`.
+
+-  Helpers
+   -  url_title() performance and output improved. You can now use any string as the word delimiter, but 'dash' and 'underscore' are still supported.
+
+Bug fixes for 2.1.1
+-------------------
+
+-  Fixed a bug (#697) - A wrong array key was used in the Upload library to check for mime-types.
+-  Fixed a bug - form_open() compared $action against site_url() instead of base_url().
+-  Fixed a bug - CI_Upload::_file_mime_type() could've failed if mime_content_type() is used for the detection and returns FALSE.
+-  Fixed a bug (#538) - Windows paths were ignored when using the :doc:`Image Manipulation Library <libraries/image_lib>` to create a new file.
+-  Fixed a bug - When database caching was enabled, $this->db->query() checked the cache before binding variables which resulted in cached queries never being found
 
 Version 2.1.0
 =============
 
-Release Date: Not Released
+Release Date: November 14, 2011
 
 -  General Changes
 
diff --git a/user_guide_src/source/conf.py b/user_guide_src/source/conf.py
index bb10d06..593ceaf 100644
--- a/user_guide_src/source/conf.py
+++ b/user_guide_src/source/conf.py
@@ -41,7 +41,7 @@
 
 # General information about the project.
 project = u'CodeIgniter'
-copyright = u'2011, EllisLab, Inc.'
+copyright = u'2012, EllisLab, Inc.'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -223,7 +223,7 @@
 epub_title = u'CodeIgniter'
 epub_author = u'EllisLab, Inc.'
 epub_publisher = u'EllisLab, Inc.'
-epub_copyright = u'2011, EllisLab, Inc.'
+epub_copyright = u'2012, EllisLab, Inc.'
 
 # The language of the text. It defaults to the language option
 # or en if the language is not set.
diff --git a/user_guide_src/source/database/active_record.rst b/user_guide_src/source/database/active_record.rst
index 228d1d5..c04e67d 100644
--- a/user_guide_src/source/database/active_record.rst
+++ b/user_guide_src/source/database/active_record.rst
@@ -45,7 +45,7 @@
 $query, which can be used to show the results::
 
 	$query = $this->db->get('mytable');
-	
+
 	foreach ($query->result() as $row)
 	{
 		echo $row->title;
@@ -57,32 +57,32 @@
 $this->db->get_compiled_select()
 ================================
 
-Compiles the selection query just like `$this->db->get()`_ but does not *run* 
+Compiles the selection query just like `$this->db->get()`_ but does not *run*
 the query. This method simply returns the SQL query as a string.
 
 Example::
 
 	$sql = $this->db->get_compiled_select('mytable');
 	echo $sql;
-	
+
 	// Produces string: SELECT * FROM mytable
-	
-The second parameter enables you to set whether or not the active record query 
+
+The second parameter enables you to set whether or not the active record query
 will be reset (by default it will be&mdash;just like `$this->db->get()`)::
 
 	echo $this->db->limit(10,20)->get_compiled_select('mytable', FALSE);
-	// Produces string: SELECT * FROM mytable LIMIT 20, 10 
+	// Produces string: SELECT * FROM mytable LIMIT 20, 10
 	// (in MySQL. Other databases have slightly different syntax)
-	
+
 	echo $this->db->select('title, content, date')->get_compiled_select();
 
 	// Produces string: SELECT title, content, date FROM mytable
-	
-The key thing to notice in the above example is that the second query did not 
-utilize `$this->db->from()`_ and did not pass a table name into the first 
-parameter. The reason for this outcome is because the query has not been 
-executed using `$this->db->get()`_ which resets values or reset directly 
-using `$this-db->reset_query()`_.
+
+The key thing to notice in the above example is that the second query did not
+utilize `$this->db->from()`_ and did not pass a table name into the first
+parameter. The reason for this outcome is because the query has not been
+executed using `$this->db->get()`_ which resets values or reset directly
+using `$this->db->reset_query()`_.
 
 
 $this->db->get_where()
@@ -96,8 +96,7 @@
 
 Please read the about the where function below for more information.
 
-.. note:: get_where() was formerly known as getwhere(), which has been
-removed
+.. note:: get_where() was formerly known as getwhere(), which has been removed
 
 $this->db->select()
 ===================
@@ -117,7 +116,7 @@
 
 ::
 
-	$this->db->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4') AS amount_paid', FALSE); 
+	$this->db->select('(SELECT SUM(payments.amount) FROM payments WHERE payments.invoice_id=4') AS amount_paid', FALSE);
 	$query = $this->db->get('mytable');
 
 
@@ -131,7 +130,7 @@
 
 	$this->db->select_max('age');
 	$query = $this->db->get('members');  // Produces: SELECT MAX(age) as age FROM members
-	
+
 	$this->db->select_max('age', 'member_age');
 	$query = $this->db->get('members'); // Produces: SELECT MAX(age) as member_age FROM members
 
@@ -196,7 +195,7 @@
 	$this->db->from('blogs');
 	$this->db->join('comments', 'comments.id = blogs.id');
 	$query = $this->db->get();
-	
+
 	// Produces:
 	// SELECT * FROM blogs JOIN comments ON comments.id = blogs.id
 
@@ -225,7 +224,7 @@
 
 	::
 
-		$this->db->where('name', $name); // Produces: WHERE name = 'Joe' 
+		$this->db->where('name', $name); // Produces: WHERE name = 'Joe'
 
 	Notice that the equal sign is added for you.
 
@@ -237,7 +236,7 @@
 		$this->db->where('name', $name);
 		$this->db->where('title', $title);
 		$this->db->where('status', $status);
-		// WHERE name = 'Joe' AND title = 'boss' AND status = 'active'  
+		// WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
 
 #. **Custom key/value method:**
 	You can include an operator in the first parameter in order to
@@ -246,7 +245,7 @@
 	::
 
 		$this->db->where('name !=', $name);
-		$this->db->where('id <', $id); // Produces: WHERE name != 'Joe' AND id < 45    
+		$this->db->where('id <', $id); // Produces: WHERE name != 'Joe' AND id < 45
 
 #. **Associative array method:**
 
@@ -254,7 +253,7 @@
 
 		$array = array('name' => $name, 'title' => $title, 'status' => $status);
 		$this->db->where($array);
-		// Produces: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'    
+		// Produces: WHERE name = 'Joe' AND title = 'boss' AND status = 'active'
 
 	You can include your own operators using this method as well:
 
@@ -355,7 +354,7 @@
 
 	::
 
-		$this->db->like('title', 'match');     // Produces: WHERE title LIKE '%match%' 
+		$this->db->like('title', 'match');     // Produces: WHERE title LIKE '%match%'
 
 	If you use multiple function calls they will be chained together with
 	AND between them::
@@ -372,7 +371,7 @@
 
 		$this->db->like('title', 'match', 'before');	// Produces: WHERE title LIKE '%match'
 		$this->db->like('title', 'match', 'after');		// Produces: WHERE title LIKE 'match%'
-		$this->db->like('title', 'match', 'both');		// Produces: WHERE title LIKE '%match%' 
+		$this->db->like('title', 'match', 'both');		// Produces: WHERE title LIKE '%match%'
 
 #. **Associative array method:**
 
@@ -444,7 +443,7 @@
 possible syntaxes, 1 argument or 2::
 
 	$this->db->having('user_id = 45');  // Produces: HAVING user_id = 45
-	$this->db->having('user_id',  45);  // Produces: HAVING user_id = 45 
+	$this->db->having('user_id',  45);  // Produces: HAVING user_id = 45
 
 You can also pass an array of multiple values as well::
 
@@ -487,7 +486,7 @@
 ::
 
 	$this->db->order_by("title", "desc");
-	$this->db->order_by("name", "asc"); // Produces: ORDER BY title DESC, name ASC     
+	$this->db->order_by("name", "asc"); // Produces: ORDER BY title DESC, name ASC
 
 
 .. note:: order_by() was formerly known as orderby(), which has been
@@ -519,7 +518,7 @@
 	echo $this->db->count_all_results('my_table');  // Produces an integer, like 25
 	$this->db->like('title', 'match');
 	$this->db->from('my_table');
-	echo $this->db->count_all_results(); // Produces an integer, like 17 
+	echo $this->db->count_all_results(); // Produces an integer, like 17
 
 $this->db->count_all()
 ======================
@@ -530,6 +529,54 @@
 	echo $this->db->count_all('my_table');  // Produces an integer, like 25
 
 **************
+Query grouping
+**************
+
+Query grouping allows you to create groups of WHERE clauses by enclosing them in parentheses. This will allow
+you to create queries with complex WHERE clauses. Nested groups are supported. Example:
+
+	$this->db->select('*')->from('my_table')
+		->group_start()
+			->where('a', 'a')
+			->or_group_start()
+				->where('b', 'b')
+				->where('c', 'c')
+			->group_end()
+		->group_end()
+		->where('d', 'd')
+	->get();
+
+	// Generates:
+	// SELECT * FROM (`my_table`) WHERE ( `a` = 'a' OR ( `b` = 'b' AND `c` = 'c' ) ) AND `d` = 'd'
+
+.. note:: groups need to be balanced, make sure every group_start() is matched by a group_end().
+
+$this->db->group_start()
+========================
+
+Starts a new group by adding an opening parenthesis to the WHERE clause of the query.
+
+$this->db->or_group_start()
+===========================
+
+Starts a new group by adding an opening parenthesis to the WHERE clause of the query, prefixing it with 'OR'.
+
+$this->db->not_group_start()
+============================
+
+Starts a new group by adding an opening parenthesis to the WHERE clause of the query, prefixing it with 'NOT'.
+
+$this->db->or_not_group_start()
+===============================
+
+Starts a new group by adding an opening parenthesis to the WHERE clause of the query, prefixing it with 'OR NOT'.
+
+$this->db->group_end()
+======================
+
+Ends the current group by adding an closing parenthesis to the WHERE clause of the query.
+
+**************
 Inserting Data
 **************
 
@@ -545,7 +592,7 @@
 		'name' => 'My Name',
 		'date' => 'My date'
 	);
-	
+
 	$this->db->insert('mytable', $data);
 	// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')
 
@@ -561,7 +608,7 @@
 		var  $date = 'My Date';
 	}
 	*/
-	
+
 	$object = new Myclass;
 	$this->db->insert('mytable', $object);
 	// Produces: INSERT INTO mytable (title, content, date) VALUES ('My Title', 'My Content', 'My Date')
@@ -573,7 +620,7 @@
 
 $this->db->get_compiled_insert()
 ================================
-Compiles the insertion query just like `$this->db->insert()`_ but does not 
+Compiles the insertion query just like `$this->db->insert()`_ but does not
 *run* the query. This method simply returns the SQL query as a string.
 
 Example::
@@ -583,27 +630,27 @@
 		'name'  => 'My Name',
 		'date'  => 'My date'
 	);
-	
+
 	$sql = $this->db->set($data)->get_compiled_insert('mytable');
 	echo $sql;
-	
+
 	// Produces string: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date')
 
-The second parameter enables you to set whether or not the active record query 
+The second parameter enables you to set whether or not the active record query
 will be reset (by default it will be--just like `$this->db->insert()`_)::
-	
+
 	echo $this->db->set('title', 'My Title')->get_compiled_insert('mytable', FALSE);
-	
+
 	// Produces string: INSERT INTO mytable (title) VALUES ('My Title')
-	
+
 	echo $this->db->set('content', 'My Content')->get_compiled_insert();
 
 	// Produces string: INSERT INTO mytable (title, content) VALUES ('My Title', 'My Content')
-	
-The key thing to notice in the above example is that the second query did not 
-utlize `$this->db->from()`_ nor did it pass a table name into the first 
-parameter. The reason this worked is because the query has not been executed 
-using `$this->db->insert()`_ which resets values or reset directly using 
+
+The key thing to notice in the above example is that the second query did not
+utlize `$this->db->from()`_ nor did it pass a table name into the first
+parameter. The reason this worked is because the query has not been executed
+using `$this->db->insert()`_ which resets values or reset directly using
 `$this->db->reset_query()`_.
 
 $this->db->insert_batch()
@@ -625,7 +672,7 @@
 			'date' => 'Another date'
 		)
 	);
-	
+
 	$this->db->insert_batch('mytable', $data);
 	// Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'),  ('Another title', 'Another name', 'Another date')
 
@@ -653,7 +700,7 @@
 	$this->db->set('name', $name);
 	$this->db->set('title', $title);
 	$this->db->set('status', $status);
-	$this->db->insert('mytable'); 
+	$this->db->insert('mytable');
 
 **set()** will also accept an optional third parameter ($escape), that
 will prevent data from being escaped if set to FALSE. To illustrate the
@@ -675,7 +722,7 @@
 		'title' => $title,
 		'status' => $status
 	);
-	
+
 	$this->db->set($array);
 	$this->db->insert('mytable');
 
@@ -688,7 +735,7 @@
 		var  $date = 'My Date';
 	}
 	*/
-	
+
 	$object = new Myclass;
 	$this->db->set($object);
 	$this->db->insert('mytable');
@@ -710,7 +757,7 @@
 		'name' => $name,
 		'date' => $date
 	);
-	
+
 	$this->db->where('id', $id);
 	$this->db->update('mytable', $data);
 	// Produces: // UPDATE mytable  // SET title = '{$title}', name = '{$name}', date = '{$date}' // WHERE id = $id
@@ -724,7 +771,7 @@
 		var  $date = 'My Date';
 	}
 	*/
-	
+
 	$object = new Myclass;
 	$this->db->where('id', $id);
 	$this->db->update('mytable', $object);
@@ -765,14 +812,14 @@
 	   )
 	);
 
-	$this->db->update_batch('mytable', $data, 'title'); 
+	$this->db->update_batch('mytable', $data, 'title');
 
-	// Produces: 
+	// Produces:
 	// UPDATE `mytable` SET `name` = CASE
 	// WHEN `title` = 'My title' THEN 'My Name 2'
 	// WHEN `title` = 'Another title' THEN 'Another Name 2'
 	// ELSE `name` END,
-	// `date` = CASE 
+	// `date` = CASE
 	// WHEN `title` = 'My title' THEN 'My date 2'
 	// WHEN `title` = 'Another title' THEN 'Another date 2'
 	// ELSE `date` END
@@ -789,7 +836,7 @@
 This works exactly the same way as ``$this->db->get_compiled_insert()`` except
 that it produces an UPDATE SQL string instead of an INSERT SQL string.
 
-For more information view documentation for `$this->get_compiled_insert()`_.
+For more information view documentation for `$this->db->get_compiled_insert()`_.
 
 
 *************
@@ -811,7 +858,7 @@
 
 	$this->db->where('id', $id);
 	$this->db->delete('mytable');
-	
+
 	// Produces:
 	// DELETE FROM mytable
 	// WHERE id = $id
@@ -848,23 +895,23 @@
 
 	$this->db->from('mytable');
 	$this->db->truncate();
-	
-	// or  
-	
+
+	// or
+
 	$this->db->truncate('mytable');
-	
+
 	// Produce:
-	// TRUNCATE mytable 
+	// TRUNCATE mytable
 
 .. note:: If the TRUNCATE command isn't available, truncate() will
 	execute as "DELETE FROM table".
-	
+
 $this->db->get_compiled_delete()
 ================================
 This works exactly the same way as ``$this->db->get_compiled_insert()`` except
 that it produces a DELETE SQL string instead of an INSERT SQL string.
 
-For more information view documentation for `$this->get_compiled_insert()`_.
+For more information view documentation for `$this->db->get_compiled_insert()`_.
 
 ***************
 Method Chaining
@@ -918,11 +965,11 @@
 	$this->db->stop_cache();
 	$this->db->get('tablename');
 	//Generates: SELECT `field1` FROM (`tablename`)
-	
+
 	$this->db->select('field2');
 	$this->db->get('tablename');
 	//Generates:  SELECT `field1`, `field2` FROM (`tablename`)
-	
+
 	$this->db->flush_cache();
 	$this->db->select('field2');
 	$this->db->get('tablename');
@@ -933,18 +980,16 @@
 	where, like, group_by, having, order_by, set
 
 
+$this->db->reset_query()
+========================
 
-*******************
-Reset Active Record
-*******************
-
-Resetting Active Record allows you to start fresh with your query without 
-executing it first using a method like $this->db->get() or $this->db->insert(). 
-Just like the methods that execute a query, this will *not* reset items you've 
+Resetting Active Record allows you to start fresh with your query without
+executing it first using a method like $this->db->get() or $this->db->insert().
+Just like the methods that execute a query, this will *not* reset items you've
 cached using `Active Record Caching`_.
 
-This is useful in situations where you are using Active Record to generate SQL 
-(ex. ``$this->db->get_compiled_select()``) but then choose to, for instance, 
+This is useful in situations where you are using Active Record to generate SQL
+(ex. ``$this->db->get_compiled_select()``) but then choose to, for instance,
 run the query::
 
 	// Note that the second parameter of the get_compiled_select method is FALSE
diff --git a/user_guide_src/source/database/configuration.rst b/user_guide_src/source/database/configuration.rst
index 433c671..040e7e3 100644
--- a/user_guide_src/source/database/configuration.rst
+++ b/user_guide_src/source/database/configuration.rst
@@ -28,6 +28,10 @@
 	$db['default']['autoinit'] = TRUE;
 	$db['default']['stricton'] = FALSE;
 
+If you use PDO as your dbdriver, you can specify the full DSN string describe a connection to the database like this::
+
+	$db['default']['dsn'] = 'pgsql:host=localhost;port=5432;dbname=database_name';
+
 You can also specify failovers for the situation when the main connection cannot connect for some reason.
 These failovers can be specified by setting the failover for a connection like this::
 
@@ -158,6 +162,7 @@
 			while developing an application.
 **port**		The database port number. To use this value you have to add a line to the database config array.
 			::
+			
 				$db['default']['port'] =  5432;
 ======================  ==================================================================================================
 
diff --git a/user_guide_src/source/database/connecting.rst b/user_guide_src/source/database/connecting.rst
index a834cc0..fb45241 100644
--- a/user_guide_src/source/database/connecting.rst
+++ b/user_guide_src/source/database/connecting.rst
@@ -122,6 +122,12 @@
 	| $DB1->result();
 	| etc...
 
+.. note:: You don't need to create separate database configurations if you
+	only need to use a different database on the same connection. You
+	can switch to a different database when you need to, like this:
+
+	| $this->db->db_select($database2_name);
+
 Reconnecting / Keeping the Connection Alive
 ===========================================
 
diff --git a/user_guide_src/source/database/helpers.rst b/user_guide_src/source/database/helpers.rst
index 7ea19e9..e8a5ac8 100644
--- a/user_guide_src/source/database/helpers.rst
+++ b/user_guide_src/source/database/helpers.rst
@@ -7,9 +7,9 @@
 
 The insert ID number when performing database inserts.
 
-.. note:: If using the PDO driver with PostgreSQL, this function requires
-	a $name parameter, which specifies the appropriate sequence to check
-	for the insert id.
+.. note:: If using the PDO driver with PostgreSQL, or using the Interbase
+	driver, this function requires a $name parameter, which specifies the 
+	appropriate sequence to check for the insert id.
 
 $this->db->affected_rows()
 ===========================
diff --git a/user_guide_src/source/database/queries.rst b/user_guide_src/source/database/queries.rst
index 971d5d6..15a7361 100644
--- a/user_guide_src/source/database/queries.rst
+++ b/user_guide_src/source/database/queries.rst
@@ -112,3 +112,20 @@
 automatically escaped, producing safer queries. You don't have to
 remember to manually escape data; the engine does it automatically for
 you.
+
+***************
+Handling Errors
+***************
+
+$this->db->error();
+===================
+
+If you need to get the last error that has occured, the error() method
+will return an array containing its code and message. Here's a quick
+example::
+
+	if ( ! $this->db->simple_query('SELECT `example_field` FROM `example_table`'))
+	{
+		$error = $this->db->error(); // Has keys 'code' and 'message'
+	}
+
diff --git a/user_guide_src/source/database/utilities.rst b/user_guide_src/source/database/utilities.rst
index b092010..3805ffb 100644
--- a/user_guide_src/source/database/utilities.rst
+++ b/user_guide_src/source/database/utilities.rst
@@ -161,7 +161,11 @@
 Permits you to backup your full database or individual tables. The
 backup data can be compressed in either Zip or Gzip format.
 
-.. note:: This features is only available for MySQL databases.
+.. note:: This features is only available for MySQL and Interbase/Firebird databases.
+
+.. note:: For Interbase/Firebird databases, the backup file name is the only parameter.
+	
+		Eg. $this->dbutil->backup('db_backup_filename');
 
 .. note:: Due to the limited execution time and memory available to PHP,
 	backing up very large databases may not be possible. If your database is
diff --git a/user_guide_src/source/general/styleguide.rst b/user_guide_src/source/general/styleguide.rst
index b3dc088..d8bdd05 100644
--- a/user_guide_src/source/general/styleguide.rst
+++ b/user_guide_src/source/general/styleguide.rst
@@ -441,6 +441,13 @@
 			// ...
 			}
 		}
+		
+	try {
+		// ...
+	}
+	catch() {
+		// ...
+	}
 
 **CORRECT**::
 
@@ -470,6 +477,15 @@
 			// ...
 		}
 	}
+	
+	try 
+	{
+		// ...
+	}
+	catch()
+	{
+		// ...
+	}
 
 Bracket and Parenthetic Spacing
 ===============================
diff --git a/user_guide_src/source/general/urls.rst b/user_guide_src/source/general/urls.rst
index 3126fcf..6b390b5 100644
--- a/user_guide_src/source/general/urls.rst
+++ b/user_guide_src/source/general/urls.rst
@@ -39,20 +39,23 @@
 
 	example.com/index.php/news/article/my_article
 
-You can easily remove this file by using a .htaccess file with some
-simple rules. Here is an example of such a file, using the "negative"
-method in which everything is redirected except the specified items:
+If your Apache server has mod_rewrite enabled, you can easily remove this
+file by using a .htaccess file with some simple rules. Here is an example
+of such a file, using the "negative" method in which everything is redirected
+except the specified items:
 
 ::
 	
 	RewriteEngine On
 	RewriteCond %{REQUEST_FILENAME} !-f
 	RewriteCond %{REQUEST_FILENAME} !-d
-	RewriteRule ^(.*)$ /index.php/$1 [L]
+	RewriteRule ^(.*)$ index.php/$1 [L]
 
 In the above example, any HTTP request other than those for existing
 directories and existing files is treated as a request for your index.php file.
 
+.. note:: Note: These specific rules might not work for all server configurations.
+
 Adding a URL Suffix
 ===================
 
diff --git a/user_guide_src/source/installation/upgrade_300.rst b/user_guide_src/source/installation/upgrade_300.rst
new file mode 100644
index 0000000..4c594ab
--- /dev/null
+++ b/user_guide_src/source/installation/upgrade_300.rst
@@ -0,0 +1,33 @@
+#############################
+Upgrading from 2.1.0 to 3.0.0
+#############################
+
+.. note:: These upgrade notes are for a version that is yet to be released.
+
+
+Before performing an update you should take your site offline by
+replacing the index.php file with a static one.
+
+Step 1: Update your CodeIgniter files
+=====================================
+
+Replace all files and directories in your "system" folder and replace
+your index.php file. If any modifications were made to your index.php
+they will need to be made fresh in this new one.
+
+.. note:: If you have any custom developed files in these folders please
+	make copies of them first.
+
+Step 2: Change References to the SHA Library
+============================================
+
+The previously deprecated SHA library has been removed in CodeIgniter 3.0.
+Alter your code to use the native `sha1()` PHP function to generate a sha1 hash.
+
+Additionally, the `sha1()` method in the :doc:`Encryption Library <../libraries/encryption>` has been removed.
+
+Step 3: Remove $autoload['core'] from your config/autoload.php
+==============================================================
+
+Use of the `$autoload['core']` config array has been deprecated as of CodeIgniter 1.4.1 and is now removed.
+Move any entries that you might have listed there to `$autoload['libraries']` instead.
diff --git a/user_guide_src/source/libraries/cart.rst b/user_guide_src/source/libraries/cart.rst
index fbf7778..6594b3b 100644
--- a/user_guide_src/source/libraries/cart.rst
+++ b/user_guide_src/source/libraries/cart.rst
@@ -257,7 +257,7 @@
 Permits you to update items in the shopping cart, as outlined above.
 
 $this->cart->remove(rowid);
-**********************
+***************************
 
 Allows you to remove an item from the shopping cart by passing it the rowid.
 
@@ -267,12 +267,12 @@
 Displays the total amount in the cart.
 
 $this->cart->total_items();
-****************************
+***************************
 
 Displays the total number of items in the cart.
 
 $this->cart->contents(boolean);
-************************
+*******************************
 
 Returns an array containing everything in the cart. You can sort the order,
 by which this is returned by passing it "true" where the contents will be sorted
@@ -280,7 +280,7 @@
 first added to the basket to last added to the basket.
 
 $this->cart->has_options(rowid);
-*********************************
+********************************
 
 Returns TRUE (boolean) if a particular row in the cart contains options.
 This function is designed to be used in a loop with
@@ -288,7 +288,7 @@
 as shown in the Displaying the Cart example above.
 
 $this->cart->product_options(rowid);
-*************************************
+************************************
 
 Returns an array of options for a particular product. This function is
 designed to be used in a loop with $this->cart->contents(), since you
diff --git a/user_guide_src/source/libraries/encryption.rst b/user_guide_src/source/libraries/encryption.rst
index 80b45e4..28bdca2 100644
--- a/user_guide_src/source/libraries/encryption.rst
+++ b/user_guide_src/source/libraries/encryption.rst
@@ -126,21 +126,6 @@
 Please visit php.net for a list of `available
 modes <http://php.net/mcrypt>`_.
 
-$this->encrypt->sha1();
-=======================
-
-SHA1 encoding function. Provide a string and it will return a 160 bit
-one way hash. Note: SHA1, just like MD5 is non-decodable. Example::
-
-	$hash = $this->encrypt->sha1('Some string');
-
-Many PHP installations have SHA1 support by default so if all you need
-is to encode a hash it's simpler to use the native function::
-
-	$hash = sha1('Some string');
-
-If your server does not support SHA1 you can use the provided function.
-
 $this->encrypt->encode_from_legacy($orig_data, $legacy_mode = MCRYPT_MODE_ECB, $key = '');
 ==========================================================================================
 
diff --git a/user_guide_src/source/libraries/form_validation.rst b/user_guide_src/source/libraries/form_validation.rst
index e7875bc..2fe315d 100644
--- a/user_guide_src/source/libraries/form_validation.rst
+++ b/user_guide_src/source/libraries/form_validation.rst
@@ -579,7 +579,27 @@
 
 For more info please see the :ref:`using-arrays-as-field-names` section below.
 
-.. _saving-groups:
+Validating An Array (Other Than The $_POST Array)
+=================================================
+
+Sometimes you may want to validate an array that does not originate from $_POST data.
+
+In this case, you can specify the array to be validated::
+	
+      $data = array(
+	      'username' => 'johndoe',
+		  'password' => 'mypassword',
+		  'passconf' => 'mypassword'
+		));
+
+      $this->form_validation->set_data($data);
+
+Creating validation rules, running the validation and retrieving error messages works the same whether you are
+validating $_POST data or an array.
+
+For more info please see the :ref:`function-reference` section below.
+
+-.. _saving-groups:
 
 ************************************************
 Saving Sets of Validation Rules to a Config File
@@ -930,6 +950,25 @@
 
 		Permits you to set custom error messages. See :ref:`setting-error-messages`
 
+$this->form_validation->set_data();
+========================================
+	
+	.. php:method:: set_data ($data = '')
+
+		:param array $data: The data to validate
+
+		Permits you to set an array for validation, instead of using the default
+		$_POST array.
+
+$this->form_validation->error_array();
+========================================
+	
+	.. php:method:: error_array ()
+
+		:rtype: Array
+
+		Returns the error messages as an array.
+
 .. _helper-functions:
 
 ****************
@@ -1010,5 +1049,4 @@
 ::
 
 	<input type="radio" name="myradio" value="1" <?php echo  set_radio('myradio', '1', TRUE); ?> />
-	<input type="radio" name="myradio" value="2" <?php echo  set_radio('myradio', '2'); ?> />
-
+	<input type="radio" name="myradio" value="2" <?php echo  set_radio('myradio', '2'); ?> />
\ No newline at end of file
diff --git a/user_guide_src/source/libraries/image_lib.rst b/user_guide_src/source/libraries/image_lib.rst
index 14bd128..ed6575c 100644
--- a/user_guide_src/source/libraries/image_lib.rst
+++ b/user_guide_src/source/libraries/image_lib.rst
@@ -390,13 +390,11 @@
 **wm_font_size**        16                  None                The size of the text. Note: If you are not using the True Type option
                                                                 above, the number is set using a range of 1 - 5. Otherwise, you can use
                                                                 any valid pixel size for the font you're using.
-**wm_font_color**       ffffff              None                The font color, specified in hex. Note, you must use the full 6
-                                                                character hex value (ie, 993300), rather than the three character
-                                                                abbreviated version (ie fff).
+**wm_font_color**       ffffff              None                The font color, specified in hex. Both the full 6-length (ie, 993300) and
+                                                                the short three character abbreviated version (ie, fff) are supported.
 **wm_shadow_color**     None                None                The color of the drop shadow, specified in hex. If you leave this blank
-                                                                a drop shadow will not be used. Note, you must use the full 6 character
-                                                                hex value (ie, 993300), rather than the three character abbreviated
-                                                                version (ie fff).
+                                                                a drop shadow will not be used. Both the full 6-length (ie, 993300) and
+                                                                the short three character abbreviated version (ie, fff) are supported.
 **wm_shadow_distance**  3                   None                The distance (in pixels) from the font that the drop shadow should
                                                                 appear.
 ======================= =================== =================== ==========================================================================
diff --git a/user_guide_src/source/libraries/loader.rst b/user_guide_src/source/libraries/loader.rst
index bbe2ed5..2090404 100644
--- a/user_guide_src/source/libraries/loader.rst
+++ b/user_guide_src/source/libraries/loader.rst
@@ -165,6 +165,12 @@
 your views. This is useful if for any reason a var is set in a library
 or another controller method using $this->load->vars().
 
+$this->load->get_vars()
+===========================
+
+This function retrieves all variables available to
+your views.
+
 $this->load->helper('file_name')
 =================================
 
diff --git a/user_guide_src/source/libraries/security.rst b/user_guide_src/source/libraries/security.rst
index 8ee0c6e..e7d2555 100644
--- a/user_guide_src/source/libraries/security.rst
+++ b/user_guide_src/source/libraries/security.rst
@@ -85,6 +85,10 @@
 form_open() function will automatically insert a hidden csrf field in
 your forms.
 
+Tokens may be either regenerated on every submission (default) or kept the same throughout the life of the CSRF cookie. The default regeneration of tokens provides stricter security but may result in usability concerns as other tokens become invalid (back/forward navigation, multiple tabs/windows, asynchronous actions, etc). You may alter this behavior by editing the following config parameter::
+
+	$config['csrf_regeneration'] = TRUE;
+
 Select URIs can be whitelisted from csrf protection (for example API
 endpoints expecting externally POSTed content). You can add these URIs
 by editing the 'csrf_exclude_uris' config parameter::
diff --git a/user_guide_src/source/overview/at_a_glance.rst b/user_guide_src/source/overview/at_a_glance.rst
index 31f0b4d..6dcfdbb 100644
--- a/user_guide_src/source/overview/at_a_glance.rst
+++ b/user_guide_src/source/overview/at_a_glance.rst
@@ -41,7 +41,7 @@
 CodeIgniter uses the Model-View-Controller approach, which allows great
 separation between logic and presentation. This is particularly good for
 projects in which designers are working with your template files, as the
-code these file contain will be minimized. We describe MVC in more
+code these files contain will be minimized. We describe MVC in more
 detail on its own page.
 
 CodeIgniter Generates Clean URLs
diff --git a/user_guide_src/source/tutorial/news_section.rst b/user_guide_src/source/tutorial/news_section.rst
index fe8e416..38e4214 100644
--- a/user_guide_src/source/tutorial/news_section.rst
+++ b/user_guide_src/source/tutorial/news_section.rst
@@ -149,7 +149,7 @@
         <div id="main">
             <?php echo $news_item['text'] ?>
         </div>
-        <p><a href="news/<?php echo $news_item['slug'] ?>">View article</a></p>
+        <p><a href="<?php echo $news_item['slug'] ?>">View article</a></p>
 
     <?php endforeach ?>
 
diff --git a/user_guide_src/source/tutorial/static_pages.rst b/user_guide_src/source/tutorial/static_pages.rst
index 82de2a8..708eaeb 100644
--- a/user_guide_src/source/tutorial/static_pages.rst
+++ b/user_guide_src/source/tutorial/static_pages.rst
@@ -72,7 +72,7 @@
 
 ::
 
-            <em>&copy; 2011</em>
+            <em>&copy; 2012</em>
         </body>
     <html>
 
@@ -97,7 +97,7 @@
     public function view($page = 'home')
     {
                 
-        if ( ! file_exists('application/views/pages/'.$page.'.php'))
+        if ( ! file_exists(APPPATH.'/views/pages/'.$page.'.php'))
         {
             // Whoops, we don't have a page for that!
             show_404();